Reputation: 502
Checking the latest standard for ECMA-262 ECMAScript 2020 (or 11th Edition) and couldn't figure out the grammar production for exponentiation.
UpdateExpression[Yield, Await]: LeftHandSideExpression[?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await][no LineTerminator here]++ LeftHandSideExpression[?Yield, ?Await][no LineTerminator here]-- ++UnaryExpression[?Yield, ?Await] --UnaryExpression[?Yield, ?Await] UnaryExpression[Yield, Await]: UpdateExpression[?Yield, ?Await] delete UnaryExpression[?Yield, ?Await] void UnaryExpression[?Yield, ?Await] typeof UnaryExpression[?Yield, ?Await] +UnaryExpression[?Yield, ?Await] -UnaryExpression[?Yield, ?Await] ~UnaryExpression[?Yield, ?Await] !UnaryExpression[?Yield, ?Await] [+Await]AwaitExpression[?Yield] ExponentiationExpression[Yield, Await]: UnaryExpression[?Yield, ?Await] UpdateExpression[?Yield, ?Await]**ExponentiationExpression[?Yield, ?Await]
So a UnaryExpression is an ExponentiationExpression thus allowing something like -x to pass up the parsing tree but to actually evaluate an exponentiation the LHS has to be an UpdateExpression (++x, --x, x++, x-- or just x). The RHS is an ExponentiationExpression so can therefore be a UnaryExpression. This means that parsing x ** -y is easy but how do you parse -x ** y. I thought of treating it as -(x ** y) but then had no way to get the unparenthesized x ** y from being an Expression back to an UpdateExpression to feed into UnaryExpression.
Or is it simply that -x ** y is disallowed and you have to get explicit by using
-(x ** y)
or
(-x) ** y
, both of which are easy to parse as follows:
(x ** y) is a ParenthesizedExpression so feeds in to UnaryExpression as a PrimaryExpression.
(-x) similarly feeds into UpdateExpression as a PrimaryExpression
Or am I missing something obvious.
Upvotes: 2
Views: 74
Reputation: 241771
Or is it simply that -x ** y is disallowed and you have to get explicit by using
-(x ** y)
or
(-x) ** y
Precisely.
Or am I missing something obvious.
No, you got it right.
There are some useful links in this answer to a related question from 2017, including this email thread started by Brendan Eich on the es-discuss list in 2015, which proposes the current syntax.
Some concrete examples:
From the Firefox console:
-2**4
SyntaxError: unparenthesized unary expression can't appear on the left-hand side of '**'
From David Flanagan's "JavaScript: The Definitive Guide" (O'Reilly) (not an endorsement):
There is a natural ambiguity to expressions like
-3 ** 2
. Depending on the relative precedence of unary minus and exponentiation, that expression could mean(-3)**2
or-(3**2)
. Different languages handle this differently, and rather than pick sides, JavaScript simply makes it a syntax error to omit parentheses in this case, forcing you to write an unambiguous expression.
Of course, the real definitive guide is the grammar, which you have already quoted.
Upvotes: 1