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