grammars-v4 icon indicating copy to clipboard operation
grammars-v4 copied to clipboard

Dart2 grammar fails to parse super parameters

Open levelrin opened this issue 9 months ago • 2 comments
trafficstars

I'm using Dart2Parser.g4, Dart2Lexer.g4, and Dart2LexerBase.java.

The grammar could not parse the following code:

class Parent {
  final String? lastName;
  const Parent({
    this.lastName
  });
}

class Child extends Parent {
  final String firstName;
  const Child({
    required this.firstName,
    super.lastName,
  });
}

It failed at super.lastName.

Here is the error message:

line 12:4 no viable alternative at input ',super'
line 13:3 mismatched input ')' expecting {<EOF>, '@', 'abstract', 'as', 'async', 'await', 'class', 'const', 'covariant', 'deferred', 'dynamic', 'enum', 'export', 'extension', 'external', 'factory', 'final', 'Function', 'get', 'hide', 'implements', 'import', 'interface', 'late', 'library', 'mixin', 'native', 'of', 'on', 'operator', 'part', 'required', 'set', 'show', 'static', 'sync', 'typedef', 'var', 'void', 'yield', IDENTIFIER}

Here is the Java code to reproduce the issue:

package com.levelrin;

import com.levelrin.antlr.generated.Dart2Lexer;
import com.levelrin.antlr.generated.Dart2Parser;
import com.levelrin.antlr.generated.Dart2ParserBaseListener;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;

public final class Main {

    public static void main(final String... args) {
        final String source = """
            class Parent {
              final String? lastName;
              const Parent({
                this.lastName
              });
            }
            
            class Child extends Parent {
              final String firstName;
              const Child({
                required this.firstName,
                super.lastName,
              });
            }
            """;
        final CharStream charStream = CharStreams.fromString(source);
        final Dart2Lexer lexer = new Dart2Lexer(charStream);
        final CommonTokenStream tokens = new CommonTokenStream(lexer);
        final Dart2Parser parser = new Dart2Parser(tokens);
        final ParseTree tree = parser.compilationUnit();
        final Dart2ParserBaseListener listener = new Dart2ParserBaseListener();
        ParseTreeWalker.DEFAULT.walk(listener, tree);
    }

}

levelrin avatar Jan 21 '25 14:01 levelrin

"super" "." is not in either Dart2 or Dart3 in the spec:

⟨fieldFormalParameter⟩ ::=
⟨finalConstVarOrType⟩? this ‘.’ ⟨identifier⟩ (⟨formalParameterPart⟩ ‘?’?)?

(page 23, https://dart.dev/resources/language/spec/versions/DartLangSpec-v2.10.pdf)

It needs to be raised with Dart people. https://github.com/dart-lang/language eernstg

kaby76 avatar Jan 21 '25 14:01 kaby76

Since @kaby76 pointed out that the Dart spec does not have super parameters, I submitted a ticket to the Dart community.

By the way, here is a workaround I made in Dart2Parser.g4:

fieldFormalParameter
    // The original rule was: finalConstVarOrType? THIS_ D identifier (formalParameterPart QU?)?
    // Since Dart spec does not have super parameters, I include SUPER_ as a workaround.
    : finalConstVarOrType? (THIS_|SUPER_) D identifier (formalParameterPart QU?)?
    ;

levelrin avatar Jan 21 '25 17:01 levelrin