mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 08:20:31 +00:00
d2911decfb
This change is needed as a consequence of https://github.com/dart-lang/language/pull/2422 where `()` was introduced as the syntax for the empty record as well as the empty record type. Change-Id: Ia8b3f590361343ca14355043c5898e7bd084c04e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/261645 Reviewed-by: William Hesse <whesse@google.com> Auto-Submit: Erik Ernst <eernst@google.com> Commit-Queue: William Hesse <whesse@google.com>
1972 lines
40 KiB
Text
1972 lines
40 KiB
Text
// 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:
|
|
//
|
|
// v0.20 Adjust record syntax such that () is allowed (denoting the empty
|
|
// record type and the empty record value).
|
|
//
|
|
// v0.19 Add support for super parameters, named arguments everywhere, and
|
|
// records.
|
|
//
|
|
// v0.18 Add support for enhanced `enum` declarations.
|
|
//
|
|
// v0.17 (58d917e7573c359580ade43845004dbbc62220d5) Correct `uri` to allow
|
|
// multi-line strings (raw and non-raw).
|
|
//
|
|
// v0.16 (284695f1937c262523a9a11b9084213f889c83e0) Correct instance variable
|
|
// declaration syntax such that `covariant late final` is allowed.
|
|
//
|
|
// v0.15 (6facd6dfdafa2953e8523348220d3129ea884678) Add support for
|
|
// constructor tearoffs and explicitly instantiated function tearoffs and
|
|
// type literals.
|
|
//
|
|
// v0.14 (f65c20124edd9e04f7b3a6f014f40c16f51052f6) Correct `partHeader`
|
|
// to allow uri syntax in a `PART OF` directive.
|
|
//
|
|
// v0.13 (bb5cb79a2fd57d6a480b922bc650d5cd15948753) Introduce non-terminals
|
|
// `builtinIdentifier` and `reservedWord`; update `typeAlias` to enable
|
|
// non-function type aliases; add missing `metadata` to formal parameter
|
|
// declarations; correct `symbolLiteral` to allow `VOID`;
|
|
|
|
// v0.12 (82403371ac00ddf004be60fa7b705474d2864509) Cf. language issue #1341:
|
|
// correct `metadata`. Change `qualifiedName` such that it only includes the
|
|
// cases with a '.'; the remaining case is added where `qualifiedName` is used.
|
|
//
|
|
// v0.11 (67c703063d5b68c9e132edbaf34dfe375851f5a6) Corrections, mainly:
|
|
// `fieldFormalParameter` now allows `?` on the parameter type; cascade was
|
|
// reorganized in the spec, it is now reorganized similarly here; `?` was
|
|
// removed from argumentPart (null-aware invocation was never added).
|
|
//
|
|
// v0.10 (8ccdb9ae796d543e4ad8f339c847c02b09018d2d) Simplify grammar by making
|
|
// `constructorInvocation` an alternative in `primary`.
|
|
//
|
|
// v0.9 (f4d7951a88e1b738e22b768c3bc72bf1a1062365) Introduce abstract and
|
|
// external variables.
|
|
//
|
|
// v0.8 (a9ea9365ad8a3e3b59115bd889a55b6aa2c5a5fa) Change null-aware
|
|
// invocations of `operator []` and `operator []=` to not have a period.
|
|
//
|
|
// v0.7 (6826faf583f6a543b1a0e2e85bd6a8042607ce00) Introduce extension and
|
|
// mixin declarations. Revise rules about string literals and string
|
|
// interpolation. Reorganize "keywords" (built-in identifiers, reserved words,
|
|
// other words that are specified in the grammar and not parsed as IDENTIFIER)
|
|
// into explicitly marked groups. Change the cascade syntax to be
|
|
// compositional.
|
|
//
|
|
// v0.6 (a58052974ec2b4b334922c5227b043ed2b9c2cc5) Introduce syntax associated
|
|
// with null safety.
|
|
//
|
|
// v0.5 (56793b3d4714d4818d855a72074d5295489aef3f) Stop treating `ASYNC` as a
|
|
// conditional reserved word (only `AWAIT` and `YIELD` get this treatment).
|
|
//
|
|
// v0.4 Added support for 'unified collections' (spreads and control flow
|
|
// in collection literals).
|
|
//
|
|
// v0.3 Updated to use ANTLR v4 rather than antlr3.
|
|
//
|
|
// v0.2 Changed top level variable declarations to avoid redundant and
|
|
// misleading occurrence of (FINAL|CONST).
|
|
//
|
|
// v0.1 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.
|
|
|
|
grammar Dart;
|
|
|
|
@parser::header{
|
|
import java.util.Stack;
|
|
}
|
|
|
|
@lexer::header{
|
|
import java.util.Stack;
|
|
}
|
|
|
|
@parser::members {
|
|
static String filePath = null;
|
|
static boolean errorHasOccurred = false;
|
|
|
|
/// Must be invoked before the first error is reported for a library.
|
|
/// Will print the name of the library and indicate that it has errors.
|
|
static void prepareForErrors() {
|
|
errorHasOccurred = true;
|
|
System.err.println("Syntax error in " + filePath + ":");
|
|
}
|
|
|
|
/// Parse library, return true if success, false if errors occurred.
|
|
public boolean parseLibrary(String filePath) throws RecognitionException {
|
|
this.filePath = filePath;
|
|
errorHasOccurred = false;
|
|
libraryDefinition();
|
|
return !errorHasOccurred;
|
|
}
|
|
|
|
// Enable the parser to treat 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 AWAIT/YIELD as an identifier/typeIdentifier.
|
|
boolean asyncEtcPredicate(int tokenId) {
|
|
if (tokenId == AWAIT || tokenId == YIELD) {
|
|
return !asyncEtcAreKeywords.peek();
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
@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?
|
|
libraryName?
|
|
importOrExport*
|
|
partDirective*
|
|
(metadata topLevelDefinition)*
|
|
EOF
|
|
;
|
|
|
|
topLevelDefinition
|
|
: classDeclaration
|
|
| mixinDeclaration
|
|
| extensionDeclaration
|
|
| enumType
|
|
| typeAlias
|
|
| EXTERNAL functionSignature ';'
|
|
| EXTERNAL getterSignature ';'
|
|
| EXTERNAL setterSignature ';'
|
|
| EXTERNAL finalVarOrType identifierList ';'
|
|
| getterSignature functionBody
|
|
| setterSignature functionBody
|
|
| functionSignature functionBody
|
|
| (FINAL | CONST) type? staticFinalDeclarationList ';'
|
|
| LATE FINAL type? initializedIdentifierList ';'
|
|
| LATE? varOrType identifier ('=' expression)?
|
|
(',' initializedIdentifier)* ';'
|
|
;
|
|
|
|
declaredIdentifier
|
|
: COVARIANT? finalConstVarOrType identifier
|
|
;
|
|
|
|
finalConstVarOrType
|
|
: LATE? FINAL type?
|
|
| CONST type?
|
|
| LATE? varOrType
|
|
;
|
|
|
|
finalVarOrType
|
|
: FINAL type?
|
|
| varOrType
|
|
;
|
|
|
|
varOrType
|
|
: VAR
|
|
| type
|
|
;
|
|
|
|
initializedIdentifier
|
|
: identifier ('=' expression)?
|
|
;
|
|
|
|
initializedIdentifierList
|
|
: initializedIdentifier (',' initializedIdentifier)*
|
|
;
|
|
|
|
functionSignature
|
|
: type? identifierNotFUNCTION 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 ','? ')'
|
|
| '(' normalFormalParameters ',' optionalOrNamedFormalParameters ')'
|
|
| '(' optionalOrNamedFormalParameters ')'
|
|
;
|
|
|
|
normalFormalParameters
|
|
: normalFormalParameter (',' normalFormalParameter)*
|
|
;
|
|
|
|
optionalOrNamedFormalParameters
|
|
: optionalPositionalFormalParameters
|
|
| namedFormalParameters
|
|
;
|
|
|
|
optionalPositionalFormalParameters
|
|
: '[' defaultFormalParameter (',' defaultFormalParameter)* ','? ']'
|
|
;
|
|
|
|
namedFormalParameters
|
|
: LBRACE defaultNamedParameter (',' defaultNamedParameter)* ','? RBRACE
|
|
;
|
|
|
|
normalFormalParameter
|
|
: metadata normalFormalParameterNoMetadata
|
|
;
|
|
|
|
normalFormalParameterNoMetadata
|
|
: functionFormalParameter
|
|
| fieldFormalParameter
|
|
| simpleFormalParameter
|
|
| superFormalParameter
|
|
;
|
|
|
|
// NB: It is an anomaly that a functionFormalParameter cannot be FINAL.
|
|
functionFormalParameter
|
|
: COVARIANT? type? identifierNotFUNCTION formalParameterPart '?'?
|
|
;
|
|
|
|
simpleFormalParameter
|
|
: declaredIdentifier
|
|
| COVARIANT? identifier
|
|
;
|
|
|
|
// NB: It is an anomaly that VAR can be a return type (`var this.x()`).
|
|
fieldFormalParameter
|
|
: finalConstVarOrType? THIS '.' identifier (formalParameterPart '?'?)?
|
|
;
|
|
|
|
superFormalParameter
|
|
: type? SUPER '.' identifier (formalParameterPart '?'?)?
|
|
;
|
|
|
|
defaultFormalParameter
|
|
: normalFormalParameter ('=' expression)?
|
|
;
|
|
|
|
defaultNamedParameter
|
|
: REQUIRED? normalFormalParameter ((':' | '=') expression)?
|
|
;
|
|
|
|
typeWithParameters
|
|
: typeIdentifier typeParameters?
|
|
;
|
|
|
|
classDeclaration
|
|
: ABSTRACT? CLASS typeWithParameters superclass? mixins? interfaces?
|
|
LBRACE (metadata classMemberDefinition)* RBRACE
|
|
| ABSTRACT? CLASS mixinApplicationClass
|
|
;
|
|
|
|
superclass
|
|
: EXTENDS typeNotVoidNotFunction
|
|
;
|
|
|
|
mixins
|
|
: WITH typeNotVoidNotFunctionList
|
|
;
|
|
|
|
interfaces
|
|
: IMPLEMENTS typeNotVoidNotFunctionList
|
|
;
|
|
|
|
classMemberDefinition
|
|
: methodSignature functionBody
|
|
| declaration ';'
|
|
;
|
|
|
|
mixinApplicationClass
|
|
: typeWithParameters '=' mixinApplication ';'
|
|
;
|
|
|
|
mixinDeclaration
|
|
: MIXIN typeIdentifier typeParameters?
|
|
(ON typeNotVoidNotFunctionList)? interfaces?
|
|
LBRACE (metadata mixinMemberDefinition)* RBRACE
|
|
;
|
|
|
|
// TODO: We will probably want to make this more strict.
|
|
mixinMemberDefinition
|
|
: classMemberDefinition
|
|
;
|
|
|
|
extensionDeclaration
|
|
: EXTENSION identifier? typeParameters? ON type
|
|
LBRACE (metadata extensionMemberDefinition)* RBRACE
|
|
;
|
|
|
|
// TODO: We might want to make this more strict.
|
|
extensionMemberDefinition
|
|
: classMemberDefinition
|
|
;
|
|
|
|
methodSignature
|
|
: constructorSignature initializers
|
|
| factoryConstructorSignature
|
|
| STATIC? functionSignature
|
|
| STATIC? getterSignature
|
|
| STATIC? setterSignature
|
|
| operatorSignature
|
|
| constructorSignature
|
|
;
|
|
|
|
declaration
|
|
: EXTERNAL factoryConstructorSignature
|
|
| EXTERNAL constantConstructorSignature
|
|
| EXTERNAL constructorSignature
|
|
| (EXTERNAL STATIC?)? getterSignature
|
|
| (EXTERNAL STATIC?)? setterSignature
|
|
| (EXTERNAL STATIC?)? functionSignature
|
|
| EXTERNAL (STATIC? finalVarOrType | COVARIANT varOrType) identifierList
|
|
| ABSTRACT (finalVarOrType | COVARIANT varOrType) identifierList
|
|
| EXTERNAL? operatorSignature
|
|
| STATIC (FINAL | CONST) type? staticFinalDeclarationList
|
|
| STATIC LATE FINAL type? initializedIdentifierList
|
|
| STATIC LATE? varOrType initializedIdentifierList
|
|
| COVARIANT LATE FINAL type? identifierList
|
|
| COVARIANT LATE? varOrType initializedIdentifierList
|
|
| LATE? (FINAL type? | varOrType) initializedIdentifierList
|
|
| redirectingFactoryConstructorSignature
|
|
| constantConstructorSignature (redirection | initializers)?
|
|
| constructorSignature (redirection | initializers)?
|
|
;
|
|
|
|
staticFinalDeclarationList
|
|
: staticFinalDeclaration (',' staticFinalDeclaration)*
|
|
;
|
|
|
|
staticFinalDeclaration
|
|
: identifier '=' expression
|
|
;
|
|
|
|
operatorSignature
|
|
: type? OPERATOR operator formalParameterList
|
|
;
|
|
|
|
operator
|
|
: '~'
|
|
| binaryOperator
|
|
| '[' ']'
|
|
| '[' ']' '='
|
|
;
|
|
|
|
binaryOperator
|
|
: multiplicativeOperator
|
|
| additiveOperator
|
|
| shiftOperator
|
|
| relationalOperator
|
|
| '=='
|
|
| bitwiseOperator
|
|
;
|
|
|
|
getterSignature
|
|
: type? GET identifier
|
|
;
|
|
|
|
setterSignature
|
|
: type? SET identifier formalParameterList
|
|
;
|
|
|
|
constructorSignature
|
|
: constructorName formalParameterList
|
|
;
|
|
|
|
constructorName
|
|
: typeIdentifier ('.' (identifier | NEW))?
|
|
;
|
|
|
|
redirection
|
|
: ':' THIS ('.' (identifier | NEW))? arguments
|
|
;
|
|
|
|
initializers
|
|
: ':' initializerListEntry (',' initializerListEntry)*
|
|
;
|
|
|
|
initializerListEntry
|
|
: SUPER arguments
|
|
| SUPER '.' (identifier | NEW) arguments
|
|
| fieldInitializer
|
|
| assertion
|
|
;
|
|
|
|
fieldInitializer
|
|
: (THIS '.')? identifier '=' initializerExpression
|
|
;
|
|
|
|
initializerExpression
|
|
: conditionalExpression
|
|
| cascade
|
|
;
|
|
|
|
factoryConstructorSignature
|
|
: CONST? FACTORY constructorName formalParameterList
|
|
;
|
|
|
|
redirectingFactoryConstructorSignature
|
|
: CONST? FACTORY constructorName formalParameterList '='
|
|
constructorDesignation
|
|
;
|
|
|
|
constantConstructorSignature
|
|
: CONST constructorName formalParameterList
|
|
;
|
|
|
|
mixinApplication
|
|
: typeNotVoidNotFunction mixins interfaces?
|
|
;
|
|
|
|
enumType
|
|
: ENUM typeIdentifier typeParameters? mixins? interfaces? LBRACE
|
|
enumEntry (',' enumEntry)* (',')?
|
|
(';' (metadata classMemberDefinition)*)?
|
|
RBRACE
|
|
;
|
|
|
|
enumEntry
|
|
: metadata identifier argumentPart?
|
|
| metadata identifier typeArguments? '.' identifier arguments
|
|
;
|
|
|
|
typeParameter
|
|
: metadata typeIdentifier (EXTENDS typeNotVoid)?
|
|
;
|
|
|
|
typeParameters
|
|
: '<' typeParameter (',' typeParameter)* '>'
|
|
;
|
|
|
|
metadata
|
|
: ('@' metadatum)*
|
|
;
|
|
|
|
metadatum
|
|
: constructorDesignation arguments
|
|
| identifier
|
|
| qualifiedName
|
|
;
|
|
|
|
expression
|
|
: functionExpression
|
|
| throwExpression
|
|
| assignableExpression assignmentOperator expression
|
|
| conditionalExpression
|
|
| cascade
|
|
;
|
|
|
|
expressionWithoutCascade
|
|
: functionExpressionWithoutCascade
|
|
| throwExpressionWithoutCascade
|
|
| assignableExpression assignmentOperator expressionWithoutCascade
|
|
| conditionalExpression
|
|
;
|
|
|
|
expressionList
|
|
: expression (',' expression)*
|
|
;
|
|
|
|
primary
|
|
: thisExpression
|
|
| SUPER unconditionalAssignableSelector
|
|
| constObjectExpression
|
|
| newExpression
|
|
| constructorInvocation
|
|
| functionPrimary
|
|
| '(' expression ')'
|
|
| literal
|
|
| identifier
|
|
| constructorTearoff
|
|
;
|
|
|
|
constructorInvocation
|
|
: typeName typeArguments '.' NEW arguments
|
|
| typeName '.' NEW arguments
|
|
;
|
|
|
|
literal
|
|
: nullLiteral
|
|
| booleanLiteral
|
|
| numericLiteral
|
|
| stringLiteral
|
|
| symbolLiteral
|
|
| setOrMapLiteral
|
|
| listLiteral
|
|
| recordLiteral
|
|
;
|
|
|
|
nullLiteral
|
|
: NULL
|
|
;
|
|
|
|
numericLiteral
|
|
: NUMBER
|
|
| HEX_NUMBER
|
|
;
|
|
|
|
booleanLiteral
|
|
: TRUE
|
|
| FALSE
|
|
;
|
|
|
|
stringLiteral
|
|
: (multiLineString | singleLineString)+
|
|
;
|
|
|
|
// Not used in the specification (needed here for <uri>).
|
|
stringLiteralWithoutInterpolation
|
|
: singleStringWithoutInterpolation+
|
|
;
|
|
|
|
setOrMapLiteral
|
|
: CONST? typeArguments? LBRACE elements? RBRACE
|
|
;
|
|
|
|
listLiteral
|
|
: CONST? typeArguments? '[' elements? ']'
|
|
;
|
|
|
|
recordLiteral
|
|
: CONST? recordLiteralNoConst
|
|
;
|
|
|
|
recordLiteralNoConst
|
|
: '(' ')'
|
|
| '(' expression ',' ')'
|
|
| '(' label expression ','? ')'
|
|
| '(' recordField ',' recordField (',' recordField)* ','? ')'
|
|
;
|
|
|
|
recordField
|
|
: label? expression
|
|
;
|
|
|
|
elements
|
|
: element (',' element)* ','?
|
|
;
|
|
|
|
element
|
|
: expressionElement
|
|
| mapElement
|
|
| spreadElement
|
|
| ifElement
|
|
| forElement
|
|
;
|
|
|
|
expressionElement
|
|
: expression
|
|
;
|
|
|
|
mapElement
|
|
: expression ':' expression
|
|
;
|
|
|
|
spreadElement
|
|
: ('...' | '...?') expression
|
|
;
|
|
|
|
ifElement
|
|
: IF '(' expression ')' element (ELSE element)?
|
|
;
|
|
|
|
forElement
|
|
: AWAIT? FOR '(' forLoopParts ')' element
|
|
;
|
|
|
|
constructorTearoff
|
|
: typeName typeArguments? '.' NEW
|
|
;
|
|
|
|
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
|
|
: argument (',' argument)*
|
|
;
|
|
|
|
argument
|
|
: label? expression
|
|
;
|
|
|
|
cascade
|
|
: cascade '..' cascadeSection
|
|
| conditionalExpression ('?..' | '..') cascadeSection
|
|
;
|
|
|
|
cascadeSection
|
|
: cascadeSelector cascadeSectionTail
|
|
;
|
|
|
|
cascadeSelector
|
|
: '[' expression ']'
|
|
| identifier
|
|
;
|
|
|
|
cascadeSectionTail
|
|
: cascadeAssignment
|
|
| selector* (assignableSelector cascadeAssignment)?
|
|
;
|
|
|
|
cascadeAssignment
|
|
: assignmentOperator expressionWithoutCascade
|
|
;
|
|
|
|
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 unaryExpression
|
|
| awaitExpression
|
|
| postfixExpression
|
|
| (minusOperator | tildeOperator) SUPER
|
|
| incrementOperator assignableExpression
|
|
;
|
|
|
|
prefixOperator
|
|
: minusOperator
|
|
| negationOperator
|
|
| tildeOperator
|
|
;
|
|
|
|
minusOperator
|
|
: '-'
|
|
;
|
|
|
|
negationOperator
|
|
: '!'
|
|
;
|
|
|
|
tildeOperator
|
|
: '~'
|
|
;
|
|
|
|
awaitExpression
|
|
: AWAIT unaryExpression
|
|
;
|
|
|
|
postfixExpression
|
|
: assignableExpression postfixOperator
|
|
| primary selector*
|
|
;
|
|
|
|
postfixOperator
|
|
: incrementOperator
|
|
;
|
|
|
|
selector
|
|
: '!'
|
|
| assignableSelector
|
|
| argumentPart
|
|
| typeArguments
|
|
;
|
|
|
|
argumentPart
|
|
: typeArguments? arguments
|
|
;
|
|
|
|
incrementOperator
|
|
: '++'
|
|
| '--'
|
|
;
|
|
|
|
assignableExpression
|
|
: SUPER unconditionalAssignableSelector
|
|
| primary assignableSelectorPart
|
|
| identifier
|
|
;
|
|
|
|
assignableSelectorPart
|
|
: selector* assignableSelector
|
|
;
|
|
|
|
unconditionalAssignableSelector
|
|
: '[' expression ']'
|
|
| '.' identifier
|
|
;
|
|
|
|
assignableSelector
|
|
: unconditionalAssignableSelector
|
|
| '?.' identifier
|
|
| '?' '[' expression ']'
|
|
;
|
|
|
|
identifierNotFUNCTION
|
|
: IDENTIFIER
|
|
| builtInIdentifier
|
|
| ASYNC // Not a built-in identifier.
|
|
| 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.
|
|
| { asyncEtcPredicate(getCurrentToken().getType()) }? (AWAIT|YIELD)
|
|
;
|
|
|
|
identifier
|
|
: identifierNotFUNCTION
|
|
| FUNCTION // Built-in identifier that can be used as a type.
|
|
;
|
|
|
|
qualifiedName
|
|
: typeIdentifier '.' (identifier | NEW)
|
|
| typeIdentifier '.' typeIdentifier '.' (identifier | NEW)
|
|
;
|
|
|
|
typeIdentifier
|
|
: IDENTIFIER
|
|
| DYNAMIC // Built-in identifier that can be used as a type.
|
|
| ASYNC // Not a built-in identifier.
|
|
| 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.
|
|
| { asyncEtcPredicate(getCurrentToken().getType()) }? (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
|
|
: block
|
|
| localVariableDeclaration
|
|
| forStatement
|
|
| whileStatement
|
|
| doStatement
|
|
| switchStatement
|
|
| ifStatement
|
|
| rethrowStatement
|
|
| tryStatement
|
|
| breakStatement
|
|
| continueStatement
|
|
| returnStatement
|
|
| localFunctionDeclaration
|
|
| assertStatement
|
|
| yieldStatement
|
|
| yieldEachStatement
|
|
| expressionStatement
|
|
;
|
|
|
|
expressionStatement
|
|
: expression? ';'
|
|
;
|
|
|
|
localVariableDeclaration
|
|
: metadata initializedVariableDeclaration ';'
|
|
;
|
|
|
|
initializedVariableDeclaration
|
|
: declaredIdentifier ('=' expression)? (',' initializedIdentifier)*
|
|
;
|
|
|
|
localFunctionDeclaration
|
|
: metadata functionSignature functionBody
|
|
;
|
|
|
|
ifStatement
|
|
: IF '(' expression ')' statement (ELSE statement)?
|
|
;
|
|
|
|
forStatement
|
|
: AWAIT? FOR '(' forLoopParts ')' statement
|
|
;
|
|
|
|
forLoopParts
|
|
: metadata declaredIdentifier IN expression
|
|
| metadata 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
|
|
| 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 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
|
|
: assertion ';'
|
|
;
|
|
|
|
assertion
|
|
: ASSERT '(' expression (',' expression)? ','? ')'
|
|
;
|
|
|
|
libraryName
|
|
: metadata LIBRARY dottedIdentifierList ';'
|
|
;
|
|
|
|
dottedIdentifierList
|
|
: identifier ('.' identifier)*
|
|
;
|
|
|
|
importOrExport
|
|
: libraryImport
|
|
| libraryExport
|
|
;
|
|
|
|
libraryImport
|
|
: metadata importSpecification
|
|
;
|
|
|
|
importSpecification
|
|
: IMPORT configurableUri (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 (dottedIdentifierList | uri)';'
|
|
;
|
|
|
|
partDeclaration
|
|
: partHeader topLevelDefinition* EOF
|
|
;
|
|
|
|
// In the specification a plain <stringLiteral> is used.
|
|
// TODO(eernst): Check whether it creates ambiguities to do that.
|
|
uri
|
|
: stringLiteralWithoutInterpolation
|
|
;
|
|
|
|
configurableUri
|
|
: uri configurationUri*
|
|
;
|
|
|
|
configurationUri
|
|
: IF '(' uriTest ')' uri
|
|
;
|
|
|
|
uriTest
|
|
: dottedIdentifierList ('==' stringLiteral)?
|
|
;
|
|
|
|
type
|
|
: functionType '?'?
|
|
| typeNotFunction
|
|
;
|
|
|
|
typeNotVoid
|
|
: functionType '?'?
|
|
| recordType '?'?
|
|
| typeNotVoidNotFunction
|
|
;
|
|
|
|
typeNotFunction
|
|
: typeNotVoidNotFunction
|
|
| recordType '?'?
|
|
| VOID
|
|
;
|
|
|
|
typeNotVoidNotFunction
|
|
: typeName typeArguments? '?'?
|
|
| FUNCTION '?'?
|
|
;
|
|
|
|
typeName
|
|
: typeIdentifier ('.' typeIdentifier)?
|
|
;
|
|
|
|
typeArguments
|
|
: '<' typeList '>'
|
|
;
|
|
|
|
typeList
|
|
: type (',' type)*
|
|
;
|
|
|
|
recordType
|
|
: '(' ')'
|
|
| '(' recordTypeFields ',' recordTypeNamedFields ')'
|
|
| '(' recordTypeFields ','? ')'
|
|
| '(' recordTypeNamedFields? ')'
|
|
;
|
|
|
|
recordTypeFields
|
|
: recordTypeField (',' recordTypeField)*
|
|
;
|
|
|
|
recordTypeField
|
|
: metadata type identifier?
|
|
;
|
|
|
|
recordTypeNamedFields
|
|
: LBRACE recordTypeNamedField (',' recordTypeNamedField)* ','? RBRACE
|
|
;
|
|
|
|
recordTypeNamedField
|
|
: metadata typedIdentifier
|
|
;
|
|
|
|
typeNotVoidNotFunctionList
|
|
: typeNotVoidNotFunction (',' typeNotVoidNotFunction)*
|
|
;
|
|
|
|
typeAlias
|
|
: TYPEDEF typeIdentifier typeParameters? '=' type ';'
|
|
| TYPEDEF functionTypeAlias
|
|
;
|
|
|
|
functionTypeAlias
|
|
: functionPrefix formalParameterPart ';'
|
|
;
|
|
|
|
functionPrefix
|
|
: type identifier
|
|
| identifier
|
|
;
|
|
|
|
functionTypeTail
|
|
: FUNCTION typeParameters? parameterTypeList
|
|
;
|
|
|
|
functionTypeTails
|
|
: functionTypeTail '?'? functionTypeTails
|
|
| functionTypeTail
|
|
;
|
|
|
|
functionType
|
|
: functionTypeTails
|
|
| typeNotFunction functionTypeTails
|
|
;
|
|
|
|
parameterTypeList
|
|
: '(' ')'
|
|
| '(' normalParameterTypes ',' optionalParameterTypes ')'
|
|
| '(' normalParameterTypes ','? ')'
|
|
| '(' optionalParameterTypes ')'
|
|
;
|
|
|
|
normalParameterTypes
|
|
: normalParameterType (',' normalParameterType)*
|
|
;
|
|
|
|
normalParameterType
|
|
: metadata typedIdentifier
|
|
| metadata type
|
|
;
|
|
|
|
optionalParameterTypes
|
|
: optionalPositionalParameterTypes
|
|
| namedParameterTypes
|
|
;
|
|
|
|
optionalPositionalParameterTypes
|
|
: '[' normalParameterTypes ','? ']'
|
|
;
|
|
|
|
namedParameterTypes
|
|
: LBRACE namedParameterType (',' namedParameterType)* ','? RBRACE
|
|
;
|
|
|
|
namedParameterType
|
|
: metadata REQUIRED? typedIdentifier
|
|
;
|
|
|
|
typedIdentifier
|
|
: type identifier
|
|
;
|
|
|
|
constructorDesignation
|
|
: typeIdentifier
|
|
| qualifiedName
|
|
| typeName typeArguments ('.' (identifier | NEW))?
|
|
;
|
|
|
|
symbolLiteral
|
|
: '#' (operator | (identifier ('.' identifier)*) | VOID)
|
|
;
|
|
|
|
// Not used in the specification (needed here for <uri>).
|
|
singleStringWithoutInterpolation
|
|
: RAW_SINGLE_LINE_STRING
|
|
| RAW_MULTI_LINE_STRING
|
|
| SINGLE_LINE_STRING_DQ_BEGIN_END
|
|
| SINGLE_LINE_STRING_SQ_BEGIN_END
|
|
| MULTI_LINE_STRING_DQ_BEGIN_END
|
|
| MULTI_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
|
|
;
|
|
|
|
reservedWord
|
|
: ASSERT
|
|
| BREAK
|
|
| CASE
|
|
| CATCH
|
|
| CLASS
|
|
| CONST
|
|
| CONTINUE
|
|
| DEFAULT
|
|
| DO
|
|
| ELSE
|
|
| ENUM
|
|
| EXTENDS
|
|
| FALSE
|
|
| FINAL
|
|
| FINALLY
|
|
| FOR
|
|
| IF
|
|
| IN
|
|
| IS
|
|
| NEW
|
|
| NULL
|
|
| RETHROW
|
|
| RETURN
|
|
| SUPER
|
|
| SWITCH
|
|
| THIS
|
|
| THROW
|
|
| TRUE
|
|
| TRY
|
|
| VAR
|
|
| VOID
|
|
| WHILE
|
|
| WITH
|
|
;
|
|
|
|
builtInIdentifier
|
|
: ABSTRACT
|
|
| AS
|
|
| COVARIANT
|
|
| DEFERRED
|
|
| DYNAMIC
|
|
| EXPORT
|
|
| EXTENSION
|
|
| EXTERNAL
|
|
| FACTORY
|
|
| FUNCTION
|
|
| GET
|
|
| IMPLEMENTS
|
|
| IMPORT
|
|
| INTERFACE
|
|
| LATE
|
|
| LIBRARY
|
|
| OPERATOR
|
|
| MIXIN
|
|
| PART
|
|
| REQUIRED
|
|
| SET
|
|
| STATIC
|
|
| TYPEDEF
|
|
;
|
|
|
|
// ---------------------------------------- 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
|
|
;
|
|
|
|
// Reserved words.
|
|
|
|
ASSERT
|
|
: 'assert'
|
|
;
|
|
|
|
BREAK
|
|
: 'break'
|
|
;
|
|
|
|
CASE
|
|
: 'case'
|
|
;
|
|
|
|
CATCH
|
|
: 'catch'
|
|
;
|
|
|
|
CLASS
|
|
: 'class'
|
|
;
|
|
|
|
CONST
|
|
: 'const'
|
|
;
|
|
|
|
CONTINUE
|
|
: 'continue'
|
|
;
|
|
|
|
DEFAULT
|
|
: 'default'
|
|
;
|
|
|
|
DO
|
|
: 'do'
|
|
;
|
|
|
|
ELSE
|
|
: 'else'
|
|
;
|
|
|
|
ENUM
|
|
: 'enum'
|
|
;
|
|
|
|
EXTENDS
|
|
: 'extends'
|
|
;
|
|
|
|
FALSE
|
|
: 'false'
|
|
;
|
|
|
|
FINAL
|
|
: 'final'
|
|
;
|
|
|
|
FINALLY
|
|
: 'finally'
|
|
;
|
|
|
|
FOR
|
|
: 'for'
|
|
;
|
|
|
|
IF
|
|
: 'if'
|
|
;
|
|
|
|
IN
|
|
: 'in'
|
|
;
|
|
|
|
IS
|
|
: 'is'
|
|
;
|
|
|
|
NEW
|
|
: 'new'
|
|
;
|
|
|
|
NULL
|
|
: 'null'
|
|
;
|
|
|
|
RETHROW
|
|
: 'rethrow'
|
|
;
|
|
|
|
RETURN
|
|
: 'return'
|
|
;
|
|
|
|
SUPER
|
|
: 'super'
|
|
;
|
|
|
|
SWITCH
|
|
: 'switch'
|
|
;
|
|
|
|
THIS
|
|
: 'this'
|
|
;
|
|
|
|
THROW
|
|
: 'throw'
|
|
;
|
|
|
|
TRUE
|
|
: 'true'
|
|
;
|
|
|
|
TRY
|
|
: 'try'
|
|
;
|
|
|
|
VAR
|
|
: 'var'
|
|
;
|
|
|
|
VOID
|
|
: 'void'
|
|
;
|
|
|
|
WHILE
|
|
: 'while'
|
|
;
|
|
|
|
WITH
|
|
: 'with'
|
|
;
|
|
|
|
// Built-in identifiers.
|
|
|
|
ABSTRACT
|
|
: 'abstract'
|
|
;
|
|
|
|
AS
|
|
: 'as'
|
|
;
|
|
|
|
COVARIANT
|
|
: 'covariant'
|
|
;
|
|
|
|
DEFERRED
|
|
: 'deferred'
|
|
;
|
|
|
|
DYNAMIC
|
|
: 'dynamic'
|
|
;
|
|
|
|
EXPORT
|
|
: 'export'
|
|
;
|
|
|
|
EXTENSION
|
|
: 'extension'
|
|
;
|
|
|
|
EXTERNAL
|
|
: 'external'
|
|
;
|
|
|
|
FACTORY
|
|
: 'factory'
|
|
;
|
|
|
|
FUNCTION
|
|
: 'Function'
|
|
;
|
|
|
|
GET
|
|
: 'get'
|
|
;
|
|
|
|
IMPLEMENTS
|
|
: 'implements'
|
|
;
|
|
|
|
IMPORT
|
|
: 'import'
|
|
;
|
|
|
|
INTERFACE
|
|
: 'interface'
|
|
;
|
|
|
|
LATE
|
|
: 'late'
|
|
;
|
|
|
|
LIBRARY
|
|
: 'library'
|
|
;
|
|
|
|
OPERATOR
|
|
: 'operator'
|
|
;
|
|
|
|
MIXIN
|
|
: 'mixin'
|
|
;
|
|
|
|
PART
|
|
: 'part'
|
|
;
|
|
|
|
REQUIRED
|
|
: 'required'
|
|
;
|
|
|
|
SET
|
|
: 'set'
|
|
;
|
|
|
|
STATIC
|
|
: 'static'
|
|
;
|
|
|
|
TYPEDEF
|
|
: 'typedef'
|
|
;
|
|
|
|
// "Contextual keywords".
|
|
|
|
AWAIT
|
|
: 'await'
|
|
;
|
|
|
|
YIELD
|
|
: 'yield'
|
|
;
|
|
|
|
// Other words used in the grammar.
|
|
|
|
ASYNC
|
|
: 'async'
|
|
;
|
|
|
|
HIDE
|
|
: 'hide'
|
|
;
|
|
|
|
OF
|
|
: 'of'
|
|
;
|
|
|
|
ON
|
|
: 'on'
|
|
;
|
|
|
|
SHOW
|
|
: 'show'
|
|
;
|
|
|
|
SYNC
|
|
: 'sync'
|
|
;
|
|
|
|
// Lexical tokens that are not words.
|
|
|
|
NUMBER
|
|
: 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' '"""' (.)*? '"""'
|
|
| 'r' '\'\'\'' (.)*? '\'\'\''
|
|
;
|
|
|
|
fragment
|
|
SIMPLE_STRING_INTERPOLATION
|
|
: '$' IDENTIFIER_NO_DOLLAR
|
|
;
|
|
|
|
fragment
|
|
ESCAPE_SEQUENCE
|
|
: '\\n'
|
|
| '\\r'
|
|
| '\\b'
|
|
| '\\t'
|
|
| '\\v'
|
|
| '\\x' HEX_DIGIT HEX_DIGIT
|
|
| '\\u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
|
|
| '\\u{' HEX_DIGIT_SEQUENCE '}'
|
|
;
|
|
|
|
fragment
|
|
HEX_DIGIT_SEQUENCE
|
|
: HEX_DIGIT HEX_DIGIT? HEX_DIGIT?
|
|
HEX_DIGIT? HEX_DIGIT? HEX_DIGIT?
|
|
;
|
|
|
|
fragment
|
|
STRING_CONTENT_COMMON
|
|
: ~('\\' | '\'' | '"' | '$' | '\r' | '\n')
|
|
| ESCAPE_SEQUENCE
|
|
| '\\' ~('n' | 'r' | 'b' | 't' | 'v' | 'x' | 'u' | '\r' | '\n')
|
|
| SIMPLE_STRING_INTERPOLATION
|
|
;
|
|
|
|
fragment
|
|
STRING_CONTENT_SQ
|
|
: STRING_CONTENT_COMMON
|
|
| '"'
|
|
;
|
|
|
|
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) }?
|
|
{ exitBrace(); } '}' STRING_CONTENT_SQ* '${'
|
|
{ enterBraceSingleQuote(); }
|
|
;
|
|
|
|
SINGLE_LINE_STRING_SQ_MID_END
|
|
: { currentBraceLevel(BRACE_SINGLE) }?
|
|
{ exitBrace(); } '}' STRING_CONTENT_SQ* '\''
|
|
;
|
|
|
|
fragment
|
|
STRING_CONTENT_DQ
|
|
: STRING_CONTENT_COMMON
|
|
| '\''
|
|
;
|
|
|
|
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) }?
|
|
{ exitBrace(); } '}' STRING_CONTENT_DQ* '${'
|
|
{ enterBraceDoubleQuote(); }
|
|
;
|
|
|
|
SINGLE_LINE_STRING_DQ_MID_END
|
|
: { currentBraceLevel(BRACE_DOUBLE) }?
|
|
{ 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
|
|
(STRING_CONTENT_COMMON | '"' | '\r' | '\n' | '\\\r' | '\\\n')
|
|
;
|
|
|
|
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) }?
|
|
{ exitBrace(); } '}' STRING_CONTENT_TSQ* QUOTES_SQ '${'
|
|
{ enterBraceThreeSingleQuotes(); }
|
|
;
|
|
|
|
MULTI_LINE_STRING_SQ_MID_END
|
|
: { currentBraceLevel(BRACE_THREE_SINGLE) }?
|
|
{ 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
|
|
(STRING_CONTENT_COMMON | '\'' | '\r' | '\n' | '\\\r' | '\\\n')
|
|
;
|
|
|
|
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) }?
|
|
{ exitBrace(); } '}' STRING_CONTENT_TDQ* QUOTES_DQ '${'
|
|
{ enterBraceThreeDoubleQuotes(); }
|
|
;
|
|
|
|
MULTI_LINE_STRING_DQ_MID_END
|
|
: { currentBraceLevel(BRACE_THREE_DOUBLE) }?
|
|
{ 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
|
|
: '/*' (MULTI_LINE_COMMENT | .)*? '*/'
|
|
{ skip(); }
|
|
;
|
|
|
|
fragment
|
|
NEWLINE
|
|
: ('\r' | '\n' | '\r\n')
|
|
;
|
|
|
|
FEFF
|
|
: '\uFEFF'
|
|
;
|
|
|
|
WS
|
|
: (' ' | '\t' | '\r' | '\n')+
|
|
{ skip(); }
|
|
;
|