dart-lang / language

Design of the Dart language
Other
2.65k stars 202 forks source link

[parse/spec] Cascade-related inconsistency between the spec and the implementation. #3508

Open modulovalue opened 9 months ago

modulovalue commented 9 months ago

Consider the following program:

void a() {
  b..c = () => 0..d;
}

Which leads to the following parse trees:

 === Analyzer ===
Scan errors: 0
Parse errors: 0
<CompilationUnitImpl> [0-34]
┗━ <FunctionDeclarationImpl> [0-33]
  ┣━ <NamedTypeImpl> [0-4]
  ┃  ┗━ 'void' [0-4]
  ┣━ 'a' [5-6]
  ┗━ <FunctionExpressionImpl> [6-33]
    ┣━ <FormalParameterListImpl> [6-8]
    ┃  ┣━ '(' [6-7]
    ┃  ┗━ ')' [7-8]
    ┗━ <BlockFunctionBodyImpl> [9-33]
      ┗━ <BlockImpl> [9-33]
        ┣━ '{' [9-10]
        ┣━ <ExpressionStatementImpl> [13-31]
        ┃  ┣━ <CascadeExpressionImpl> [13-30]
        ┃  ┃  ┣━ <SimpleIdentifierImpl> [13-14]
        ┃  ┃  ┃  ┗━ 'b' [13-14]
        ┃  ┃  ┗━ <AssignmentExpressionImpl> [14-30]
        ┃  ┃    ┣━ <PropertyAccessImpl> [14-17]
        ┃  ┃    ┃  ┣━ '..' [14-16]
        ┃  ┃    ┃  ┗━ <SimpleIdentifierImpl> [16-17]
        ┃  ┃    ┃    ┗━ 'c' [16-17]
        ┃  ┃    ┣━ '=' [18-19]
        ┃  ┃    ┗━ <FunctionExpressionImpl> [20-30]
        ┃  ┃      ┣━ <FormalParameterListImpl> [20-22]
        ┃  ┃      ┃  ┣━ '(' [20-21]
        ┃  ┃      ┃  ┗━ ')' [21-22]
        ┃  ┃      ┗━ <ExpressionFunctionBodyImpl> [23-30]
        ┃  ┃        ┣━ '=>' [23-25]
        ┃  ┃        ┗━ <CascadeExpressionImpl> [26-30]
        ┃  ┃          ┣━ <IntegerLiteralImpl> [26-27]
        ┃  ┃          ┃  ┗━ '0' [26-27]
        ┃  ┃          ┗━ <PropertyAccessImpl> [27-30]
        ┃  ┃            ┣━ '..' [27-29]
        ┃  ┃            ┗━ <SimpleIdentifierImpl> [29-30]
        ┃  ┃              ┗━ 'd' [29-30]
        ┃  ┗━ ';' [30-31]
        ┗━ '}' [32-33]
--------------------------------------------------------------------------------
 === ANTLR ===
