archives

« Bugzilla Issues Index

#4242 — Possible bug in IterationStatement grammar


I'm usually missing something when I encounter something like this, so bear with me.

Here is a quote from the grammar, but with each production truncated to fit in the textarea I'm working in:

IterationStatement[Yield, Return] :
do [...]
while [...]
for ( [lookahead ∉ {let [}] Expression[?Yield]_opt ; [...]
for ( var VariableDeclarationList[?Yield] ; [...]
for ( LexicalDeclaration [...]
for ( [lookahead ∉ {let [}] LeftHandSideExpression[?Yield] in [...]
for ( var ForBinding[?Yield] in [...]
for ( ForDeclaration[?Yield] in [...]
for ( [lookahead ≠ let] LeftHandSideExpression[?Yield] of [...]
for ( var ForBinding[?Yield] of [...]
for ( ForDeclaration[?Yield] of [...]

What is the purpose of banning `[` after `(` in productions 3 and 6 but not 9?

The purpose of banning `let` there is clear: it is so that `for(let` unambiguously starts one of the ForBinding/LexicalDeclaration productions, and we don't need a cover grammar to make the syntax parseable with finite lookahead.

But it seems `[` unambiguously selects one of the non-declaration productions anyway.


This looks correct to me. Let me try to explain.

3 & 6: We want `let [` to be the start of a pattern declaration and not a `let[key]` member lookup. However, we want to support the identifier expression `let` for backwards compat:

var let;
for (let in {}) {}
for (let = 0; let < 10; let++) {}

9: for of is new syntax so we can restrict even furtehr


Oh, OK, that makes sense, but there's still a bug. The part in 5.1.5 that explains what [lookahead ∉ set] means needs to be updated. Right now it says:

> If the phrase “[lookahead ∉ set]” appears in the right-hand side of a
> production, it indicates that the production may not be used if the
> immediately following input token is a member of the given set.

Note the singular "immediately following input token".

This is why I was confused; I was reading the restriction as:

[lookahead ∉ {`let`, `[`}]

because I didn't realize that the intended meaning

[lookahead ∉ {`let [`}]

was a possibility.

----

(more philosophically) The use of ∉ is misleading now that "lookahead" no longer refers to exactly one token in particular. It would be clearer to say "[lookahead does not match x]" and "[lookahead does not match any of {x, y, z}]" but I don't know of symbols that mean quite those things.


fixed in rev37 editor's draft

I tweaked 5.1.5 to make it explicit that the elements of the set are are one or two element sequences of terminal symbols


In Rev37