As suggested by @dlatikay , following the existing hunch , the CoveredParenthesizedExpression study provided a better understanding of what is happening here.
Apparently, the reason that no terminal could not be found in spec , to explain why (foo) is acceptable as LeftHandExpression , is surprisingly simple. I assume that you understand how parsers work, and that they work in two separate phases: Lexing and Parse .
What I learned from this little tangent study is that the construction (foo) not technically delivered to the parser, and therefore the engine, as you think.
var foo = (((bar)));
As we all know, something like this is completely legal. What for? Well, you can visually just ignore the brackets, while the statement remains in the ideal sense.
Similarly, here is another valid example, even in terms of human readability, as it is explained in parentheses that PEMDAS already makes implicit.
(3 + ((4 * 5) / 2)) === 3 + 4 * 5 / 2 >> true
One of the key observations can be easily derived from this, given the understanding of how parsers already work. (remember that Javascript is still parsed ( read: compiled ) and then launched). Literally, these parentheses "indicate the obvious."
So, all that is said, what exactly is happening?
In principle, parentheses (with the exception of functional parameters) are collapsed into the correct groupings of their containing characters. IANAL, but in layman terms, this means that parentheses are only interpreted to direct the parser to group what it reads. If the context of the parentheses is already βin orderβ and therefore does not require any tuning of the emitted AST , then the (machine) code is emitted as if these parentheses did not exist at all.
The parser is more or less lazy, believing that the partners are impudent. (which is wrong in this boundary case)
OK, and where exactly is this happening?
According to 12.2.1.5 Static semantics: IsValidSimpleAssignmentTarget in the specification,
Primary expression: (CoverParenthesizedExpressionAndArrowParameterList)
- Let expr be CoveredParenthesizedExpression of CoverParenthesizedExpressionAndArrowParameterList.
- Returns the IsValidSimpleAssignmentTarget expression.
those. If you expect primaryExpression to return everything that is inside the bracket, and use this.
Because of this, in this case it does not convert (foo) to CoveredParenthesizedExpression{ inner: "foo" } , it converts it simply to foo , which preserves the fact that it is an Identifier and, therefore, is syntactically not necessarily lexically valid.
TL; DR
He looked through.
Want a little more insight?
Mark @Bergi's answer .