Errors of type 1: []
Errors of type 2: []
<startSymbol>
┗━ <libraryDefinition>
  ┣━ <metadata>
  ┣━ <topLevelDefinition>
  ┃  ┣━ <functionSignature>
  ┃  ┃  ┣━ <type>
  ┃  ┃  ┃  ┗━ <typeNotFunction>
  ┃  ┃  ┃    ┗━ 'void'
  ┃  ┃  ┣━ <identifier>
  ┃  ┃  ┃  ┗━ 'a'
  ┃  ┃  ┗━ <formalParameterPart>
  ┃  ┃    ┗━ <formalParameterList>
  ┃  ┃      ┣━ '('
  ┃  ┃      ┗━ ')'
  ┃  ┗━ <functionBody>
  ┃    ┗━ <block>
  ┃      ┣━ '{'
  ┃      ┣━ <statements>
  ┃      ┃  ┗━ <statement>
  ┃      ┃    ┗━ <nonLabelledStatement>
  ┃      ┃      ┗━ <expressionStatement>
  ┃      ┃        ┣━ <expression>
  ┃      ┃        ┃  ┗━ <cascade>
  ┃      ┃        ┃    ┣━ <cascade>
  ┃      ┃        ┃    ┃  ┣━ <conditionalExpression>
  ┃      ┃        ┃    ┃  ┃  ┗━ <ifNullExpression>
  ┃      ┃        ┃    ┃  ┃    ┗━ <logicalOrExpression>
  ┃      ┃        ┃    ┃  ┃      ┗━ <logicalAndExpression>
  ┃      ┃        ┃    ┃  ┃        ┗━ <equalityExpression>
  ┃      ┃        ┃    ┃  ┃          ┗━ <relationalExpression>
  ┃      ┃        ┃    ┃  ┃            ┗━ <bitwiseOrExpression>
  ┃      ┃        ┃    ┃  ┃              ┗━ <bitwiseXorExpression>
  ┃      ┃        ┃    ┃  ┃                ┗━ <bitwiseAndExpression>
  ┃      ┃        ┃    ┃  ┃                  ┗━ <shiftExpression>
  ┃      ┃        ┃    ┃  ┃                    ┗━ <additiveExpression>
  ┃      ┃        ┃    ┃  ┃                      ┗━ <multiplicativeExpression>
  ┃      ┃        ┃    ┃  ┃                        ┗━ <unaryExpression>
  ┃      ┃        ┃    ┃  ┃                          ┗━ <postfixExpression>
  ┃      ┃        ┃    ┃  ┃                            ┗━ <primary>
  ┃      ┃        ┃    ┃  ┃                              ┗━ <identifier>
  ┃      ┃        ┃    ┃  ┃                                ┗━ 'b'
  ┃      ┃        ┃    ┃  ┣━ '..'
  ┃      ┃        ┃    ┃  ┗━ <cascadeSection>
  ┃      ┃        ┃    ┃    ┣━ <cascadeSelector>
  ┃      ┃        ┃    ┃    ┃  ┗━ <identifier>
  ┃      ┃        ┃    ┃    ┃    ┗━ 'c'
  ┃      ┃        ┃    ┃    ┗━ <cascadeSectionTail>
  ┃      ┃        ┃    ┃      ┗━ <cascadeAssignment>
  ┃      ┃        ┃    ┃        ┣━ <assignmentOperator>
  ┃      ┃        ┃    ┃        ┃  ┗━ '='
  ┃      ┃        ┃    ┃        ┗━ <expressionWithoutCascade>
  ┃      ┃        ┃    ┃          ┗━ <functionExpressionWithoutCascade>
  ┃      ┃        ┃    ┃            ┣━ <formalParameterPart>
  ┃      ┃        ┃    ┃            ┃  ┗━ <formalParameterList>
  ┃      ┃        ┃    ┃            ┃    ┣━ '('
  ┃      ┃        ┃    ┃            ┃    ┗━ ')'
  ┃      ┃        ┃    ┃            ┗━ <functionExpressionWithoutCascadeBody>
  ┃      ┃        ┃    ┃              ┣━ '=>'
  ┃      ┃        ┃    ┃              ┗━ <expressionWithoutCascade>
  ┃      ┃        ┃    ┃                ┗━ <conditionalExpression>
  ┃      ┃        ┃    ┃                  ┗━ <ifNullExpression>
  ┃      ┃        ┃    ┃                    ┗━ <logicalOrExpression>
  ┃      ┃        ┃    ┃                      ┗━ <logicalAndExpression>
  ┃      ┃        ┃    ┃                        ┗━ <equalityExpression>
  ┃      ┃        ┃    ┃                          ┗━ <relationalExpression>
  ┃      ┃        ┃    ┃                            ┗━ <bitwiseOrExpression>
  ┃      ┃        ┃    ┃                              ┗━ <bitwiseXorExpression>
  ┃      ┃        ┃    ┃                                ┗━ <bitwiseAndExpression>
  ┃      ┃        ┃    ┃                                  ┗━ <shiftExpression>
  ┃      ┃        ┃    ┃                                    ┗━ <additiveExpression>
  ┃      ┃        ┃    ┃                                      ┗━ <multiplicativeExpression>
  ┃      ┃        ┃    ┃                                        ┗━ <unaryExpression>
  ┃      ┃        ┃    ┃                                          ┗━ <postfixExpression>
  ┃      ┃        ┃    ┃                                            ┗━ <primary>
  ┃      ┃        ┃    ┃                                              ┗━ <literal>
  ┃      ┃        ┃    ┃                                                ┗━ <numericLiteral>
  ┃      ┃        ┃    ┃                                                  ┗━ '0'
  ┃      ┃        ┃    ┣━ '..'
  ┃      ┃        ┃    ┗━ <cascadeSection>
  ┃      ┃        ┃      ┣━ <cascadeSelector>
  ┃      ┃        ┃      ┃  ┗━ <identifier>
  ┃      ┃        ┃      ┃    ┗━ 'd'
  ┃      ┃        ┃      ┗━ <cascadeSectionTail>
  ┃      ┃        ┗━ ';'
  ┃      ┗━ '}'
  ┗━ '<EOF>'

