Search code examples
javascriptecmascript-6context-free-grammarcompiler-construction

How can `AssignmentExpression` be derived from `Statement` in EcmaScript grammar


Suppose I have the following part of JS code:

const v = 3;

As I understand it can be parsed as AssignmentExpression:

AssignmentExpression :
    LeftHandSideExpression = AssignmentExpression

Now I'm wondering how it can be derived from the Statement? One possible route is:

Statement -> ExpressionStatement -> Expression -> AssignmentExpression

But I'm not sure about that. Is it correct?

Here is how I found it:

AssignmentExpression is part Expression:

Expression :
    AssignmentExpression
    Expression, AssignmentExpression

then Expression is part of ExpressionStatement is

ExpressionStatement:

    [lookahead ∉ { {, function, ..., let [ }] Expression;

and then ExpressionStatement is part of Statement:

Statement :
    ExpressionStatement

Solution

  • const v = 3; is a declaration, not an assignment. Interestingly declarations aren't Statements, but can appear in StatementLists. So you can't derive const v = 3; from Statement, but you can derive it from StatementList. So if you have a script containing only const v = 3;, the full derivation would be:

                Script
                   |
              ScriptBody
                   |
             StatementList
                   |
           StatementListItem
                   |
              Declaration
                   |
          LexicalDeclaration
         /         |        \
    LetOrConst BindingList  ';'
        |           |
     'const'   LexicalBinding
                 /          \
         BindingIdentifier  Initializer
                |                |
             Identifier    AssignmentExpression
                |                  |
           IdentifierName         ...
                |                  |
               'v'                '5'
    

    An actual assignment would be just v = 5;. That would go through ExpressionStatement and the derivation from Statement would look like this:

                         Statement
                             |
                   ExpressionStatement
                         /        \
                       Expression ';'
                            |
                  AssignmentExpression
                 /          |         \
    LeftHandSideExpression '=' AssignmentExpression
             |                         |
        NewExpression                ...
             |                         |
       MemberExpression               '5'
             |
       PrimaryExpression              
             |
    IdentifierReference
             |
         Identifier
             |
       IdentifierName
             |
            'v'