| 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(); }
|
| + ;
|
|
|