It looks like the analyzer and a Dart.g-based parser disagree on the expression that ..d is meant to belong to.

The analyzer appears to assume the following:

void a() {
  // Analyzer:
  b..c = (() => 0..d);
}
 === Analyzer ===
Scan errors: 0
Parse errors: 0
<CompilationUnitImpl> [0-51]
┗━ <FunctionDeclarationImpl> [0-50]
  ┣━ <NamedTypeImpl> [0-4]
  ┃  ┗━ 'void' [0-4]
  ┣━ 'a' [5-6]
  ┗━ <FunctionExpressionImpl> [6-50]
    ┣━ <FormalParameterListImpl> [6-8]
    ┃  ┣━ '(' [6-7]
    ┃  ┗━ ')' [7-8]
    ┗━ <BlockFunctionBodyImpl> [9-50]
      ┗━ <BlockImpl> [9-50]
        ┣━ '{' [9-10]
        ┣━ <ExpressionStatementImpl> [28-48]
        ┃  ┣━ <CascadeExpressionImpl> [28-47]
        ┃  ┃  ┣━ <SimpleIdentifierImpl> [28-29]
        ┃  ┃  ┃  ┗━ 'b' [28-29]
        ┃  ┃  ┗━ <AssignmentExpressionImpl> [29-47]
        ┃  ┃    ┣━ <PropertyAccessImpl> [29-32]
        ┃  ┃    ┃  ┣━ '..' [29-31]
        ┃  ┃    ┃  ┗━ <SimpleIdentifierImpl> [31-32]
        ┃  ┃    ┃    ┗━ 'c' [31-32]
        ┃  ┃    ┣━ '=' [33-34]
        ┃  ┃    ┗━ <ParenthesizedExpressionImpl> [35-47]
        ┃  ┃      ┣━ '(' [35-36]
        ┃  ┃      ┣━ <FunctionExpressionImpl> [36-46]
        ┃  ┃      ┃  ┣━ <FormalParameterListImpl> [36-38]
        ┃  ┃      ┃  ┃  ┣━ '(' [36-37]
        ┃  ┃      ┃  ┃  ┗━ ')' [37-38]
        ┃  ┃      ┃  ┗━ <ExpressionFunctionBodyImpl> [39-46]
        ┃  ┃      ┃    ┣━ '=>' [39-41]
        ┃  ┃      ┃    ┗━ <CascadeExpressionImpl> [42-46]
        ┃  ┃      ┃      ┣━ <IntegerLiteralImpl> [42-43]
        ┃  ┃      ┃      ┃  ┗━ '0' [42-43]
        ┃  ┃      ┃      ┗━ <PropertyAccessImpl> [43-46]
        ┃  ┃      ┃        ┣━ '..' [43-45]
        ┃  ┃      ┃        ┗━ <SimpleIdentifierImpl> [45-46]
        ┃  ┃      ┃          ┗━ 'd' [45-46]
        ┃  ┃      ┗━ ')' [46-47]
        ┃  ┗━ ';' [47-48]
        ┗━ '}' [49-50]
--------------------------------------------------------------------------------
 === ANTLR ===
