
Hi folks In search of displacement activity, I'm trying to tweak Language.Haskell.Exts to support a few more perfidious Exts I have in mind -- they only need a preprocessor, but I do need to work on parsed programs, ideally. I was hoping to add a production to the grammar of types to admit expressions, delimited by braces: { exp } The idea is that instead of writing, (er, hi Claus), data True data False one just re-uses yer actual Bool (which becomes kind {Bool}) and writes {True} or {False}. The trouble is, the production I've added causes a reduce/reduce conflict in the grammar, but I don't get any more precise complaint than that. I guess what I'd like to know is whether I just need to debug my grammar extension, or whether the notation I'm proposing actually introduces a serious ambiguity that I'm too dim to notice. I'm mostly sending this in the hope that I have one of those "d'oh" moments you sometimes get when you articulate a stupid question in public. Put me out of my misery, please... Cheers Conor

I'd suggest using some different kind of brackets to relieve the
misery, like {| |}.
On Wed, Apr 15, 2009 at 4:10 PM, Conor McBride
Hi folks
In search of displacement activity, I'm trying to tweak Language.Haskell.Exts to support a few more perfidious Exts I have in mind -- they only need a preprocessor, but I do need to work on parsed programs, ideally.
I was hoping to add a production to the grammar of types to admit expressions, delimited by braces:
{ exp }
The idea is that instead of writing, (er, hi Claus),
data True data False
one just re-uses yer actual Bool (which becomes kind {Bool}) and writes {True} or {False}.
The trouble is, the production I've added causes a reduce/reduce conflict in the grammar, but I don't get any more precise complaint than that.
I guess what I'd like to know is whether I just need to debug my grammar extension, or whether the notation I'm proposing actually introduces a serious ambiguity that I'm too dim to notice. I'm mostly sending this in the hope that I have one of those "d'oh" moments you sometimes get when you articulate a stupid question in public.
Put me out of my misery, please...
Cheers
Conor
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 15 Apr 2009, at 16:01, Lennart Augustsson wrote:
I'd suggest using some different kind of brackets to relieve the misery, like {| |}.
That would speed up my tinkering, certainly. I did have a d'oh moment: you can write data Foo = Moo {goo :: Int} -- braces where a type goes and indeed, commenting out field declarations makes happy happy. However, these { exp } guys never stand as types of things, only as parameters of types, so it might be possible to resolve the problem without fat brackets. Whether it's worth it is another matter... Cheers Conor

Conor See this, which I've just written for you: http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/Parser (Others: please do add to this new Commentary page.) In any case, my guess is that adding atype ::= '{' qcon '}' ought not to introduce ambiguities. You don't want all of 'exp' (yet) do you? Simon | -----Original Message----- | From: haskell-cafe-bounces@haskell.org [mailto:haskell-cafe-bounces@haskell.org] On | Behalf Of Conor McBride | Sent: 15 April 2009 16:13 | To: Lennart Augustsson | Cc: Haskell Cafe | Subject: Re: [Haskell-cafe] types and braces | | | On 15 Apr 2009, at 16:01, Lennart Augustsson wrote: | | > I'd suggest using some different kind of brackets to relieve the | > misery, like {| |}. | | That would speed up my tinkering, certainly. | | I did have a d'oh moment: you can write | | data Foo = Moo {goo :: Int} -- braces where a type goes | | and indeed, commenting out field declarations makes happy | happy. However, these { exp } guys never stand as types of | things, only as parameters of types, so it might be possible | to resolve the problem without fat brackets. Whether it's | worth it is another matter... | | Cheers | | Conor | | _______________________________________________ | Haskell-Cafe mailing list | Haskell-Cafe@haskell.org | http://www.haskell.org/mailman/listinfo/haskell-cafe

Hi Conor, Conor McBride:
The trouble is, the production I've added causes a reduce/reduce conflict in the grammar, but I don't get any more precise complaint than that.
To get more precise complaints, you should give the -i flag to happy, that will cause happy to print the whole parser table into a file named Parser.info. It also tells you in which states the conflicts occur, allowing you to track 'em down.
I guess what I'd like to know is whether I just need to debug my grammar extension, or whether the notation I'm proposing actually introduces a serious ambiguity that I'm too dim to notice. I'm mostly sending this in the hope that I have one of those "d'oh" moments you sometimes get when you articulate a stupid question in public.
I don't immediately see what the clash in that context would be - I *think* what you propose should be doable. I'd be interested to know what you come up with, or I might have a look at it myself when I find a few minutes to spare. Cheers, /Niklas

