H98 Report: expression syntax glitch
Simon Peyton-Jones
simonpj@microsoft.com
Wed, 27 Feb 2002 06:45:45 -0800
I'm inclined to stay with the formulation as a side condition,
assuming you all think it's correct.=20
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=20
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=20
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:ross@soi.city.ac.uk]=20
| Sent: 27 February 2002 10:43
| To: Simon Peyton-Jones
| Cc: haskell@haskell.org
| Subject: Re: H98 Report: expression syntax glitch
|=20
|=20
| 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)=20
| > punctuation symbol; and if that phrase parses as an exp=20
| that's fine,=20
| > otherwise it's a parse error. So I should not really speak=20
| in terms=20
| > of 'ambiguity'.
| >=20
| > Perhaps we can simply say that=20
| > let .. in exp
| > is legal only if the phrase is followed by one of the punctuation=20
| > symbols. That's nice, because we don't need to talk of=20
| "not part of a=20
| > smaller expression".
|=20
| OK, so you have a context-free grammar qualified by a rule=20
| forbidding some of the derivations of that grammar.
|=20
| Another solution would be to subdivide exp^10 using a=20
| superscript I've called A or B from lack of imagination:
|=20
| exp10A -> \ apat[1] ... apat[n] -> exp (lambda=20
| abstraction, n>=3D1)
| | 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
|=20
| Only the latter sort can be followed by infix operators or=20
| type signatures. We could extend the distinction to the exp^i=20
| (here x ranges over {A,B}):
|=20
| exp -> exp0B :: [context =3D>] type (expression=20
| 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)
|=20
| and the rules for sections would be
|=20
| aexp -> ...
| | ( expi+1B qop(a,i) ) (left section)
| | ( qop(a,i) expi+1 ) (right section)
|=20
| It's complicated, but it does at least specify precisely the=20
| language and parses we want in a single context-free description.
|=20