Errors of type 1: []
Errors of type 2: []
<startSymbol>
┗━ <libraryDefinition>
  ┣━ <metadata>
  ┣━ <topLevelDefinition>
  ┃  ┣━ <functionSignature>
  ┃  ┃  ┣━ <type>
  ┃  ┃  ┃  ┗━ <typeNotFunction>
  ┃  ┃  ┃    ┗━ 'void'
  ┃  ┃  ┣━ <identifier>
  ┃  ┃  ┃  ┗━ 'a'
  ┃  ┃  ┗━ <formalParameterPart>
  ┃  ┃    ┗━ <formalParameterList>
  ┃  ┃      ┣━ '('
  ┃  ┃      ┗━ ')'
  ┃  ┗━ <functionBody>
  ┃    ┗━ <block>
  ┃      ┣━ '{'
  ┃      ┣━ <statements>
  ┃      ┃  ┗━ <statement>
  ┃      ┃    ┗━ <nonLabelledStatement>
  ┃      ┃      ┗━ <expressionStatement>
  ┃      ┃        ┣━ <expression>
  ┃      ┃        ┃  ┗━ <cascade>
  ┃      ┃        ┃    ┣━ <conditionalExpression>
  ┃      ┃        ┃    ┃  ┗━ <ifNullExpression>
  ┃      ┃        ┃    ┃    ┗━ <logicalOrExpression>
  ┃      ┃        ┃    ┃      ┗━ <logicalAndExpression>
  ┃      ┃        ┃    ┃        ┗━ <equalityExpression>
  ┃      ┃        ┃    ┃          ┗━ <relationalExpression>
  ┃      ┃        ┃    ┃            ┗━ <bitwiseOrExpression>
  ┃      ┃        ┃    ┃              ┗━ <bitwiseXorExpression>
  ┃      ┃        ┃    ┃                ┗━ <bitwiseAndExpression>
  ┃      ┃        ┃    ┃                  ┗━ <shiftExpression>
  ┃      ┃        ┃    ┃                    ┗━ <additiveExpression>
  ┃      ┃        ┃    ┃                      ┗━ <multiplicativeExpression>
  ┃      ┃        ┃    ┃                        ┗━ <unaryExpression>
  ┃      ┃        ┃    ┃                          ┗━ <postfixExpression>
  ┃      ┃        ┃    ┃                            ┗━ <primary>
  ┃      ┃        ┃    ┃                              ┗━ <identifier>
  ┃      ┃        ┃    ┃                                ┗━ 'b'
  ┃      ┃        ┃    ┣━ '..'
  ┃      ┃        ┃    ┗━ <cascadeSection>
  ┃      ┃        ┃      ┣━ <cascadeSelector>
  ┃      ┃        ┃      ┃  ┗━ <identifier>
  ┃      ┃        ┃      ┃    ┗━ 'c'
  ┃      ┃        ┃      ┗━ <cascadeSectionTail>
  ┃      ┃        ┃        ┗━ <cascadeAssignment>
  ┃      ┃        ┃          ┣━ <assignmentOperator>
  ┃      ┃        ┃          ┃  ┗━ '='
  ┃      ┃        ┃          ┗━ <expressionWithoutCascade>
  ┃      ┃        ┃            ┗━ <conditionalExpression>
  ┃      ┃        ┃              ┗━ <ifNullExpression>
  ┃      ┃        ┃                ┗━ <logicalOrExpression>
  ┃      ┃        ┃                  ┗━ <logicalAndExpression>
  ┃      ┃        ┃                    ┗━ <equalityExpression>
  ┃      ┃        ┃                      ┗━ <relationalExpression>
  ┃      ┃        ┃                        ┗━ <bitwiseOrExpression>
  ┃      ┃        ┃                          ┗━ <bitwiseXorExpression>
  ┃      ┃        ┃                            ┗━ <bitwiseAndExpression>
  ┃      ┃        ┃                              ┗━ <shiftExpression>
  ┃      ┃        ┃                                ┗━ <additiveExpression>
  ┃      ┃        ┃                                  ┗━ <multiplicativeExpression>
  ┃      ┃        ┃                                    ┗━ <unaryExpression>
  ┃      ┃        ┃                                      ┗━ <postfixExpression>
  ┃      ┃        ┃                                        ┗━ <primary>
  ┃      ┃        ┃                                          ┣━ '('
  ┃      ┃        ┃                                          ┣━ <expression>
  ┃      ┃        ┃                                          ┃  ┗━ <functionExpression>
  ┃      ┃        ┃                                          ┃    ┣━ <formalParameterPart>
  ┃      ┃        ┃                                          ┃    ┃  ┗━ <formalParameterList>
  ┃      ┃        ┃                                          ┃    ┃    ┣━ '('
  ┃      ┃        ┃                                          ┃    ┃    ┗━ ')'
  ┃      ┃        ┃                                          ┃    ┗━ <functionExpressionBody>
  ┃      ┃        ┃                                          ┃      ┣━ '=>'
  ┃      ┃        ┃                                          ┃      ┗━ <expression>
  ┃      ┃        ┃                                          ┃        ┗━ <cascade>
  ┃      ┃        ┃                                          ┃          ┣━ <conditionalExpression>
  ┃      ┃        ┃                                          ┃          ┃  ┗━ <ifNullExpression>
  ┃      ┃        ┃                                          ┃          ┃    ┗━ <logicalOrExpression>
  ┃      ┃        ┃                                          ┃          ┃      ┗━ <logicalAndExpression>
  ┃      ┃        ┃                                          ┃          ┃        ┗━ <equalityExpression>
  ┃      ┃        ┃                                          ┃          ┃          ┗━ <relationalExpression>
  ┃      ┃        ┃                                          ┃          ┃            ┗━ <bitwiseOrExpression>
  ┃      ┃        ┃                                          ┃          ┃              ┗━ <bitwiseXorExpression>
  ┃      ┃        ┃                                          ┃          ┃                ┗━ <bitwiseAndExpression>
  ┃      ┃        ┃                                          ┃          ┃                  ┗━ <shiftExpression>
  ┃      ┃        ┃                                          ┃          ┃                    ┗━ <additiveExpression>
  ┃      ┃        ┃                                          ┃          ┃                      ┗━ <multiplicativeExpression>
  ┃      ┃        ┃                                          ┃          ┃                        ┗━ <unaryExpression>
  ┃      ┃        ┃                                          ┃          ┃                          ┗━ <postfixExpression>
  ┃      ┃        ┃                                          ┃          ┃                            ┗━ <primary>
  ┃      ┃        ┃                                          ┃          ┃                              ┗━ <literal>
  ┃      ┃        ┃                                          ┃          ┃                                ┗━ <numericLiteral>
  ┃      ┃        ┃                                          ┃          ┃                                  ┗━ '0'
  ┃      ┃        ┃                                          ┃          ┣━ '..'
  ┃      ┃        ┃                                          ┃          ┗━ <cascadeSection>
  ┃      ┃        ┃                                          ┃            ┣━ <cascadeSelector>
  ┃      ┃        ┃                                          ┃            ┃  ┗━ <identifier>
  ┃      ┃        ┃                                          ┃            ┃    ┗━ 'd'
  ┃      ┃        ┃                                          ┃            ┗━ <cascadeSectionTail>
  ┃      ┃        ┃                                          ┗━ ')'
  ┃      ┃        ┗━ ';'
  ┃      ┗━ '}'
  ┗━ '<EOF>'

