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