The trouble with ambiguous grammars

Brendan Eich brendan at mozilla.com
Fri Oct 17 15:39:25 PDT 2008


On Oct 17, 2008, at 12:25 PM, Waldemar Horwat wrote:

> Here's a clearer case that Firefox gets wrong (or your grammar gets  
> wrong, depending on your point of view):
>
> function f() {return "f"}
> var x = 3;
> let (a = 1) a ? f : x++();
>
> The grammar states that the last statement must evaluate to "f".   
> Firefox gives a syntax error.  This is incorrect because the let  
> expression up to the ++ is a PrimaryExpression so can be used as the  
> left operand of a function call.

Consider the simpler, let-expression-free test:

js> var a = 1, f = 2;
js> a ? f : x++();
typein:3: SyntaxError: missing ; before statement:
typein:3: a ? f : x++();
typein:3: .........^

(The error pointer is off by two, I'm filing a bug on that.)

Safari and IE seem to agree (IE blames the correct column number, the  
one for the ( -- good for it).

This is an error according to ES1-3 because x++ is a postfixExpression  
derived from

PostfixExpression :
       LeftHandSideExpression
       LeftHandSideExpression [no LineTerminator here] ++
       LeftHandSideExpression [no LineTerminator here] --

while expr() meaning "call expr with zero arguments" derives from

CallExpression : MemberExpression Arguments

and MemberExpression is never an unparenthesized PostfixExpression:

MemberExpression :
       PrimaryExpression
       FunctionExpression
       MemberExpression [ Expression ]
       MemberExpression . Identifier
       new MemberExpression Arguments

So your example with or without the leading let (a = 1) is not  
syntactically valid.


> In an ambiguous grammar, you also need to prove the negative:  no  
> *other* expansion can match that source program and shadow your  
> expansions.  Proving the negative causes trouble because a language  
> extension could turn the mismatch into a match and because  
> sometimes, as in the above case, you expected some other part of the  
> grammar to shadow your expansions but it didn't.

That's a good point, but it is not what is going on here. There is no  
valid sentence x++() produced by ES1-3's expression grammar.

/be


More information about the Es-discuss mailing list