And the Dart.g grammar appears to assume the following:

void a() {
  // Dart.g:
  (b..c = () => 0)..d;
}
 === Analyzer ===
Scan errors: 0
Parse errors: 0
<CompilationUnitImpl> [0-49]
┗━ <FunctionDeclarationImpl> [0-48]
  ┣━ <NamedTypeImpl> [0-4]
  ┃  ┗━ 'void' [0-4]
  ┣━ 'a' [5-6]
  ┗━ <FunctionExpressionImpl> [6-48]
    ┣━ <FormalParameterListImpl> [6-8]
    ┃  ┣━ '(' [6-7]
    ┃  ┗━ ')' [7-8]
    ┗━ <BlockFunctionBodyImpl> [9-48]
      ┗━ <BlockImpl> [9-48]
        ┣━ '{' [9-10]
        ┣━ <ExpressionStatementImpl> [26-46]
        ┃  ┣━ <CascadeExpressionImpl> [26-45]
        ┃  ┃  ┣━ <ParenthesizedExpressionImpl> [26-42]
        ┃  ┃  ┃  ┣━ '(' [26-27]
        ┃  ┃  ┃  ┣━ <CascadeExpressionImpl> [27-41]
        ┃  ┃  ┃  ┃  ┣━ <SimpleIdentifierImpl> [27-28]
        ┃  ┃  ┃  ┃  ┃  ┗━ 'b' [27-28]
        ┃  ┃  ┃  ┃  ┗━ <AssignmentExpressionImpl> [28-41]
        ┃  ┃  ┃  ┃    ┣━ <PropertyAccessImpl> [28-31]
        ┃  ┃  ┃  ┃    ┃  ┣━ '..' [28-30]
        ┃  ┃  ┃  ┃    ┃  ┗━ <SimpleIdentifierImpl> [30-31]
        ┃  ┃  ┃  ┃    ┃    ┗━ 'c' [30-31]
        ┃  ┃  ┃  ┃    ┣━ '=' [32-33]
        ┃  ┃  ┃  ┃    ┗━ <FunctionExpressionImpl> [34-41]
        ┃  ┃  ┃  ┃      ┣━ <FormalParameterListImpl> [34-36]
        ┃  ┃  ┃  ┃      ┃  ┣━ '(' [34-35]
        ┃  ┃  ┃  ┃      ┃  ┗━ ')' [35-36]
        ┃  ┃  ┃  ┃      ┗━ <ExpressionFunctionBodyImpl> [37-41]
        ┃  ┃  ┃  ┃        ┣━ '=>' [37-39]
        ┃  ┃  ┃  ┃        ┗━ <IntegerLiteralImpl> [40-41]
        ┃  ┃  ┃  ┃          ┗━ '0' [40-41]
        ┃  ┃  ┃  ┗━ ')' [41-42]
        ┃  ┃  ┗━ <PropertyAccessImpl> [42-45]
        ┃  ┃    ┣━ '..' [42-44]
        ┃  ┃    ┗━ <SimpleIdentifierImpl> [44-45]
        ┃  ┃      ┗━ 'd' [44-45]
        ┃  ┗━ ';' [45-46]
        ┗━ '}' [47-48]
