Arrow function followed by divide or syntax error?
Michał Wadas
michalwadas at gmail.com
Wed May 24 10:54:03 UTC 2017
I have filled an issue for Babylon
<https://github.com/babel/babylon/issues/536>.
On Wed, May 24, 2017 at 11:14 AM, Peter van der Zee <ecma at qfox.nl> wrote:
> 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
> >> >
> >
> >
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170524/4af6e619/attachment-0001.html>
More information about the es-discuss
mailing list