Hi Niklas Good to hear from you, and thanks for providing such a useful starting point for my experiments. On 15 Apr 2009, at 19:27, Niklas Broberg wrote:
Hi Conor,
Conor McBride:
The trouble is, the production I've added causes a reduce/reduce conflict in the grammar, but I don't get any more precise complaint than that.
To get more precise complaints, you should give the -i flag to happy, that will cause happy to print the whole parser table into a file named Parser.info. It also tells you in which states the conflicts occur, allowing you to track 'em down.
So that's how you do it! I was expecting that some such thing would exist.
I guess what I'd like to know is whether I just need to debug my grammar extension, or whether the notation I'm proposing actually introduces a serious ambiguity that I'm too dim to notice. I'm mostly sending this in the hope that I have one of those "d'oh" moments you sometimes get when you articulate a stupid question in public.
I don't immediately see what the clash in that context would be - I *think* what you propose should be doable. I'd be interested to know what you come up with, or I might have a look at it myself when I find a few minutes to spare.
I've found that I can add a production atype :: { Type } ... | '{' trueexp '}' if I remove the productions for record declarations constr1 :: { ConDecl } | con '{' '}' { RecDecl $1 [] } | con '{' fielddecls '}' { RecDecl $1 (reverse $3) } which suggests that it is indeed the syntax data Moo = Foo {goo :: Boo Hoo} which is in apparent conflict with my proposed extension. The current parser uses the type parser btype to parse the initial segment of constructor declarations, so my change causes trouble. Further trouble is in store from infix constructors data Noo = Foo {True} :*: Foo {False} should make sense, but you have to look quite far to distinguish that from a record. So I don't see that my proposed extension introduces a genuine ambiguity, but it does make the parser a bit knottier. I can use (|...|) as the brackets I need in the meantime, without even disturbing the lexer, but I'd much rather use {...} if I can learn a bit more happy hacking. My efforts so far have been clumsy and frustrating, but -i might help me see what I'm doing wrong. Subtle stuff Conor

Conor,
I'd like to point out a few things that may help you on the way.
On Wed, Apr 15, 2009 at 8:58 PM, Conor McBride
I don't immediately see what the clash in that context would be - I *think* what you propose should be doable. I'd be interested to know what you come up with, or I might have a look at it myself when I find a few minutes to spare.
I've found that I can add a production
atype :: { Type } ... | '{' trueexp '}'
if I remove the productions for record declarations
constr1 :: { ConDecl } | con '{' '}' { RecDecl $1 [] } | con '{' fielddecls '}' { RecDecl $1 (reverse $3) }
which suggests that it is indeed the syntax
data Moo = Foo {goo :: Boo Hoo}
which is in apparent conflict with my proposed extension. The current parser uses the type parser btype to parse the initial segment of constructor declarations, so my change causes trouble.
Further trouble is in store from infix constructors
data Noo = Foo {True} :*: Foo {False}
should make sense, but you have to look quite far to distinguish that from a record.
So I don't see that my proposed extension introduces a genuine ambiguity, but it does make the parser a bit knottier.
Remember that even though your parser in unambiguous that doesn't mean that happy will be able to handle it. Happy deals with LALR grammars and you have to confine yourself to that restriction in order to make happy happy. Also, your example above suggests that your grammar might require an infinite lookahead, something which happy doesn't deal with. Having said all this, there is a magic flag which you can give to happy which will make all these headaches go away. The incantation is --glr which makes happy produce generalized lr parsers which can deal even with ambiguous grammars. I've never used this myself so I can't give you any further advice than to point you in the general direction. The happy manual is your friend. Happy happy hacking. Josef
participants (5)
-
Conor McBride
-
Josef Svenningsson
-
Lennart Augustsson
-
Niklas Broberg
-
Simon Peyton-Jones