--------------------------------------------------------------------------------
 === ANTLR ===
Errors of type 1: []
Errors of type 2: []
<startSymbol>
┗━ <libraryDefinition>
  ┣━ <metadata>
  ┣━ <topLevelDefinition>
  ┃  ┣━ <functionSignature>
  ┃  ┃  ┣━ <type>
  ┃  ┃  ┃  ┗━ <typeNotFunction>
  ┃  ┃  ┃    ┗━ 'void'
  ┃  ┃  ┣━ <identifier>
  ┃  ┃  ┃  ┗━ 'a'
  ┃  ┃  ┗━ <formalParameterPart>
  ┃  ┃    ┗━ <formalParameterList>
  ┃  ┃      ┣━ '('
  ┃  ┃      ┗━ ')'
  ┃  ┗━ <functionBody>
  ┃    ┗━ <block>
  ┃      ┣━ '{'
  ┃      ┣━ <statements>
  ┃      ┃  ┗━ <statement>
  ┃      ┃    ┗━ <nonLabelledStatement>
  ┃      ┃      ┗━ <expressionStatement>
  ┃      ┃        ┣━ <expression>
  ┃      ┃        ┃  ┗━ <cascade>
  ┃      ┃        ┃    ┣━ <conditionalExpression>
  ┃      ┃        ┃    ┃  ┗━ <ifNullExpression>
  ┃      ┃        ┃    ┃    ┗━ <logicalOrExpression>
  ┃      ┃        ┃    ┃      ┗━ <logicalAndExpression>
  ┃      ┃        ┃    ┃        ┗━ <equalityExpression>
  ┃      ┃        ┃    ┃          ┗━ <relationalExpression>
  ┃      ┃        ┃    ┃            ┗━ <bitwiseOrExpression>
  ┃      ┃        ┃    ┃              ┗━ <bitwiseXorExpression>
  ┃      ┃        ┃    ┃                ┗━ <bitwiseAndExpression>
  ┃      ┃        ┃    ┃                  ┗━ <shiftExpression>
  ┃      ┃        ┃    ┃                    ┗━ <additiveExpression>
  ┃      ┃        ┃    ┃                      ┗━ <multiplicativeExpression>
  ┃      ┃        ┃    ┃                        ┗━ <unaryExpression>
  ┃      ┃        ┃    ┃                          ┗━ <postfixExpression>
  ┃      ┃        ┃    ┃                            ┗━ <primary>
  ┃      ┃        ┃    ┃                              ┣━ '('
  ┃      ┃        ┃    ┃                              ┣━ <expression>
  ┃      ┃        ┃    ┃                              ┃  ┗━ <cascade>
  ┃      ┃        ┃    ┃                              ┃    ┣━ <conditionalExpression>
  ┃      ┃        ┃    ┃                              ┃    ┃  ┗━ <ifNullExpression>
  ┃      ┃        ┃    ┃                              ┃    ┃    ┗━ <logicalOrExpression>
  ┃      ┃        ┃    ┃                              ┃    ┃      ┗━ <logicalAndExpression>
  ┃      ┃        ┃    ┃                              ┃    ┃        ┗━ <equalityExpression>
  ┃      ┃        ┃    ┃                              ┃    ┃          ┗━ <relationalExpression>
  ┃      ┃        ┃    ┃                              ┃    ┃            ┗━ <bitwiseOrExpression>
  ┃      ┃        ┃    ┃                              ┃    ┃              ┗━ <bitwiseXorExpression>
  ┃      ┃        ┃    ┃                              ┃    ┃                ┗━ <bitwiseAndExpression>
  ┃      ┃        ┃    ┃                              ┃    ┃                  ┗━ <shiftExpression>
  ┃      ┃        ┃    ┃                              ┃    ┃                    ┗━ <additiveExpression>
  ┃      ┃        ┃    ┃                              ┃    ┃                      ┗━ <multiplicativeExpression>
  ┃      ┃        ┃    ┃                              ┃    ┃                        ┗━ <unaryExpression>
  ┃      ┃        ┃    ┃                              ┃    ┃                          ┗━ <postfixExpression>
  ┃      ┃        ┃    ┃                              ┃    ┃                            ┗━ <primary>
  ┃      ┃        ┃    ┃                              ┃    ┃                              ┗━ <identifier>
  ┃      ┃        ┃    ┃                              ┃    ┃                                ┗━ 'b'
  ┃      ┃        ┃    ┃                              ┃    ┣━ '..'
  ┃      ┃        ┃    ┃                              ┃    ┗━ <cascadeSection>
  ┃      ┃        ┃    ┃                              ┃      ┣━ <cascadeSelector>
  ┃      ┃        ┃    ┃                              ┃      ┃  ┗━ <identifier>
  ┃      ┃        ┃    ┃                              ┃      ┃    ┗━ 'c'
  ┃      ┃        ┃    ┃                              ┃      ┗━ <cascadeSectionTail>
  ┃      ┃        ┃    ┃                              ┃        ┗━ <cascadeAssignment>
  ┃      ┃        ┃    ┃                              ┃          ┣━ <assignmentOperator>
  ┃      ┃        ┃    ┃                              ┃          ┃  ┗━ '='
  ┃      ┃        ┃    ┃                              ┃          ┗━ <expressionWithoutCascade>
  ┃      ┃        ┃    ┃                              ┃            ┗━ <functionExpressionWithoutCascade>
  ┃      ┃        ┃    ┃                              ┃              ┣━ <formalParameterPart>
  ┃      ┃        ┃    ┃                              ┃              ┃  ┗━ <formalParameterList>
  ┃      ┃        ┃    ┃                              ┃              ┃    ┣━ '('
  ┃      ┃        ┃    ┃                              ┃              ┃    ┗━ ')'
  ┃      ┃        ┃    ┃                              ┃              ┗━ <functionExpressionWithoutCascadeBody>
  ┃      ┃        ┃    ┃                              ┃                ┣━ '=>'
  ┃      ┃        ┃    ┃                              ┃                ┗━ <expressionWithoutCascade>
  ┃      ┃        ┃    ┃                              ┃                  ┗━ <conditionalExpression>
  ┃      ┃        ┃    ┃                              ┃                    ┗━ <ifNullExpression>
  ┃      ┃        ┃    ┃                              ┃                      ┗━ <logicalOrExpression>
  ┃      ┃        ┃    ┃                              ┃                        ┗━ <logicalAndExpression>
  ┃      ┃        ┃    ┃                              ┃                          ┗━ <equalityExpression>
  ┃      ┃        ┃    ┃                              ┃                            ┗━ <relationalExpression>
  ┃      ┃        ┃    ┃                              ┃                              ┗━ <bitwiseOrExpression>
  ┃      ┃        ┃    ┃                              ┃                                ┗━ <bitwiseXorExpression>
  ┃      ┃        ┃    ┃                              ┃                                  ┗━ <bitwiseAndExpression>
  ┃      ┃        ┃    ┃                              ┃                                    ┗━ <shiftExpression>
  ┃      ┃        ┃    ┃                              ┃                                      ┗━ <additiveExpression>
  ┃      ┃        ┃    ┃                              ┃                                        ┗━ <multiplicativeExpression>
  ┃      ┃        ┃    ┃                              ┃                                          ┗━ <unaryExpression>
  ┃      ┃        ┃    ┃                              ┃                                            ┗━ <postfixExpression>
  ┃      ┃        ┃    ┃                              ┃                                              ┗━ <primary>
  ┃      ┃        ┃    ┃                              ┃                                                ┗━ <literal>
  ┃      ┃        ┃    ┃                              ┃                                                  ┗━ <numericLiteral>
  ┃      ┃        ┃    ┃                              ┃                                                    ┗━ '0'
  ┃      ┃        ┃    ┃                              ┗━ ')'
  ┃      ┃        ┃    ┣━ '..'
  ┃      ┃        ┃    ┗━ <cascadeSection>
  ┃      ┃        ┃      ┣━ <cascadeSelector>
  ┃      ┃        ┃      ┃  ┗━ <identifier>
  ┃      ┃        ┃      ┃    ┗━ 'd'
  ┃      ┃        ┃      ┗━ <cascadeSectionTail>
  ┃      ┃        ┗━ ';'
  ┃      ┗━ '}'
  ┗━ '<EOF>'
