I'm inclined to stay with the formulation as a side condition, assuming you all think it's correct.
Filling it out as a complete context free grammar as you suggest looks complex. That makes it easy to introduce new errors. And in fact the meta-rule can be implemented by simply telling the parser to resolve shift/reduce errors by shifting. So the extra complexity in the grammar is not mirrored in the implementation. So I propose to say that 'let', 'lambda' and 'if' productions have a side condition that (say) let .. in exp is syntactially valid only if the phrase is followed by one of the punctuation symbols ) ] } | ; , .. where of then else Any objectors? Myself I think this is way better than "leftwards precedence" and "rightwards precedence", which I never did understand Simon | -----Original Message----- | From: Ross Paterson [mailto:[EMAIL PROTECTED]] | Sent: 27 February 2002 10:43 | To: Simon Peyton-Jones | Cc: [EMAIL PROTECTED] | Subject: Re: H98 Report: expression syntax glitch | | | On Tue, Feb 26, 2002 at 08:23:03AM -0800, Simon Peyton-Jones wrote: | > I didn't phrase it right. I meant that a let/lambda/if always | > extends to the next relevant (not part of a smaller expression) | > punctuation symbol; and if that phrase parses as an exp | that's fine, | > otherwise it's a parse error. So I should not really speak | in terms | > of 'ambiguity'. | > | > Perhaps we can simply say that | > let .. in exp | > is legal only if the phrase is followed by one of the punctuation | > symbols. That's nice, because we don't need to talk of | "not part of a | > smaller expression". | | OK, so you have a context-free grammar qualified by a rule | forbidding some of the derivations of that grammar. | | Another solution would be to subdivide exp^10 using a | superscript I've called A or B from lack of imagination: | | exp10A -> \ apat[1] ... apat[n] -> exp (lambda | abstraction, n>=1) | | let decls in exp (let expression) | | if exp then exp else exp (conditional) | exp10B -> case exp of { alts } (case expression) | | do { stmts } (do expression) | | fexp | | Only the latter sort can be followed by infix operators or | type signatures. We could extend the distinction to the exp^i | (here x ranges over {A,B}): | | exp -> exp0B :: [context =>] type (expression | type signature) | | exp0 | expi -> expiA | | expiB | expix -> expi+1B [qop(n,i) expi+1x] | | lexpix | | rexpix | lexpix -> (lexpiB | expi+1B) qop(l,i) expi+1x | lexp6x -> - exp7x | rexpix -> expi+1B qop(r,i) (rexpix | expi+1x) | | and the rules for sections would be | | aexp -> ... | | ( expi+1B qop(a,i) ) (left section) | | ( qop(a,i) expi+1 ) (right section) | | It's complicated, but it does at least specify precisely the | language and parses we want in a single context-free description. | _______________________________________________ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell