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.