eernstg commented 9 months ago

Let's consider the example program:

void a() {
  b..c = () => 0..d;
}

In the specified grammar, a <cascadeAssignment> has the following syntax:

<cascadeAssignment> ::= <assignmentOperator> <expressionWithoutCascade>

This implies that the specified grammar must parse a prefix of () => 0..d using <expressionWithoutCascade>. The language specification grammar will happily derive () => 0..d from <expressionWithoutCascade>, because of the rampant ambiguity introduced by <functionExpression>.

The grammar in Dart.g will also parse a prefix of () => 0..d using <expressionWithoutCascade>, but in this case we will use <functionExpressionWithoutCascade> to parse the body (a prefix of 0..d), which yields 0.

So, indeed, the Dart.g grammar will give rise to a parsing with the structure (b..c = () => 0)..d, and the grammar in the language specification will only arrive at b..c = (() => 0..d) because it will parse () => 0..d as an "expression without cascade".

I think the construct () => 0..d is not a particularly convincing "expression without cascade", so the intended parse is probably going to be as follows:

void main() {
  // Likely intended structure:
  var v1 = b
    ..c = () => 0
    ..d;

  // Less likely:
  var v2 = b
    ..c = (() => 0..d);
}

I think this serves as yet another argument in favor of doing what Dart.g has done for years (that is, changing <functionExpression> to <functionPrimary> in <primary>, adding <functionExpression> to <expression>, and adding <functionExpressionWithoutCascade> to <expressionWithoutCascade>; finally, changing <functionExpression> and the one without cascades such that they only derive => functions).

I'll transfer this issue to the language repo, given that there is no reasonable solution (I think) without grammar changes.

eernstg commented 9 months ago

@dart-lang/language-team, WDYT? Are we finally coming around to a solution to this ambiguity issue in the grammar?

The underlying issue with <functionExpression> is described here.

The short version is that <primary> is wildly ambiguous because it contains <functionExpression>. We can fix this by changing the grammar such that <primary> only derives {} function literals, and => function literals are derived from <expression> or <expressionWithoutCascade>.

munificent commented 6 months ago

WDYT? Are we finally coming around to a solution to this ambiguity issue in the grammar?

SGTM.

Also, the cascade syntax is still bad. Even if we disambiguate the grammar for our parsers, actual humans will still be hopeless confused when presented with code like a..b = () => c..d or, hell, even a..b = c..d.