Arrow function followed by divide or syntax error?
Peter van der Zee
ecma at qfox.nl
Wed May 24 09:14:11 UTC 2017
Oh, so subtle. You're right, the missing semi makes it a syntax error.
Thanks for clearing that up :)
- peter
On Wed, May 24, 2017 at 11:10 AM, Andreas Rossberg <rossberg at google.com> wrote:
> Note that the arrow function can only form an ExpressionStatement, which
> requires a terminating semicolon. There is none in this example, nor a line
> break that would allow one to be inserted implicitly. So when reaching the
> first `/` a syntax error is apparent, since there is no way the input can
> still form a well-formed statement at that point.
>
> On 24 May 2017 at 10:32, Peter van der Zee <ecma at qfox.nl> wrote:
>>
>> > Unlike an ordinary function expression, which is a PrimaryExpression, an
>> > arrow function is merely an AssigmentExpression, so has much lower
>> > precedence than any arithmetic operator.
>>
>> I'm curious how this should be parsed so let's break this down.
>>
>> Given the following "Script" (I don't think the actual goal matters much
>> here):
>> ```
>> x=x=>{}/alert(1)/+alert(2)//
>> ```
>>
>> Script :
>> ScriptBody opt
>>
>> ScriptBody :
>> StatementList
>>
>> StatementList [Yield, Return] :
>> StatementListItem [?Yield, ?Return]
>> StatementList [?Yield, ?Return] StatementListItem [?Yield, ?Return]
>>
>> StatementListItem [Yield, Return] :
>> Statement [?Yield, ?Return]
>> Declaration [?Yield]
>>
>> Statement [Yield, Return] :
>> BlockStatement [?Yield, ?Return]
>> VariableStatement [?Yield]
>> EmptyStatement
>> ExpressionStatement [?Yield]
>> ... (trunced)
>>
>> ExpressionStatement [Yield] :
>> [lookahead ∉ { { , function , class , let [ }] Expression [In, ?Yield] ;
>>
>> Expression [In, Yield] :
>> AssignmentExpression [?In, ?Yield]
>> Expression [?In, ?Yield] , AssignmentExpression [?In, ?Yield]
>>
>> AssignmentExpression [In, Yield] :
>> ConditionalExpression [?In, ?Yield]
>> [+Yield]
>> YieldExpression [?In]
>> ArrowFunction [?In, ?Yield]LeftHandSideExpression [?Yield] =
>> AssignmentExpression [?In, ?Yield]
>> LeftHandSideExpression [?Yield] AssignmentOperator
>> AssignmentExpression [?In, ?Yield]
>>
>> I hope we can agree that the leading `x=` is consumed by
>> "LeftHandSideExpression [?Yield] AssignmentOperator" in the very last
>> rule above. Proceeding with "AssignmentExpression" from the arrow arg.
>>
>> Note that there is no other rule that applies up to this point.
>>
>> ArrowFunction [In, Yield] :
>> ArrowParameters [?Yield] [no LineTerminator here] => ConciseBody [?In]
>>
>> ArrowParameters [Yield] :
>> BindingIdentifier [?Yield]
>> CoverParenthesizedExpressionAndArrowParameterList [?Yield]
>>
>> Here "CoverParenthesizedExpressionAndArrowParameterList" will consume
>> the second `x` and then the only rule in "ArrowFunction" will consume
>> the arrow (`=>`). Continueing to parse the remainder
>> `{}/alert(1)/+alert(2)//` starting at "ConciseBody".
>>
>> ConciseBody [In] :
>> [lookahead ≠ {] AssignmentExpression [?In]
>> { FunctionBody }
>>
>> Obviously only the second rule applies so we parse the function body
>> and the curlies. We parse greedy but the function body is empty so
>> only the next two chars are consumed (`{}`). Parser has
>> `/alert(1)/+alert(2)//` left to parse and the "Statement" rule has
>> depleted it's options. So we go back to "StatementList" and parse
>> another statement. This should result in a regular expression, a plus
>> operator, a call expression, and a single line comment.
>>
>> I don't think there's a rule here that allows parsing operators after
>> an explicit arrow function body as being part of the arrow function.
>> In fact, I remember that this was explicitly designed this way to
>> prevent this ambiguity. Beyond that I agree that it parses similar to
>> function expressions.
>>
>> If this was wrong I'd love to know the right way to parse this.
>>
>> - peter
>>
>>
>>
>> On Wed, May 24, 2017 at 9:18 AM, Andreas Rossberg <rossberg at google.com>
>> wrote:
>> > On 24 May 2017 at 08:57, Gareth Heyes <gareth.heyes at portswigger.net>
>> > wrote:
>> >>
>> >>
>> >>>
>> >>> you'll get a SyntaxError in all browsers but Edge, which interprets it
>> >>> as
>> >>> `(x => {}) * alert(1)`.
>> >>>
>> >>> Given how confusing that expression is, I think that the SyntaxError
>> >>> is
>> >>> the right choice.
>> >>
>> >>
>> >> Well it is a function expression. So IMO Edge is right. It's
>> >> equivalent
>> >> to:
>> >> x=function(){} * alert(1)
>> >
>> >
>> > Edge is wrong. Unlike an ordinary function expression, which is a
>> > PrimaryExpression, an arrow function is merely an AssigmentExpression,
>> > so
>> > has much lower precedence than any arithmetic operator. The rationale is
>> > that its body doesn't necessarily have braces, so `x => x * 1` would be
>> > ambiguous.
>> >
>> > _______________________________________________
>> > es-discuss mailing list
>> > es-discuss at mozilla.org
>> > https://mail.mozilla.org/listinfo/es-discuss
>> >
>
>
More information about the es-discuss
mailing list