Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2480)

Unified Diff: docs/language/Dart.g

Issue 2688903004: Creating an ANTLR grammar for Dart, potentially the syntax spec.
Patch Set: Enabled parsing many files from one JVM process Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/language/language_parser.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: docs/language/Dart.g
diff --git a/docs/language/Dart.g b/docs/language/Dart.g
new file mode 100644
index 0000000000000000000000000000000000000000..49d069fc18c7990382e3611407bc7de1f7c512be
--- /dev/null
+++ b/docs/language/Dart.g
@@ -0,0 +1,1729 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// CHANGES:
+//
+// v1.0 First version available in the SDK github repository. Covers the
+// Dart language as specified in the language specification based on the
+// many grammar rule snippets. That grammar was then adjusted to remove
+// known issues (e.g., misplaced metadata) and to resolve ambiguities.
+// HERE!
+
+grammar Dart;
+
+/*
+options {
+ backtrack=true;
+ memoize=true;
+}
+*/
+
+@parser::header{
+import java.util.Stack;
+}
+
+@lexer::header{
+import java.util.Stack;
+}
+
+@parser::members {
+ public static String filePath = null;
+ public static boolean filePathHasBeenPrinted = true;
+
+ // Grammar debugging friendly output, 'The Definitive ANTLR Reference', p247.
+ public String getErrorMessage(RecognitionException e, String[] tokenNames) {
+ List stack = getRuleInvocationStack(e, this.getClass().getName());
+ String msg = null;
+ if ( e instanceof NoViableAltException ) {
+ NoViableAltException nvae = (NoViableAltException)e;
+ msg = "no viable alt; token=" + e.token +
+ " (decision=" + nvae.decisionNumber +
+ " state " + nvae.stateNumber + ")" +
+ " decision=<<" + nvae.grammarDecisionDescription + ">>";
+ }
+ else {
+ msg = super.getErrorMessage(e, tokenNames);
+ }
+ if (!filePathHasBeenPrinted) {
+ filePathHasBeenPrinted = true;
+ System.err.println(">>> Parse error in " + filePath + ":");
+ }
+ return stack + " " + msg;
+ }
+
+ public String getTokenErrorDisplay(Token t) {
+ return t.toString();
+ }
+
+ // Enable the parser to treat ASYNC/AWAIT/YIELD as keywords in the body of an
+ // `async`, `async*`, or `sync*` function. Access via methods below.
+ private Stack<Boolean> asyncEtcAreKeywords = new Stack<Boolean>();
+ { asyncEtcAreKeywords.push(false); }
+
+ // Use this to indicate that we are now entering an `async`, `async*`,
+ // or `sync*` function.
+ void startAsyncFunction() { asyncEtcAreKeywords.push(true); }
+
+ // Use this to indicate that we are now entering a function which is
+ // neither `async`, `async*`, nor `sync*`.
+ void startNonAsyncFunction() { asyncEtcAreKeywords.push(false); }
+
+ // Use this to indicate that we are now leaving any funciton.
+ void endFunction() { asyncEtcAreKeywords.pop(); }
+
+ // Whether we can recognize ASYNC/AWAIT/YIELD as an identifier/typeIdentifier.
+ boolean asyncEtcPredicate(int tokenId) {
+ if (tokenId == ASYNC || tokenId == AWAIT || tokenId == YIELD) {
+ return !asyncEtcAreKeywords.peek();
+ }
+ return false;
+ }
+
+ // Debugging support methods.
+ void dp(int indent, String method, String sep) {
+ for (int i = 0; i < indent; i++) {
+ System.out.print(" ");
+ }
+ System.out.println(method + sep + " " + input.LT(1) + " " + state.failed);
+ }
+
+ void dpBegin(int indent, String method) { dp(indent, method, ":"); }
+ void dpEnd(int indent, String method) { dp(indent, method, " END:"); }
+ void dpCall(int indent, String method) { dp(indent, method, "?"); }
+ void dpCalled(int indent, String method) { dp(indent, method, ".."); }
+ void dpResult(int indent, String method) { dp(indent, method, "!"); }
+}
+
+@lexer::members{
+ public static final int BRACE_NORMAL = 1;
+ public static final int BRACE_SINGLE = 2;
+ public static final int BRACE_DOUBLE = 3;
+ public static final int BRACE_THREE_SINGLE = 4;
+ public static final int BRACE_THREE_DOUBLE = 5;
+
+ // Enable the parser to handle string interpolations via brace matching.
+ // The top of the `braceLevels` stack describes the most recent unmatched
+ // '{'. This is needed in order to enable/disable certain lexer rules.
+ //
+ // NORMAL: Most recent unmatched '{' was not string literal related.
+ // SINGLE: Most recent unmatched '{' was `'...${`.
+ // DOUBLE: Most recent unmatched '{' was `"...${`.
+ // THREE_SINGLE: Most recent unmatched '{' was `'''...${`.
+ // THREE_DOUBLE: Most recent unmatched '{' was `"""...${`.
+ //
+ // Access via functions below.
+ private Stack<Integer> braceLevels = new Stack<Integer>();
+
+ // Whether we are currently in a string literal context, and which one.
+ boolean currentBraceLevel(int braceLevel) {
+ if (braceLevels.empty()) return false;
+ return braceLevels.peek() == braceLevel;
+ }
+
+ // Use this to indicate that we are now entering a specific '{...}'.
+ // Call it after accepting the '{'.
+ void enterBrace() {
+ braceLevels.push(BRACE_NORMAL);
+ }
+ void enterBraceSingleQuote() {
+ braceLevels.push(BRACE_SINGLE);
+ }
+ void enterBraceDoubleQuote() {
+ braceLevels.push(BRACE_DOUBLE);
+ }
+ void enterBraceThreeSingleQuotes() {
+ braceLevels.push(BRACE_THREE_SINGLE);
+ }
+ void enterBraceThreeDoubleQuotes() {
+ braceLevels.push(BRACE_THREE_DOUBLE);
+ }
+
+ // Use this to indicate that we are now exiting a specific '{...}',
+ // no matter which kind. Call it before accepting the '}'.
+ void exitBrace() {
+ // We might raise a parse error here if the stack is empty, but the
+ // parsing rules should ensure that we get a parse error anyway, and
+ // it is not a big problem for the spec parser even if it misinterprets
+ // the brace structure of some programs with syntax errors.
+ if (!braceLevels.empty()) braceLevels.pop();
+ }
+}
+
+// ---------------------------------------- Grammar rules.
+
+libraryDefinition
+ : FEFF? SCRIPT_TAG?
+ ((metadata LIBRARY) => libraryName)?
+ ((metadata (IMPORT | EXPORT)) => importOrExport)*
+ ((metadata PART) => partDirective)*
+ (metadata topLevelDefinition)*
+ EOF
+ ;
+
+// `functionSignature functionBody` is split into two alternatives because
+// this eliminates an ambiguity.
+
+topLevelDefinition
+ : classDefinition
+ | enumType
+ | (TYPEDEF typeIdentifier typeParameters? '=') => typeAlias
+ | (TYPEDEF functionPrefix ('<' | '(')) => typeAlias
+ | (EXTERNAL functionSignature ';') => EXTERNAL functionSignature ';'
+ | (EXTERNAL getterSignature) => EXTERNAL getterSignature ';'
+ | (EXTERNAL type? SET identifier '(') =>
+ EXTERNAL setterSignature ';'
+ | (getterSignature functionBodyPrefix) => getterSignature functionBody
+ | (type? SET identifier '(') => setterSignature functionBody
+ | (identifier typeParameters? '(') => functionSignature functionBody
+ | (type identifier typeParameters? '(') =>
+ functionSignature functionBody
+ | ((FINAL | CONST) type? identifier '=') =>
+ (FINAL | CONST) type? staticFinalDeclarationList ';'
+ | initializedVariableDeclaration ';'
+ ;
+
+declaredIdentifier
+ : COVARIANT? finalConstVarOrType identifier
+ ;
+
+finalConstVarOrType
+ : FINAL type?
+ | CONST type?
+ | varOrType
+ ;
+
+varOrType
+ : VAR
+ | type
+ ;
+
+initializedVariableDeclaration
+ : declaredIdentifier ('=' expression)? (',' initializedIdentifier)*
+ ;
+
+initializedIdentifier
+ : identifier ('=' expression)?
+ ;
+
+initializedIdentifierList
+ : initializedIdentifier (',' initializedIdentifier)*
+ ;
+
+functionSignature
+ : (type identifier typeParameters? '(') =>
+ type identifier formalParameterPart
+ | identifier formalParameterPart
+ ;
+
+functionBodyPrefix
+ : ASYNC? '=>'
+ | (ASYNC | ASYNC '*' | SYNC '*')? LBRACE
+ ;
+
+functionBody
+ : '=>' { startNonAsyncFunction(); } expression { endFunction(); } ';'
+ | { startNonAsyncFunction(); } block { endFunction(); }
+ | ASYNC '=>'
+ { startAsyncFunction(); } expression { endFunction(); } ';'
+ | (ASYNC | ASYNC '*' | SYNC '*')
+ { startAsyncFunction(); } block { endFunction(); }
+ ;
+
+block
+ : LBRACE statements RBRACE
+ ;
+
+formalParameterPart
+ : typeParameters? formalParameterList
+ ;
+
+formalParameterList
+ : '(' ')'
+ | '(' normalFormalParameters (','? | ',' optionalFormalParameters) ')'
+ | '(' optionalFormalParameters ')'
+ ;
+
+normalFormalParameters
+ : normalFormalParameter (',' normalFormalParameter)*
+ ;
+
+optionalFormalParameters
+ : optionalPositionalFormalParameters
+ | namedFormalParameters
+ ;
+
+optionalPositionalFormalParameters
+ : '[' defaultFormalParameter (',' defaultFormalParameter)* ','? ']'
+ ;
+
+namedFormalParameters
+ : LBRACE defaultNamedParameter (',' defaultNamedParameter)* ','? RBRACE
+ ;
+
+normalFormalParameter
+ : metadata normalFormalParameterNoMetadata
+ ;
+
+// `functionFormalParameter` is split into two alternatives because
+// this eliminates an ambiguity.
+
+normalFormalParameterNoMetadata
+ : (COVARIANT? identifier typeParameters? '(') => functionFormalParameter
+ | (COVARIANT? type identifier typeParameters? '(') =>
+ functionFormalParameter
+ | (finalConstVarOrType? THIS) => fieldFormalParameter
+ | simpleFormalParameter
+ ;
+
+functionFormalParameter
+ : (COVARIANT? type identifier typeParameters? '(') =>
+ COVARIANT? type identifier formalParameterPart
+ | COVARIANT? identifier formalParameterPart
+ ;
+
+simpleFormalParameter
+ : declaredIdentifier
+ | COVARIANT? identifier
+ ;
+
+fieldFormalParameter
+ : finalConstVarOrType? THIS '.' identifier formalParameterPart?
+ ;
+
+defaultFormalParameter
+ : normalFormalParameter ('=' expression)?
+ ;
+
+defaultNamedParameter
+ : normalFormalParameter ((':' | '=') expression)?
+ ;
+
+typeApplication
+ : typeIdentifier typeParameters?
+ ;
+
+classDefinition
+ : (ABSTRACT? CLASS typeApplication (EXTENDS|IMPLEMENTS|LBRACE)) =>
+ ABSTRACT? CLASS typeApplication (superclass mixins?)? interfaces?
+ LBRACE (metadata classMemberDefinition)* RBRACE
+ | (ABSTRACT? CLASS typeApplication '=') =>
+ ABSTRACT? CLASS mixinApplicationClass
+ ;
+
+mixins
+ : WITH typeNotVoidNotFunctionList
+ ;
+
+classMemberDefinition
+ : (methodSignature functionBodyPrefix) => methodSignature functionBody
+ | declaration ';'
+ ;
+
+// `STATIC? functionSignature` is split into two alternatives because this
+// eliminates an ambiguity.
+
+methodSignature
+ : (constructorName '(') => constructorSignature initializers?
+ | (FACTORY constructorName '(') => factoryConstructorSignature
+ | (STATIC? identifier typeParameters? '(') => STATIC? functionSignature
+ | (STATIC? type identifier typeParameters? '(') =>
+ STATIC? functionSignature
+ | (STATIC? type? GET) => STATIC? getterSignature
+ | (STATIC? type? SET) => STATIC? setterSignature
+ | operatorSignature
+ ;
+
+// https://github.com/dart-lang/sdk/issues/29501 reports on the problem which
+// was solved by adding a case for redirectingFactoryConstructorSignature.
+// TODO(eernst): Close that issue when this is integrated into the spec.
+
+// https://github.com/dart-lang/sdk/issues/29502 reports on the problem that
+// than external const factory constructor declaration cannot be derived by
+// the spec grammar (and also not by this grammar). The following fixes were
+// introduced for that: Added the 'factoryConstructorSignature' case below in
+// 'declaration'; also added 'CONST?' in the 'factoryConstructorSignature'
+// rule, such that const factories in general are allowed.
+// TODO(eernst): Close that issue when this is integrated into the spec.
+
+declaration
+ : (EXTERNAL CONST? FACTORY constructorName '(') =>
+ EXTERNAL factoryConstructorSignature
+ | EXTERNAL constantConstructorSignature
+ | (EXTERNAL constructorName '(') => EXTERNAL constructorSignature
+ | ((EXTERNAL STATIC?)? type? GET) => (EXTERNAL STATIC?)? getterSignature
+ | ((EXTERNAL STATIC?)? type? SET) => (EXTERNAL STATIC?)? setterSignature
+ | (EXTERNAL? type? OPERATOR) => EXTERNAL? operatorSignature
+ | (STATIC (FINAL | CONST)) =>
+ STATIC (FINAL | CONST) type? staticFinalDeclarationList
+ | FINAL type? initializedIdentifierList
+ | ((STATIC | COVARIANT)? (VAR | type) identifier ('=' | ',' | ';')) =>
+ (STATIC | COVARIANT)? (VAR | type) initializedIdentifierList
+ | (EXTERNAL? STATIC? functionSignature ';') =>
+ EXTERNAL? STATIC? functionSignature
+ | (CONST? FACTORY constructorName formalParameterList '=') =>
+ redirectingFactoryConstructorSignature
+ | constantConstructorSignature (redirection | initializers)?
+ | constructorSignature (redirection | initializers)?
+ ;
+
+staticFinalDeclarationList
+ : staticFinalDeclaration (',' staticFinalDeclaration)*
+ ;
+
+staticFinalDeclaration
+ : identifier '=' expression
+ ;
+
+operatorSignature
+ : type? OPERATOR operator formalParameterList
+ ;
+
+operator
+ : '~'
+ | binaryOperator
+ | '[' ']'
+ | '[' ']' '='
+ ;
+
+binaryOperator
+ : multiplicativeOperator
+ | additiveOperator
+ | (shiftOperator) => shiftOperator
+ | relationalOperator
+ | '=='
+ | bitwiseOperator
+ ;
+
+getterSignature
+ : type? GET identifier
+ ;
+
+setterSignature
+ : type? SET identifier formalParameterList
+ ;
+
+constructorSignature
+ : constructorName formalParameterList
+ ;
+
+constructorName
+ : typeIdentifier ('.' identifier)?
+ ;
+
+redirection
+ : ':' THIS ('.' identifier)? arguments
+ ;
+
+initializers
+ : ':' superCallOrFieldInitializer (',' superCallOrFieldInitializer)*
+ ;
+
+superCallOrFieldInitializer
+ : SUPER arguments
+ | SUPER '.' identifier arguments
+ | fieldInitializer
+ | assertClause
+ ;
+
+fieldInitializer
+ : (THIS '.')? identifier '=' conditionalExpression cascadeSection*
+ ;
+
+factoryConstructorSignature
+ : CONST? FACTORY constructorName formalParameterList
+ ;
+
+redirectingFactoryConstructorSignature
+ : CONST? FACTORY constructorName formalParameterList '='
+ constructorDesignation
+ ;
+
+constantConstructorSignature
+ : CONST constructorName formalParameterList
+ ;
+
+superclass
+ : EXTENDS typeNotVoidNotFunction
+ ;
+
+interfaces
+ : IMPLEMENTS typeNotVoidNotFunctionList
+ ;
+
+mixinApplicationClass
+ : typeApplication '=' mixinApplication ';'
+ ;
+
+mixinApplication
+ : typeNotVoidNotFunction mixins interfaces?
+ ;
+
+enumType
+ : ENUM typeIdentifier LBRACE identifier (',' identifier)* (',')? RBRACE
+ ;
+
+typeParameter
+ : metadata typeIdentifier (EXTENDS typeNotVoid)?
+ ;
+
+typeParameters
+ : '<' typeParameter (',' typeParameter)* '>'
+ ;
+
+metadata
+ : ('@' metadatum)*
+ ;
+
+metadatum
+ : constructorDesignation arguments
+ | qualified
+ ;
+
+expression
+ : (formalParameterPart functionExpressionBodyPrefix) =>
+ functionExpression
+ | throwExpression
+ | (assignableExpression assignmentOperator) =>
+ assignableExpression assignmentOperator expression
+ | conditionalExpression cascadeSection*
+ ;
+
+expressionWithoutCascade
+ : (formalParameterPart functionExpressionBodyPrefix) =>
+ functionExpressionWithoutCascade
+ | throwExpressionWithoutCascade
+ | (assignableExpression assignmentOperator) =>
+ assignableExpression assignmentOperator expressionWithoutCascade
+ | conditionalExpression
+ ;
+
+expressionList
+ : expression (',' expression)*
+ ;
+
+primary
+ : thisExpression
+ | SUPER unconditionalAssignableSelector
+ | (CONST constructorDesignation) => constObjectExpression
+ | newExpression
+ | (formalParameterPart functionPrimaryBodyPrefix) => functionPrimary
+ | '(' expression ')'
+ | literal
+ | identifier
+ ;
+
+literal
+ : nullLiteral
+ | booleanLiteral
+ | numericLiteral
+ | stringLiteral
+ | symbolLiteral
+ | (CONST? typeArguments? LBRACE) => mapLiteral
+ | listLiteral
+ ;
+
+nullLiteral
+ : NULL
+ ;
+
+numericLiteral
+ : NUMBER
+ | HEX_NUMBER
+ ;
+
+booleanLiteral
+ : TRUE
+ | FALSE
+ ;
+
+stringLiteral
+ : (multiLineString | singleLineString)+
+ ;
+
+stringLiteralWithoutInterpolation
+ : singleLineStringWithoutInterpolation+
+ ;
+
+listLiteral
+ : CONST? typeArguments? '[' (expressionList ','?)? ']'
+ ;
+
+mapLiteral
+ : CONST? typeArguments?
+ LBRACE (mapLiteralEntry (',' mapLiteralEntry)* ','?)? RBRACE
+ ;
+
+mapLiteralEntry
+ : expression ':' expression
+ ;
+
+throwExpression
+ : THROW expression
+ ;
+
+throwExpressionWithoutCascade
+ : THROW expressionWithoutCascade
+ ;
+
+functionExpression
+ : formalParameterPart functionExpressionBody
+ ;
+
+functionExpressionBody
+ : '=>' { startNonAsyncFunction(); } expression { endFunction(); }
+ | ASYNC '=>' { startAsyncFunction(); } expression { endFunction(); }
+ ;
+
+functionExpressionBodyPrefix
+ : ASYNC? '=>'
+ ;
+
+functionExpressionWithoutCascade
+ : formalParameterPart functionExpressionWithoutCascadeBody
+ ;
+
+functionExpressionWithoutCascadeBody
+ : '=>' { startNonAsyncFunction(); }
+ expressionWithoutCascade { endFunction(); }
+ | ASYNC '=>' { startAsyncFunction(); }
+ expressionWithoutCascade { endFunction(); }
+ ;
+
+functionPrimary
+ : formalParameterPart functionPrimaryBody
+ ;
+
+functionPrimaryBody
+ : { startNonAsyncFunction(); } block { endFunction(); }
+ | (ASYNC | ASYNC '*' | SYNC '*')
+ { startAsyncFunction(); } block { endFunction(); }
+ ;
+
+functionPrimaryBodyPrefix
+ : (ASYNC | ASYNC '*' | SYNC '*')? LBRACE
+ ;
+
+thisExpression
+ : THIS
+ ;
+
+newExpression
+ : NEW constructorDesignation arguments
+ ;
+
+constObjectExpression
+ : CONST constructorDesignation arguments
+ ;
+
+arguments
+ : '(' (argumentList ','?)? ')'
+ ;
+
+argumentList
+ : namedArgument (',' namedArgument)*
+ | expressionList (',' namedArgument)*
+ ;
+
+namedArgument
+ : label expression
+ ;
+
+cascadeSection
+ : '..'
+ (cascadeSelector argumentPart*)
+ (assignableSelector argumentPart*)*
+ (assignmentOperator expressionWithoutCascade)?
+ ;
+
+cascadeSelector
+ : '[' expression ']'
+ | identifier
+ ;
+
+assignmentOperator
+ : '='
+ | compoundAssignmentOperator
+ ;
+
+compoundAssignmentOperator
+ : '*='
+ | '/='
+ | '~/='
+ | '%='
+ | '+='
+ | '-='
+ | '<<='
+ | '>' '>' '='
+ | '&='
+ | '^='
+ | '|='
+ | '??='
+ ;
+
+conditionalExpression
+ : ifNullExpression
+ ('?' expressionWithoutCascade ':' expressionWithoutCascade)?
+ ;
+
+ifNullExpression
+ : logicalOrExpression ('??' logicalOrExpression)*
+ ;
+
+logicalOrExpression
+ : logicalAndExpression ('||' logicalAndExpression)*
+ ;
+
+logicalAndExpression
+ : equalityExpression ('&&' equalityExpression)*
+ ;
+
+equalityExpression
+ : relationalExpression (equalityOperator relationalExpression)?
+ | SUPER equalityOperator relationalExpression
+ ;
+
+equalityOperator
+ : '=='
+ | '!='
+ ;
+
+relationalExpression
+ : bitwiseOrExpression
+ (typeTest | typeCast | relationalOperator bitwiseOrExpression)?
+ | SUPER relationalOperator bitwiseOrExpression
+ ;
+
+relationalOperator
+ : '>' '='
+ | '>'
+ | '<='
+ | '<'
+ ;
+
+bitwiseOrExpression
+ : bitwiseXorExpression ('|' bitwiseXorExpression)*
+ | SUPER ('|' bitwiseXorExpression)+
+ ;
+
+bitwiseXorExpression
+ : bitwiseAndExpression ('^' bitwiseAndExpression)*
+ | SUPER ('^' bitwiseAndExpression)+
+ ;
+
+bitwiseAndExpression
+ : shiftExpression ('&' shiftExpression)*
+ | SUPER ('&' shiftExpression)+
+ ;
+
+bitwiseOperator
+ : '&'
+ | '^'
+ | '|'
+ ;
+
+shiftExpression
+ : additiveExpression (shiftOperator additiveExpression)*
+ | SUPER (shiftOperator additiveExpression)+
+ ;
+
+shiftOperator
+ : '<<'
+ | '>' '>'
+ ;
+
+additiveExpression
+ : multiplicativeExpression (additiveOperator multiplicativeExpression)*
+ | SUPER (additiveOperator multiplicativeExpression)+
+ ;
+
+additiveOperator
+ : '+'
+ | '-'
+ ;
+
+multiplicativeExpression
+ : unaryExpression (multiplicativeOperator unaryExpression)*
+ | SUPER (multiplicativeOperator unaryExpression)+
+ ;
+
+multiplicativeOperator
+ : '*'
+ | '/'
+ | '%'
+ | '~/'
+ ;
+
+unaryExpression
+ : (prefixOperator ~SUPER) => prefixOperator unaryExpression
+ | (awaitExpression) => awaitExpression
+ | postfixExpression
+ | (minusOperator | tildeOperator) SUPER
+ | incrementOperator assignableExpression
+ ;
+
+prefixOperator
+ : minusOperator
+ | negationOperator
+ | tildeOperator
+ ;
+
+minusOperator
+ : '-'
+ ;
+
+negationOperator
+ : '!'
+ ;
+
+tildeOperator
+ : '~'
+ ;
+
+awaitExpression
+ : AWAIT unaryExpression
+ ;
+
+// The `(selector)` predicate ensures that the parser commits to the longest
+// possible chain of selectors, e.g., `a<b,c>(d)` as a call rather than as a
+// sequence of two relational expressions.
+
+postfixExpression
+ : (assignableExpression postfixOperator) =>
+ assignableExpression postfixOperator
+ | primary ((selector) => selector)*
+ ;
+
+postfixOperator
+ : incrementOperator
+ ;
+
+selector
+ : assignableSelector
+ | argumentPart
+ ;
+
+argumentPart
+ : typeArguments? arguments
+ ;
+
+incrementOperator
+ : '++'
+ | '--'
+ ;
+
+// The `(assignableSelectorPart)` predicate ensures that the parser
+// commits to the longest possible chain, e.g., `a<b,c>(d).e` as one rather
+// than two expressions. The first `identifier` alternative handles all
+// the simple cases; the final `identifier` alternative at the end catches
+// the case where we have `identifier '<'` and the '<' is used as a
+// relationalOperator, not the beginning of typeArguments.
+
+assignableExpression
+ : (SUPER unconditionalAssignableSelector
+ ~('<' | '(' | '[' | '.' | '?.')) =>
+ SUPER unconditionalAssignableSelector
+ | (identifier ~('<' | '(' | '[' | '.' | '?.')) => identifier
+ | (primary argumentPart* assignableSelector) =>
+ primary ((assignableSelectorPart) => assignableSelectorPart)+
+ | identifier
+ ;
+
+assignableSelectorPart
+ : argumentPart* assignableSelector
+ ;
+
+unconditionalAssignableSelector
+ : '[' expression ']'
+ | '.' identifier
+ ;
+
+assignableSelector
+ : unconditionalAssignableSelector
+ | '?.' identifier
+ ;
+
+identifier
+ : IDENTIFIER
+ | ABSTRACT
+ | AS
+ | COVARIANT
+ | DEFERRED
+ | DYNAMIC
+ | EXPORT
+ | EXTERNAL
+ | FACTORY
+ | GET
+ | IMPLEMENTS
+ | IMPORT
+ | LIBRARY
+ | OPERATOR
+ | PART
+ | SET
+ | STATIC
+ | TYPEDEF
+ | HIDE // Not a built-in identifier.
+ | OF // Not a built-in identifier.
+ | ON // Not a built-in identifier.
+ | SHOW // Not a built-in identifier.
+ | SYNC // Not a built-in identifier.
+ | FUNCTION // Not a built-in identifier.
+ | { asyncEtcPredicate(input.LA(1)) }? (ASYNC|AWAIT|YIELD)
+ ;
+
+qualified
+ : identifier ('.' identifier)?
+ ;
+
+typeIdentifier
+ : IDENTIFIER
+ | DYNAMIC // The only built-in identifier that can be used as a type.
+ | HIDE // Not a built-in identifier.
+ | OF // Not a built-in identifier.
+ | ON // Not a built-in identifier.
+ | SHOW // Not a built-in identifier.
+ | SYNC // Not a built-in identifier.
+ | FUNCTION // Not a built-in identifier.
+ | { asyncEtcPredicate(input.LA(1)) }? (ASYNC|AWAIT|YIELD)
+ ;
+
+typeTest
+ : isOperator typeNotVoid
+ ;
+
+isOperator
+ : IS '!'?
+ ;
+
+typeCast
+ : asOperator typeNotVoid
+ ;
+
+asOperator
+ : AS
+ ;
+
+statements
+ : statement*
+ ;
+
+statement
+ : label* nonLabelledStatement
+ ;
+
+// Exception in the language specification: An expressionStatement cannot
+// start with LBRACE. We force anything that starts with LBRACE to be a block,
+// which will prevent an expressionStatement from starting with LBRACE, and
+// which will not interfere with the recognition of any other case. If we
+// add another statement which can start with LBRACE we must adjust this
+// check.
+nonLabelledStatement
+ : (LBRACE) => block
+ | (declaredIdentifier ('='|','|';')) => localVariableDeclaration
+ | (AWAIT? FOR) => forStatement
+ | whileStatement
+ | doStatement
+ | switchStatement
+ | ifStatement
+ | rethrowStatement
+ | tryStatement
+ | breakStatement
+ | continueStatement
+ | returnStatement
+ | (functionSignature functionBodyPrefix) => localFunctionDeclaration
+ | assertStatement
+ | (YIELD ~'*') => yieldStatement
+ | yieldEachStatement
+ | expressionStatement
+ ;
+
+expressionStatement
+ : expression? ';'
+ ;
+
+localVariableDeclaration
+ : initializedVariableDeclaration ';'
+ ;
+
+localFunctionDeclaration
+ : functionSignature functionBody
+ ;
+
+ifStatement
+ : IF '(' expression ')' statement ((ELSE) => ELSE statement | ())
+ ;
+
+forStatement
+ : AWAIT? FOR '(' forLoopParts ')' statement
+ ;
+
+forLoopParts
+ : (declaredIdentifier IN) => declaredIdentifier IN expression
+ | (identifier IN) => identifier IN expression
+ | forInitializerStatement expression? ';' expressionList?
+ ;
+
+// The localVariableDeclaration cannot be CONST, but that can
+// be enforced in a later phase, and the grammar allows it.
+forInitializerStatement
+ : (localVariableDeclaration) => localVariableDeclaration
+ | expression? ';'
+ ;
+
+whileStatement
+ : WHILE '(' expression ')' statement
+ ;
+
+doStatement
+ : DO statement WHILE '(' expression ')' ';'
+ ;
+
+switchStatement
+ : SWITCH '(' expression ')' LBRACE switchCase* defaultCase? RBRACE
+ ;
+
+switchCase
+ : label* CASE expression ':' statements
+ ;
+
+defaultCase
+ : label* DEFAULT ':' statements
+ ;
+
+rethrowStatement
+ : RETHROW ';'
+ ;
+
+tryStatement
+ : TRY block (onParts finallyPart? | finallyPart)
+ ;
+
+onPart
+ : catchPart block
+ | ON typeNotVoid catchPart? block
+ ;
+
+onParts
+ : (onPart (ON|CATCH)) => onPart onParts
+ | onPart
+ ;
+
+catchPart
+ : CATCH '(' identifier (',' identifier)? ')'
+ ;
+
+finallyPart
+ : FINALLY block
+ ;
+
+returnStatement
+ : RETURN expression? ';'
+ ;
+
+label
+ : identifier ':'
+ ;
+
+breakStatement
+ : BREAK identifier? ';'
+ ;
+
+continueStatement
+ : CONTINUE identifier? ';'
+ ;
+
+yieldStatement
+ : YIELD expression ';'
+ ;
+
+yieldEachStatement
+ : YIELD '*' expression ';'
+ ;
+
+assertStatement
+ : assertClause ';'
+ ;
+
+assertClause
+ : ASSERT '(' expression (',' expression)? ')'
+ ;
+
+libraryName
+ : metadata LIBRARY identifier ('.' identifier)* ';'
+ ;
+
+importOrExport
+ : (metadata IMPORT) => libraryImport
+ | (metadata EXPORT) => libraryExport
+ ;
+
+libraryImport
+ : metadata importSpecification
+ ;
+
+importSpecification
+ : IMPORT uri (AS identifier)? combinator* ';'
+ | IMPORT uri DEFERRED AS identifier combinator* ';'
+ ;
+
+combinator
+ : SHOW identifierList
+ | HIDE identifierList
+ ;
+
+identifierList
+ : identifier (',' identifier)*
+ ;
+
+libraryExport
+ : metadata EXPORT uri combinator* ';'
+ ;
+
+partDirective
+ : metadata PART uri ';'
+ ;
+
+partHeader
+ : metadata PART OF identifier ('.' identifier)* ';'
+ ;
+
+partDeclaration
+ : partHeader topLevelDefinition* EOF
+ ;
+
+uri
+ : stringLiteralWithoutInterpolation
+ ;
+
+type
+ : (FUNCTION ('('|'<')) => functionTypeTails
+ | (typeNotFunction FUNCTION ('('|'<')) =>
+ typeNotFunction functionTypeTails
+ | typeNotFunction
+ ;
+
+typeNotFunction
+ : typeNotVoidNotFunction
+ | VOID
+ ;
+
+typeNotVoid
+ : (typeNotFunction? FUNCTION ('('|'<')) => functionType
+ | typeNotVoidNotFunction
+ ;
+
+typeNotVoidNotFunction
+ : typeName typeArguments?
+ ;
+
+typeName
+ : typeIdentifier ('.' typeIdentifier)?
+ ;
+
+typeArguments
+ : '<' typeList '>'
+ ;
+
+typeList
+ : type (',' type)*
+ ;
+
+typeNotVoidNotFunctionList
+ : typeNotVoidNotFunction (',' typeNotVoidNotFunction)*
+ ;
+
+typeAlias
+ : (TYPEDEF typeIdentifier typeParameters? '=') =>
+ TYPEDEF typeIdentifier typeParameters? '=' functionType ';'
+ | TYPEDEF functionTypeAlias
+ ;
+
+functionTypeAlias
+ : functionPrefix formalParameterPart ';'
+ ;
+
+functionPrefix
+ : (type identifier) => type identifier
+ | identifier
+ ;
+
+functionTypeTail
+ : FUNCTION typeParameters? parameterTypeList
+ ;
+
+functionTypeTails
+ : (functionTypeTail FUNCTION ('<'|'(')) =>
+ functionTypeTail functionTypeTails
+ | functionTypeTail
+ ;
+
+functionType
+ : (FUNCTION ('<'|'(')) => functionTypeTails
+ | typeNotFunction functionTypeTails
+ ;
+
+parameterTypeList
+ : ('(' ')') => '(' ')'
+ | ('(' normalParameterTypes ',' ('['|'{')) =>
+ '(' normalParameterTypes ',' optionalParameterTypes ')'
+ | ('(' normalParameterTypes ','? ')') =>
+ '(' normalParameterTypes ','? ')'
+ | '(' optionalParameterTypes ')'
+ ;
+
+normalParameterTypes
+ : normalParameterType (',' normalParameterType)*
+ ;
+
+normalParameterType
+ : (typedIdentifier) => typedIdentifier
+ | type
+ ;
+
+optionalParameterTypes
+ : optionalPositionalParameterTypes
+ | namedParameterTypes
+ ;
+
+optionalPositionalParameterTypes
+ : '[' normalParameterTypes ','? ']'
+ ;
+
+namedParameterTypes
+ : '{' typedIdentifier (',' typedIdentifier)* ','? '}'
+ ;
+
+typedIdentifier
+ : type identifier
+ ;
+
+constructorDesignation
+ : typeIdentifier
+ | identifier '.' identifier
+ | identifier '.' typeIdentifier '.' identifier
+ | typeName typeArguments ('.' identifier)?
+ ;
+
+// Predicate: Force resolution as composite symbolLiteral as far as possible.
+symbolLiteral
+ : '#' (operator | (identifier (('.' identifier) => '.' identifier)*))
+ ;
+
+singleLineStringWithoutInterpolation
+ : RAW_SINGLE_LINE_STRING
+ | SINGLE_LINE_STRING_DQ_BEGIN_END
+ | SINGLE_LINE_STRING_SQ_BEGIN_END
+ ;
+
+singleLineString
+ : RAW_SINGLE_LINE_STRING
+ | SINGLE_LINE_STRING_SQ_BEGIN_END
+ | SINGLE_LINE_STRING_SQ_BEGIN_MID expression
+ (SINGLE_LINE_STRING_SQ_MID_MID expression)*
+ SINGLE_LINE_STRING_SQ_MID_END
+ | SINGLE_LINE_STRING_DQ_BEGIN_END
+ | SINGLE_LINE_STRING_DQ_BEGIN_MID expression
+ (SINGLE_LINE_STRING_DQ_MID_MID expression)*
+ SINGLE_LINE_STRING_DQ_MID_END
+ ;
+
+multiLineString
+ : RAW_MULTI_LINE_STRING
+ | MULTI_LINE_STRING_SQ_BEGIN_END
+ | MULTI_LINE_STRING_SQ_BEGIN_MID expression
+ (MULTI_LINE_STRING_SQ_MID_MID expression)*
+ MULTI_LINE_STRING_SQ_MID_END
+ | MULTI_LINE_STRING_DQ_BEGIN_END
+ | MULTI_LINE_STRING_DQ_BEGIN_MID expression
+ (MULTI_LINE_STRING_DQ_MID_MID expression)*
+ MULTI_LINE_STRING_DQ_MID_END
+ ;
+
+// ---------------------------------------- Lexer rules.
+
+fragment
+LETTER
+ : 'a' .. 'z'
+ | 'A' .. 'Z'
+ ;
+
+fragment
+DIGIT
+ : '0' .. '9'
+ ;
+
+fragment
+EXPONENT
+ : ('e' | 'E') ('+' | '-')? DIGIT+
+ ;
+
+fragment
+HEX_DIGIT
+ : ('a' | 'b' | 'c' | 'd' | 'e' | 'f')
+ | ('A' | 'B' | 'C' | 'D' | 'E' | 'F')
+ | DIGIT
+ ;
+
+FINAL
+ : 'final'
+ ;
+
+CONST
+ : 'const'
+ ;
+
+VAR
+ : 'var'
+ ;
+
+VOID
+ : 'void'
+ ;
+
+ASYNC
+ : 'async'
+ ;
+
+THIS
+ : 'this'
+ ;
+
+ABSTRACT
+ : 'abstract'
+ ;
+
+AS
+ : 'as'
+ ;
+
+SYNC
+ : 'sync'
+ ;
+
+CLASS
+ : 'class'
+ ;
+
+WITH
+ : 'with'
+ ;
+
+STATIC
+ : 'static'
+ ;
+
+DYNAMIC
+ : 'dynamic'
+ ;
+
+EXTERNAL
+ : 'external'
+ ;
+
+GET
+ : 'get'
+ ;
+
+SET
+ : 'set'
+ ;
+
+OPERATOR
+ : 'operator'
+ ;
+
+SUPER
+ : 'super'
+ ;
+
+FACTORY
+ : 'factory'
+ ;
+
+EXTENDS
+ : 'extends'
+ ;
+
+IMPLEMENTS
+ : 'implements'
+ ;
+
+ENUM
+ : 'enum'
+ ;
+
+NULL
+ : 'null'
+ ;
+
+TRUE
+ : 'true'
+ ;
+
+FALSE
+ : 'false'
+ ;
+
+THROW
+ : 'throw'
+ ;
+
+NEW
+ : 'new'
+ ;
+
+AWAIT
+ : 'await'
+ ;
+
+DEFERRED
+ : 'deferred'
+ ;
+
+EXPORT
+ : 'export'
+ ;
+
+IMPORT
+ : 'import'
+ ;
+
+LIBRARY
+ : 'library'
+ ;
+
+PART
+ : 'part'
+ ;
+
+TYPEDEF
+ : 'typedef'
+ ;
+
+IS
+ : 'is'
+ ;
+
+IF
+ : 'if'
+ ;
+
+ELSE
+ : 'else'
+ ;
+
+WHILE
+ : 'while'
+ ;
+
+FOR
+ : 'for'
+ ;
+
+IN
+ : 'in'
+ ;
+
+DO
+ : 'do'
+ ;
+
+SWITCH
+ : 'switch'
+ ;
+
+CASE
+ : 'case'
+ ;
+
+DEFAULT
+ : 'default'
+ ;
+
+RETHROW
+ : 'rethrow'
+ ;
+
+TRY
+ : 'try'
+ ;
+
+ON
+ : 'on'
+ ;
+
+CATCH
+ : 'catch'
+ ;
+
+FINALLY
+ : 'finally'
+ ;
+
+RETURN
+ : 'return'
+ ;
+
+BREAK
+ : 'break'
+ ;
+
+CONTINUE
+ : 'continue'
+ ;
+
+YIELD
+ : 'yield'
+ ;
+
+SHOW
+ : 'show'
+ ;
+
+HIDE
+ : 'hide'
+ ;
+
+OF
+ : 'of'
+ ;
+
+ASSERT
+ : 'assert'
+ ;
+
+COVARIANT
+ : 'covariant'
+ ;
+
+FUNCTION
+ : 'Function'
+ ;
+
+NUMBER
+ : (DIGIT+ '.' DIGIT) => DIGIT+ '.' DIGIT+ EXPONENT?
+ | DIGIT+ EXPONENT?
+ | '.' DIGIT+ EXPONENT?
+ ;
+
+HEX_NUMBER
+ : '0x' HEX_DIGIT+
+ | '0X' HEX_DIGIT+
+ ;
+
+RAW_SINGLE_LINE_STRING
+ : 'r' '\'' (~('\'' | '\r' | '\n'))* '\''
+ | 'r' '"' (~('"' | '\r' | '\n'))* '"'
+ ;
+
+RAW_MULTI_LINE_STRING
+ : 'r' '"""' (options {greedy=false;} : .)* '"""'
+ | 'r' '\'\'\'' (options {greedy=false;} : .)* '\'\'\''
+ ;
+
+fragment
+SIMPLE_STRING_INTERPOLATION
+ : '$' IDENTIFIER_NO_DOLLAR
+ ;
+
+fragment
+STRING_CONTENT_SQ
+ : ~('\\' | '\'' | '$' | '\r' | '\n')
+ | '\\' ~( '\r' | '\n')
+ | SIMPLE_STRING_INTERPOLATION
+ ;
+
+SINGLE_LINE_STRING_SQ_BEGIN_END
+ : '\'' STRING_CONTENT_SQ* '\''
+ ;
+
+SINGLE_LINE_STRING_SQ_BEGIN_MID
+ : '\'' STRING_CONTENT_SQ* '${' { enterBraceSingleQuote(); }
+ ;
+
+SINGLE_LINE_STRING_SQ_MID_MID
+ : { currentBraceLevel(BRACE_SINGLE) }? =>
+ ('}' STRING_CONTENT_SQ* '${') =>
+ { exitBrace(); } '}' STRING_CONTENT_SQ* '${'
+ { enterBraceSingleQuote(); }
+ ;
+
+SINGLE_LINE_STRING_SQ_MID_END
+ : { currentBraceLevel(BRACE_SINGLE) }? =>
+ ('}' STRING_CONTENT_SQ* '\'') =>
+ { exitBrace(); } '}' STRING_CONTENT_SQ* '\''
+ ;
+
+fragment
+STRING_CONTENT_DQ
+ : ~('\\' | '"' | '$' | '\r' | '\n')
+ | '\\' ~('\r' | '\n')
+ | SIMPLE_STRING_INTERPOLATION
+ ;
+
+SINGLE_LINE_STRING_DQ_BEGIN_END
+ : '"' STRING_CONTENT_DQ* '"'
+ ;
+
+SINGLE_LINE_STRING_DQ_BEGIN_MID
+ : '"' STRING_CONTENT_DQ* '${' { enterBraceDoubleQuote(); }
+ ;
+
+SINGLE_LINE_STRING_DQ_MID_MID
+ : { currentBraceLevel(BRACE_DOUBLE) }? =>
+ ('}' STRING_CONTENT_DQ* '${') =>
+ { exitBrace(); } '}' STRING_CONTENT_DQ* '${'
+ { enterBraceDoubleQuote(); }
+ ;
+
+SINGLE_LINE_STRING_DQ_MID_END
+ : { currentBraceLevel(BRACE_DOUBLE) }? =>
+ ('}' STRING_CONTENT_DQ* '"') =>
+ { exitBrace(); } '}' STRING_CONTENT_DQ* '"'
+ ;
+
+fragment
+QUOTES_SQ
+ :
+ | '\''
+ | '\'\''
+ ;
+
+// Read string contents, which may be almost anything, but stop when seeing
+// '\'\'\'' and when seeing '${'. We do this by allowing all other
+// possibilities including escapes, simple interpolation, and fewer than
+// three '\''.
+fragment
+STRING_CONTENT_TSQ
+ : QUOTES_SQ
+ (~('\\' | '$' | '\'') | '\\' . | SIMPLE_STRING_INTERPOLATION)
+ ;
+
+MULTI_LINE_STRING_SQ_BEGIN_END
+ : '\'\'\'' STRING_CONTENT_TSQ* '\'\'\''
+ ;
+
+MULTI_LINE_STRING_SQ_BEGIN_MID
+ : '\'\'\'' STRING_CONTENT_TSQ* QUOTES_SQ '${'
+ { enterBraceThreeSingleQuotes(); }
+ ;
+
+MULTI_LINE_STRING_SQ_MID_MID
+ : { currentBraceLevel(BRACE_THREE_SINGLE) }? =>
+ ('}' STRING_CONTENT_TSQ* QUOTES_SQ '${') =>
+ { exitBrace(); } '}' STRING_CONTENT_TSQ* QUOTES_SQ '${'
+ { enterBraceThreeSingleQuotes(); }
+ ;
+
+MULTI_LINE_STRING_SQ_MID_END
+ : { currentBraceLevel(BRACE_THREE_SINGLE) }? =>
+ ('}' STRING_CONTENT_TSQ* '\'\'\'') =>
+ { exitBrace(); } '}' STRING_CONTENT_TSQ* '\'\'\''
+ ;
+
+fragment
+QUOTES_DQ
+ :
+ | '"'
+ | '""'
+ ;
+
+// Read string contents, which may be almost anything, but stop when seeing
+// '"""' and when seeing '${'. We do this by allowing all other possibilities
+// including escapes, simple interpolation, and fewer-than-three '"'.
+fragment
+STRING_CONTENT_TDQ
+ : QUOTES_DQ
+ (~('\\' | '$' | '"') | '\\' . | SIMPLE_STRING_INTERPOLATION)
+ ;
+
+MULTI_LINE_STRING_DQ_BEGIN_END
+ : '"""' STRING_CONTENT_TDQ* '"""'
+ ;
+
+MULTI_LINE_STRING_DQ_BEGIN_MID
+ : '"""' STRING_CONTENT_TDQ* QUOTES_DQ '${'
+ { enterBraceThreeDoubleQuotes(); }
+ ;
+
+MULTI_LINE_STRING_DQ_MID_MID
+ : { currentBraceLevel(BRACE_THREE_DOUBLE) }? =>
+ ('}' STRING_CONTENT_TDQ* QUOTES_DQ '${') =>
+ { exitBrace(); } '}' STRING_CONTENT_TDQ* QUOTES_DQ '${'
+ { enterBraceThreeDoubleQuotes(); }
+ ;
+
+MULTI_LINE_STRING_DQ_MID_END
+ : { currentBraceLevel(BRACE_THREE_DOUBLE) }? =>
+ ('}' STRING_CONTENT_TDQ* '"""') =>
+ { exitBrace(); } '}' STRING_CONTENT_TDQ* '"""'
+ ;
+
+LBRACE
+ : '{' { enterBrace(); }
+ ;
+
+RBRACE
+ : { currentBraceLevel(BRACE_NORMAL) }? => ('}') => { exitBrace(); } '}'
+ ;
+
+fragment
+IDENTIFIER_START_NO_DOLLAR
+ : LETTER
+ | '_'
+ ;
+
+fragment
+IDENTIFIER_PART_NO_DOLLAR
+ : IDENTIFIER_START_NO_DOLLAR
+ | DIGIT
+ ;
+
+fragment
+IDENTIFIER_NO_DOLLAR
+ : IDENTIFIER_START_NO_DOLLAR IDENTIFIER_PART_NO_DOLLAR*
+ ;
+
+fragment
+IDENTIFIER_START
+ : IDENTIFIER_START_NO_DOLLAR
+ | '$'
+ ;
+
+fragment
+IDENTIFIER_PART
+ : IDENTIFIER_START
+ | DIGIT
+ ;
+
+SCRIPT_TAG
+ : '#!' (~('\r' | '\n'))* NEWLINE
+ ;
+
+IDENTIFIER
+ : IDENTIFIER_START IDENTIFIER_PART*
+ ;
+
+SINGLE_LINE_COMMENT
+ : '//' (~('\r' | '\n'))* NEWLINE?
+ { skip(); }
+ ;
+
+MULTI_LINE_COMMENT
+ : '/*' (options {greedy=false;} : (MULTI_LINE_COMMENT | .))* '*/'
+ { skip(); }
+ ;
+
+fragment
+NEWLINE
+ : ('\r' | '\n' | '\r\n')
+ ;
+
+FEFF
+ : '\uFEFF'
+ ;
+
+WS
+ : (' ' | '\t' | '\r' | '\n')+
+ { skip(); }
+ ;
« no previous file with comments | « no previous file | tests/language/language_parser.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698