|  | // 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.52 Support static access shorthands. | 
|  | // | 
|  | // v0.51 Support a `switchExpression` with no cases. | 
|  | // | 
|  | // v0.50 Add support for digit separators in numeric literals. | 
|  | // | 
|  | // v0.49 Add support for static and top-level members with no implementation. | 
|  | // | 
|  | // v0.48 Add support for enhanced parts. | 
|  | // | 
|  | // v0.47 Make `augment` a built-in identifier (this happened in the feature | 
|  | // specification v1.10, but wasn't done here at the time). | 
|  | // | 
|  | // v0.46 Rename `libraryDefinition` to `libraryDeclaration`, as in the | 
|  | // language specification. Add support for libraries with imports. | 
|  | // | 
|  | // v0.45 Update rule about augmenting extension type declaration to omit | 
|  | // the primary constructor. | 
|  | // | 
|  | // v0.44 Support null-aware elements. | 
|  | // | 
|  | // v0.43 Change rule structure such that the association of metadata | 
|  | // with non-terminals can be explained in a simple and consistent way. | 
|  | // The derivable terms do not change. Remove `metadata` from the kind | 
|  | // of `forLoopParts` where the iteration variable is an existing variable | 
|  | // in scope (this is not implemented, is inconsistent anyway). | 
|  | // | 
|  | // v0.42 Support updated augmented `extensionDeclaration`. | 
|  | // | 
|  | // v0.41 Add missing `enumEntry` update for augmentations. | 
|  | // | 
|  | // v0.40 Include support for augmentation libraries. | 
|  | // | 
|  | // v0.39 Include latest changes to mixin related class modifiers. | 
|  | // | 
|  | // v0.38 Broaden `initializerExpression` to match implemented behavior. | 
|  | // | 
|  | // v0.37 Correct `libraryExport` to use `configurableUri`, not `uri`. | 
|  | // | 
|  | // v0.36 Update syntax from `inline class` to `extension type`, including | 
|  | // a special case of primary constructors. | 
|  | // | 
|  | // v0.35 Change named optional parameter syntax to require '=', that is, | 
|  | // remove the support for ':' as in `void f({int i: 1})`. | 
|  | // | 
|  | // v0.34 Add support for inline classes. | 
|  | // | 
|  | // v0.33 This commit does not change the derived language at all. It just | 
|  | // changes several rules to use the regexp-like grammar operators to simplify | 
|  | // onParts, recordLiteralNoConst, functionTypeTails, and functionType. | 
|  | // | 
|  | // v0.32 Remove unused non-terminal `patterns`. | 
|  | // | 
|  | // v0.31 Inline `identifierNotFUNCTION` into `identifier`. Replace all | 
|  | // other references with `identifier` to match the spec. | 
|  | // | 
|  | // v0.30 Add support for the class modifiers `sealed`, `final`, `base`, | 
|  | // `interface`, and for `mixin class` declarations. Also add support for | 
|  | // unnamed libraries (`library;`). Introduce `otherIdentifier` to help | 
|  | // maintaining consistency when the grammar is modified to mention any words | 
|  | // that weren't previously mentioned, yet are not reserved or built-in. | 
|  | // | 
|  | // v0.29 Add an alternative in the `primary` rule to enable method invocations | 
|  | // of the form `super(...)` and `super<...>(...)`. This was added to the | 
|  | // language specification in May 21, b26e7287c318c0112610fe8b7e175289792dfde2, | 
|  | // but the corresponding update here wasn't done here at the time. | 
|  | // | 
|  | // v0.28 Add support for `new` in `enumEntry`, e.g., `enum E { x.new(); }`. | 
|  | // Add `identifierOrNew` non-terminal to simplify the grammar. | 
|  | // | 
|  | // v0.27 Remove unused non-terminals; make handling of interpolation in URIs | 
|  | // consistent with the language specification. Make `partDeclaration` a | 
|  | // start symbol in addition to `libraryDefinition` (such that no special | 
|  | // precautions are needed in order to parse a part file). Corrected spacing | 
|  | // in several rules. | 
|  | // | 
|  | // v0.26 Add missing `metadata` in `partDeclaration`. | 
|  | // | 
|  | // v0.25 Update pattern rules following changes to the patterns feature | 
|  | // specification since v0.24. | 
|  | // | 
|  | // v0.24 Change constant pattern rules to allow Symbols and negative numbers. | 
|  | // | 
|  | // v0.23 Change logical pattern rules to || and &&. | 
|  | // | 
|  | // v0.22 Change pattern rules, following updated feature specification. | 
|  | // | 
|  | // v0.21 Add support for patterns. | 
|  | // | 
|  | // 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; | 
|  | startSymbol(); | 
|  | 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 function. | 
|  | 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. | 
|  |  | 
|  | startSymbol | 
|  | :    libraryDeclaration | 
|  | |    partDeclaration | 
|  | ; | 
|  |  | 
|  | libraryDeclaration | 
|  | :    FEFF? SCRIPT_TAG? | 
|  | libraryName? | 
|  | importOrExport* | 
|  | partDirective* | 
|  | (metadata topLevelDefinition)* | 
|  | EOF | 
|  | ; | 
|  |  | 
|  | topLevelDefinition | 
|  | :    classDeclaration | 
|  | |    mixinDeclaration | 
|  | |    extensionTypeDeclaration | 
|  | |    extensionDeclaration | 
|  | |    enumType | 
|  | |    typeAlias | 
|  | |    AUGMENT? EXTERNAL functionSignature ';' | 
|  | |    AUGMENT? EXTERNAL getterSignature ';' | 
|  | |    AUGMENT? EXTERNAL setterSignature ';' | 
|  | |    AUGMENT? EXTERNAL finalVarOrType identifierList ';' | 
|  | |    AUGMENT? getterSignature (functionBody | ';') | 
|  | |    AUGMENT? setterSignature (functionBody | ';') | 
|  | |    AUGMENT? functionSignature (functionBody | ';') | 
|  | |    AUGMENT? (FINAL | CONST) type? initializedIdentifierList ';' | 
|  | |    AUGMENT? LATE FINAL type? initializedIdentifierList ';' | 
|  | |    AUGMENT? LATE? varOrType initializedIdentifierList ';' | 
|  | ; | 
|  |  | 
|  | 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? identifier formalParameterPart | 
|  | ; | 
|  |  | 
|  | 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? identifier 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 | 
|  | :    metadata REQUIRED? normalFormalParameterNoMetadata ('=' expression)? | 
|  | ; | 
|  |  | 
|  | typeWithParameters | 
|  | :    typeIdentifier typeParameters? | 
|  | ; | 
|  |  | 
|  | classDeclaration | 
|  | :    AUGMENT? (classModifiers | mixinClassModifiers) | 
|  | CLASS typeWithParameters superclass? interfaces? | 
|  | LBRACE (metadata classMemberDeclaration)* RBRACE | 
|  | |    classModifiers MIXIN? CLASS mixinApplicationClass | 
|  | ; | 
|  |  | 
|  | classModifiers | 
|  | :    SEALED | 
|  | |    ABSTRACT? (BASE | INTERFACE | FINAL)? | 
|  | ; | 
|  |  | 
|  | mixinClassModifiers | 
|  | :    ABSTRACT? BASE? MIXIN | 
|  | ; | 
|  |  | 
|  | superclass | 
|  | :    EXTENDS typeNotVoidNotFunction mixins? | 
|  | |    mixins | 
|  | ; | 
|  |  | 
|  | mixins | 
|  | :    WITH typeNotVoidNotFunctionList | 
|  | ; | 
|  |  | 
|  | interfaces | 
|  | :    IMPLEMENTS typeNotVoidNotFunctionList | 
|  | ; | 
|  |  | 
|  | classMemberDeclaration | 
|  | :    AUGMENT? methodSignature functionBody | 
|  | |    AUGMENT? declaration ';' | 
|  | ; | 
|  |  | 
|  | mixinApplicationClass | 
|  | :    typeWithParameters '=' mixinApplication ';' | 
|  | ; | 
|  |  | 
|  | mixinDeclaration | 
|  | :    AUGMENT? BASE? MIXIN typeWithParameters | 
|  | (ON typeNotVoidNotFunctionList)? interfaces? | 
|  | LBRACE (metadata mixinMemberDeclaration)* RBRACE | 
|  | ; | 
|  |  | 
|  | // TODO: We might want to make this more strict. | 
|  | mixinMemberDeclaration | 
|  | :    classMemberDeclaration | 
|  | ; | 
|  |  | 
|  | extensionTypeDeclaration | 
|  | :    EXTENSION TYPE CONST? typeWithParameters | 
|  | representationDeclaration interfaces? | 
|  | LBRACE (metadata extensionTypeMemberDeclaration)* RBRACE | 
|  | |    AUGMENT EXTENSION TYPE typeWithParameters interfaces? | 
|  | LBRACE (metadata extensionTypeMemberDeclaration)* RBRACE | 
|  | ; | 
|  |  | 
|  | representationDeclaration | 
|  | :    ('.' identifierOrNew)? '(' metadata typedIdentifier ')' | 
|  | ; | 
|  |  | 
|  |  | 
|  | // TODO: We might want to make this more strict. | 
|  | extensionTypeMemberDeclaration | 
|  | :    classMemberDeclaration | 
|  | ; | 
|  |  | 
|  | extensionDeclaration | 
|  | :    EXTENSION typeIdentifierNotType? typeParameters? ON type extensionBody | 
|  | |    AUGMENT EXTENSION typeIdentifierNotType typeParameters? extensionBody | 
|  | ; | 
|  |  | 
|  | extensionBody | 
|  | :    LBRACE (metadata extensionMemberDeclaration)* RBRACE | 
|  | ; | 
|  |  | 
|  | // TODO: We might want to make this more strict. | 
|  | extensionMemberDeclaration | 
|  | :    classMemberDeclaration | 
|  | ; | 
|  |  | 
|  | 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 | 
|  | |    EXTERNAL? operatorSignature | 
|  | |    ABSTRACT (finalVarOrType | COVARIANT varOrType) identifierList | 
|  | |    STATIC (FINAL | CONST) type? initializedIdentifierList | 
|  | |    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)? | 
|  | ; | 
|  |  | 
|  | 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 ('.' identifierOrNew)? | 
|  | ; | 
|  |  | 
|  | // TODO: Add this in the language specification, use it in grammar rules. | 
|  | identifierOrNew | 
|  | :    identifier | 
|  | |    NEW | 
|  | ; | 
|  |  | 
|  | redirection | 
|  | :    ':' THIS ('.' identifierOrNew)? arguments | 
|  | ; | 
|  |  | 
|  | initializers | 
|  | :    ':' initializerListEntry (',' initializerListEntry)* | 
|  | ; | 
|  |  | 
|  | initializerListEntry | 
|  | :    SUPER arguments | 
|  | |    SUPER '.' identifierOrNew arguments | 
|  | |    fieldInitializer | 
|  | |    assertion | 
|  | ; | 
|  |  | 
|  | fieldInitializer | 
|  | :    (THIS '.')? identifier '=' initializerExpression | 
|  | ; | 
|  |  | 
|  | initializerExpression | 
|  | :    throwExpression | 
|  | |    assignableExpression assignmentOperator expression | 
|  | |    conditionalExpression | 
|  | |    cascade | 
|  | ; | 
|  |  | 
|  | factoryConstructorSignature | 
|  | :    CONST? FACTORY constructorName formalParameterList | 
|  | ; | 
|  |  | 
|  | redirectingFactoryConstructorSignature | 
|  | :    CONST? FACTORY constructorName formalParameterList '=' | 
|  | constructorDesignation | 
|  | ; | 
|  |  | 
|  | constantConstructorSignature | 
|  | :    CONST constructorName formalParameterList | 
|  | ; | 
|  |  | 
|  | mixinApplication | 
|  | :    typeNotVoidNotFunction mixins interfaces? | 
|  | ; | 
|  |  | 
|  | enumType | 
|  | :    AUGMENT? ENUM typeWithParameters mixins? interfaces? LBRACE | 
|  | enumEntry (',' enumEntry)* (',')? | 
|  | (';' (metadata classMemberDeclaration)*)? | 
|  | RBRACE | 
|  | ; | 
|  |  | 
|  | enumEntry | 
|  | :    metadata AUGMENT? identifier argumentPart? | 
|  | |    metadata AUGMENT? identifier typeArguments? | 
|  | '.' identifierOrNew arguments | 
|  | ; | 
|  |  | 
|  | typeParameter | 
|  | :    metadata typeIdentifier (EXTENDS typeNotVoid)? | 
|  | ; | 
|  |  | 
|  | typeParameters | 
|  | :    '<' typeParameter (',' typeParameter)* '>' | 
|  | ; | 
|  |  | 
|  | metadata | 
|  | :    ('@' metadatum)* | 
|  | ; | 
|  |  | 
|  | metadatum | 
|  | :    constructorDesignation arguments | 
|  | |    identifier | 
|  | |    qualifiedName | 
|  | ; | 
|  |  | 
|  | expression | 
|  | :    patternAssignment | 
|  | |    functionExpression | 
|  | |    throwExpression | 
|  | |    assignableExpression assignmentOperator expression | 
|  | |    conditionalExpression | 
|  | |    cascade | 
|  | ; | 
|  |  | 
|  | expressionWithoutCascade | 
|  | :    functionExpressionWithoutCascade | 
|  | |    throwExpressionWithoutCascade | 
|  | |    assignableExpression assignmentOperator expressionWithoutCascade | 
|  | |    conditionalExpression | 
|  | ; | 
|  |  | 
|  | expressionList | 
|  | :    expression (',' expression)* | 
|  | ; | 
|  |  | 
|  | primary | 
|  | :    thisExpression | 
|  | |    SUPER unconditionalAssignableSelector | 
|  | |    SUPER argumentPart | 
|  | |    functionPrimary | 
|  | |    literal | 
|  | |    identifier | 
|  | |    newExpression | 
|  | |    constObjectExpression | 
|  | |    constructorInvocation | 
|  | |    '(' expression ')' | 
|  | |    constructorTearoff | 
|  | |    switchExpression | 
|  | ; | 
|  |  | 
|  | 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)+ | 
|  | ; | 
|  |  | 
|  | setOrMapLiteral | 
|  | :    CONST? typeArguments? LBRACE elements? RBRACE | 
|  | ; | 
|  |  | 
|  | listLiteral | 
|  | :    CONST? typeArguments? '[' elements? ']' | 
|  | ; | 
|  |  | 
|  | recordLiteral | 
|  | :    CONST? recordLiteralNoConst | 
|  | ; | 
|  |  | 
|  | recordLiteralNoConst | 
|  | :    '(' ')' | 
|  | |    '(' expression ',' ')' | 
|  | |    '(' label expression ','? ')' | 
|  | |    '(' recordField (',' recordField)+ ','? ')' | 
|  | ; | 
|  |  | 
|  | recordField | 
|  | :    label? expression | 
|  | ; | 
|  |  | 
|  | elements | 
|  | :    element (',' element)* ','? | 
|  | ; | 
|  |  | 
|  | element | 
|  | :    nullAwareExpressionElement | 
|  | |    nullAwareMapElement | 
|  | |    expressionElement | 
|  | |    mapElement | 
|  | |    spreadElement | 
|  | |    ifElement | 
|  | |    forElement | 
|  | ; | 
|  |  | 
|  | nullAwareExpressionElement | 
|  | :    '?' expression | 
|  | ; | 
|  |  | 
|  | nullAwareMapElement | 
|  | :    '?' expression ':' '?'? expression | 
|  | |    expression ':' '?' expression | 
|  | ; | 
|  |  | 
|  | expressionElement | 
|  | :    expression | 
|  | ; | 
|  |  | 
|  | mapElement | 
|  | :    expression ':' expression | 
|  | ; | 
|  |  | 
|  | spreadElement | 
|  | :    ('...' | '...?') expression | 
|  | ; | 
|  |  | 
|  | ifElement | 
|  | :    ifCondition element (ELSE element)? | 
|  | ; | 
|  |  | 
|  | forElement | 
|  | :    AWAIT? FOR '(' forLoopParts ')' element | 
|  | ; | 
|  |  | 
|  | constructorTearoff | 
|  | :    typeName typeArguments? '.' NEW | 
|  | ; | 
|  |  | 
|  | switchExpression | 
|  | :    SWITCH '(' expression ')' | 
|  | LBRACE (switchExpressionCase (',' switchExpressionCase)* ','?)? RBRACE | 
|  | ; | 
|  |  | 
|  | switchExpressionCase | 
|  | :    guardedPattern '=>' expression | 
|  | ; | 
|  |  | 
|  | staticMemberShorthand | 
|  | :    staticMemberShorthandHead selector* | 
|  | ; | 
|  |  | 
|  | staticMemberShorthandHead | 
|  | :    '.' identifierOrNew | 
|  | |    CONST '.' identifierOrNew arguments | 
|  | ; | 
|  |  | 
|  | throwExpression | 
|  | :    THROW expression | 
|  | ; | 
|  |  | 
|  | throwExpressionWithoutCascade | 
|  | :    THROW expressionWithoutCascade | 
|  | ; | 
|  |  | 
|  | functionExpression | 
|  | :    formalParameterPart functionExpressionBody | 
|  | ; | 
|  |  | 
|  | functionExpressionBody | 
|  | :    '=>' { startNonAsyncFunction(); } expression { endFunction(); } | 
|  | |    ASYNC '=>' { startAsyncFunction(); } expression { endFunction(); } | 
|  | ; | 
|  |  | 
|  | functionExpressionWithoutCascade | 
|  | :    formalParameterPart functionExpressionWithoutCascadeBody | 
|  | ; | 
|  |  | 
|  | functionExpressionWithoutCascadeBody | 
|  | :    '=>' { startNonAsyncFunction(); } | 
|  | expressionWithoutCascade { endFunction(); } | 
|  | |    ASYNC '=>' { startAsyncFunction(); } | 
|  | expressionWithoutCascade { endFunction(); } | 
|  | ; | 
|  |  | 
|  | functionPrimary | 
|  | :    formalParameterPart functionPrimaryBody | 
|  | ; | 
|  |  | 
|  | functionPrimaryBody | 
|  | :    { startNonAsyncFunction(); } block { endFunction(); } | 
|  | |    (ASYNC | ASYNC '*' | SYNC '*') | 
|  | { startAsyncFunction(); } block { endFunction(); } | 
|  | ; | 
|  |  | 
|  | 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* | 
|  | |    staticMemberShorthand | 
|  | ; | 
|  |  | 
|  | 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 ']' | 
|  | ; | 
|  |  | 
|  | identifier | 
|  | :    IDENTIFIER | 
|  | |    builtInIdentifier | 
|  | |    otherIdentifier | 
|  | |    { asyncEtcPredicate(getCurrentToken().getType()) }? (AWAIT|YIELD) | 
|  | ; | 
|  |  | 
|  | qualifiedName | 
|  | :    typeIdentifier '.' identifierOrNew | 
|  | |    typeIdentifier '.' typeIdentifier '.' identifierOrNew | 
|  | ; | 
|  |  | 
|  | typeIdentifierNotType | 
|  | :    IDENTIFIER | 
|  | |    DYNAMIC // Built-in identifier that can be used as a type. | 
|  | |    otherIdentifierNotType // Occur in grammar rules, are not built-in. | 
|  | |    { asyncEtcPredicate(getCurrentToken().getType()) }? (AWAIT|YIELD) | 
|  | ; | 
|  |  | 
|  | typeIdentifier | 
|  | :    typeIdentifierNotType | 
|  | |    TYPE | 
|  | ; | 
|  |  | 
|  | typeTest | 
|  | :    isOperator typeNotVoid | 
|  | ; | 
|  |  | 
|  | isOperator | 
|  | :    IS '!'? | 
|  | ; | 
|  |  | 
|  | typeCast | 
|  | :    asOperator typeNotVoid | 
|  | ; | 
|  |  | 
|  | asOperator | 
|  | :    AS | 
|  | ; | 
|  |  | 
|  | pattern | 
|  | :    logicalOrPattern | 
|  | ; | 
|  |  | 
|  | logicalOrPattern | 
|  | :    logicalAndPattern ('||' logicalAndPattern)* | 
|  | ; | 
|  |  | 
|  | logicalAndPattern | 
|  | :    relationalPattern ('&&' relationalPattern)* | 
|  | ; | 
|  |  | 
|  | relationalPattern | 
|  | :    (equalityOperator | relationalOperator) bitwiseOrExpression | 
|  | |    unaryPattern | 
|  | ; | 
|  |  | 
|  | unaryPattern | 
|  | :    castPattern | 
|  | |    nullCheckPattern | 
|  | |    nullAssertPattern | 
|  | |    primaryPattern | 
|  | ; | 
|  |  | 
|  | primaryPattern | 
|  | :    constantPattern | 
|  | |    variablePattern | 
|  | |    parenthesizedPattern | 
|  | |    listPattern | 
|  | |    mapPattern | 
|  | |    recordPattern | 
|  | |    objectPattern | 
|  | ; | 
|  |  | 
|  | castPattern | 
|  | :    primaryPattern AS type | 
|  | ; | 
|  |  | 
|  | nullCheckPattern | 
|  | :    primaryPattern '?' | 
|  | ; | 
|  |  | 
|  | nullAssertPattern | 
|  | :    primaryPattern '!' | 
|  | ; | 
|  |  | 
|  | constantPattern | 
|  | :    booleanLiteral | 
|  | |    nullLiteral | 
|  | |    '-'? numericLiteral | 
|  | |    stringLiteral | 
|  | |    symbolLiteral | 
|  | |    identifier | 
|  | |    qualifiedName | 
|  | |    constObjectExpression | 
|  | |    CONST typeArguments? '[' elements? ']' | 
|  | |    CONST typeArguments? LBRACE elements? RBRACE | 
|  | |    CONST '(' expression ')' | 
|  | |    staticMemberShorthand | 
|  | ; | 
|  |  | 
|  | variablePattern | 
|  | :    (VAR | FINAL | FINAL? type)? identifier | 
|  | ; | 
|  |  | 
|  | parenthesizedPattern | 
|  | :    '(' pattern ')' | 
|  | ; | 
|  |  | 
|  | listPattern | 
|  | :    typeArguments? '[' listPatternElements? ']' | 
|  | ; | 
|  |  | 
|  | listPatternElements | 
|  | :    listPatternElement (',' listPatternElement)* ','? | 
|  | ; | 
|  |  | 
|  | listPatternElement | 
|  | :    pattern | 
|  | |    restPattern | 
|  | ; | 
|  |  | 
|  | restPattern | 
|  | :    '...' pattern? | 
|  | ; | 
|  |  | 
|  | mapPattern | 
|  | :    typeArguments? LBRACE mapPatternEntries? RBRACE | 
|  | ; | 
|  |  | 
|  | mapPatternEntries | 
|  | :    mapPatternEntry (',' mapPatternEntry)* ','? | 
|  | ; | 
|  |  | 
|  | mapPatternEntry | 
|  | :    expression ':' pattern | 
|  | |    '...' | 
|  | ; | 
|  |  | 
|  | recordPattern | 
|  | :    '(' patternFields? ')' | 
|  | ; | 
|  |  | 
|  | patternFields | 
|  | :    patternField (',' patternField)* ','? | 
|  | ; | 
|  |  | 
|  | patternField | 
|  | :    (identifier? ':')? pattern | 
|  | ; | 
|  |  | 
|  | objectPattern | 
|  | :    (typeName typeArguments? | typeNamedFunction) '(' patternFields? ')' | 
|  | ; | 
|  |  | 
|  | patternVariableDeclaration | 
|  | :    outerPatternDeclarationPrefix '=' expression | 
|  | ; | 
|  |  | 
|  | outerPattern | 
|  | :    parenthesizedPattern | 
|  | |    listPattern | 
|  | |    mapPattern | 
|  | |    recordPattern | 
|  | |    objectPattern | 
|  | ; | 
|  |  | 
|  | outerPatternDeclarationPrefix | 
|  | :    (FINAL | VAR) outerPattern | 
|  | ; | 
|  |  | 
|  | patternAssignment | 
|  | :    outerPattern '=' expression | 
|  | ; | 
|  |  | 
|  | 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 ';' | 
|  | |    metadata patternVariableDeclaration ';' | 
|  | ; | 
|  |  | 
|  | initializedVariableDeclaration | 
|  | :    declaredIdentifier ('=' expression)? (',' initializedIdentifier)* | 
|  | ; | 
|  |  | 
|  | localFunctionDeclaration | 
|  | :    metadata functionSignature functionBody | 
|  | ; | 
|  |  | 
|  | ifStatement | 
|  | :    ifCondition statement (ELSE statement)? | 
|  | ; | 
|  |  | 
|  | ifCondition | 
|  | :    IF '(' expression (CASE guardedPattern)? ')' | 
|  | ; | 
|  |  | 
|  | forStatement | 
|  | :    AWAIT? FOR '(' forLoopParts ')' statement | 
|  | ; | 
|  |  | 
|  | forLoopParts | 
|  | :    forInLoopPrefix IN expression | 
|  | |    forInitializerStatement expression? ';' expressionList? | 
|  | ; | 
|  |  | 
|  | forInLoopPrefix | 
|  | :    metadata declaredIdentifier | 
|  | |    metadata outerPatternDeclarationPrefix | 
|  | |    identifier | 
|  | ; | 
|  |  | 
|  | // 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 switchStatementCase* switchStatementDefault? RBRACE | 
|  | ; | 
|  |  | 
|  | switchStatementCase | 
|  | :    label* CASE guardedPattern ':' statements | 
|  | ; | 
|  |  | 
|  | guardedPattern | 
|  | :    pattern (WHEN expression)? | 
|  | ; | 
|  |  | 
|  | switchStatementDefault | 
|  | :    label* DEFAULT ':' statements | 
|  | ; | 
|  |  | 
|  | rethrowStatement | 
|  | :    RETHROW ';' | 
|  | ; | 
|  |  | 
|  | tryStatement | 
|  | :    TRY block (onPart+ finallyPart? | finallyPart) | 
|  | ; | 
|  |  | 
|  | onPart | 
|  | :    catchPart block | 
|  | |    ON typeNotVoid catchPart? block | 
|  | ; | 
|  |  | 
|  | 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 libraryNameBody ';' | 
|  | ; | 
|  |  | 
|  | libraryNameBody | 
|  | :    LIBRARY dottedIdentifierList? | 
|  | |    AUGMENT LIBRARY uri | 
|  | ; | 
|  |  | 
|  | dottedIdentifierList | 
|  | :    identifier ('.' identifier)* | 
|  | ; | 
|  |  | 
|  | importOrExport | 
|  | :    libraryImport | 
|  | |    libraryAugmentImport | 
|  | |    libraryExport | 
|  | ; | 
|  |  | 
|  | libraryImport | 
|  | :    metadata importSpecification | 
|  | ; | 
|  |  | 
|  | libraryAugmentImport | 
|  | :    metadata IMPORT AUGMENT uri ';' | 
|  | ; | 
|  |  | 
|  | importSpecification | 
|  | :    IMPORT configurableUri (DEFERRED? AS typeIdentifier)? combinator* ';' | 
|  | ; | 
|  |  | 
|  | combinator | 
|  | :    SHOW identifierList | 
|  | |    HIDE identifierList | 
|  | ; | 
|  |  | 
|  | identifierList | 
|  | :    identifier (',' identifier)* | 
|  | ; | 
|  |  | 
|  | libraryExport | 
|  | :    metadata EXPORT configurableUri combinator* ';' | 
|  | ; | 
|  |  | 
|  | partDirective | 
|  | :    metadata PART configurableUri ';' | 
|  | ; | 
|  |  | 
|  | partHeader | 
|  | :    metadata PART OF uri ';' | 
|  | ; | 
|  |  | 
|  | partDeclaration | 
|  | :    FEFF? partHeader | 
|  | importOrExport* | 
|  | partDirective* | 
|  | (metadata topLevelDefinition)* | 
|  | EOF | 
|  | ; | 
|  |  | 
|  | uri | 
|  | :    stringLiteral | 
|  | ; | 
|  |  | 
|  | configurableUri | 
|  | :    uri configurationUri* | 
|  | ; | 
|  |  | 
|  | configurationUri | 
|  | :    IF '(' uriTest ')' uri | 
|  | ; | 
|  |  | 
|  | uriTest | 
|  | :    dottedIdentifierList ('==' stringLiteral)? | 
|  | ; | 
|  |  | 
|  | type | 
|  | :    functionType '?'? | 
|  | |    typeNotFunction | 
|  | ; | 
|  |  | 
|  | typeNotVoid | 
|  | :    functionType '?'? | 
|  | |    recordType '?'? | 
|  | |    typeNotVoidNotFunction '?'? | 
|  | ; | 
|  |  | 
|  | typeNotFunction | 
|  | :    typeNotVoidNotFunction '?'? | 
|  | |    recordType '?'? | 
|  | |    VOID | 
|  | ; | 
|  |  | 
|  | typeNamedFunction | 
|  | :    (typeIdentifier '.')? FUNCTION | 
|  | ; | 
|  |  | 
|  | typeNotVoidNotFunction | 
|  | :    typeName typeArguments? | 
|  | |    typeNamedFunction | 
|  | ; | 
|  |  | 
|  | 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 | 
|  | :    AUGMENT? TYPEDEF typeWithParameters '=' type ';' | 
|  | |    AUGMENT? TYPEDEF functionTypeAlias | 
|  | ; | 
|  |  | 
|  | functionTypeAlias | 
|  | :    functionPrefix formalParameterPart ';' | 
|  | ; | 
|  |  | 
|  | functionPrefix | 
|  | :    type identifier | 
|  | |    identifier | 
|  | ; | 
|  |  | 
|  | functionTypeTail | 
|  | :    FUNCTION typeParameters? parameterTypeList | 
|  | ; | 
|  |  | 
|  | functionTypeTails | 
|  | :    (functionTypeTail '?'?)* functionTypeTail | 
|  | ; | 
|  |  | 
|  | functionType | 
|  | :    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 ('.' identifierOrNew)? | 
|  | ; | 
|  |  | 
|  | symbolLiteral | 
|  | :    '#' (operator | (identifier ('.' identifier)*) | VOID) | 
|  | ; | 
|  |  | 
|  | 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 | 
|  | |    AUGMENT | 
|  | |    COVARIANT | 
|  | |    DEFERRED | 
|  | |    DYNAMIC | 
|  | |    EXPORT | 
|  | |    EXTENSION | 
|  | |    EXTERNAL | 
|  | |    FACTORY | 
|  | |    FUNCTION | 
|  | |    GET | 
|  | |    IMPLEMENTS | 
|  | |    IMPORT | 
|  | |    INTERFACE | 
|  | |    LATE | 
|  | |    LIBRARY | 
|  | |    OPERATOR | 
|  | |    MIXIN | 
|  | |    PART | 
|  | |    REQUIRED | 
|  | |    SET | 
|  | |    STATIC | 
|  | |    TYPEDEF | 
|  | ; | 
|  |  | 
|  | otherIdentifierNotType | 
|  | :    ASYNC | 
|  | |    BASE | 
|  | |    HIDE | 
|  | |    OF | 
|  | |    ON | 
|  | |    SEALED | 
|  | |    SHOW | 
|  | |    SYNC | 
|  | |    WHEN | 
|  | ; | 
|  |  | 
|  | otherIdentifier | 
|  | :    otherIdentifierNotType | 
|  | |    TYPE | 
|  | ; | 
|  |  | 
|  | // ---------------------------------------- Lexer rules. | 
|  |  | 
|  | fragment | 
|  | LETTER | 
|  | :    'a' .. 'z' | 
|  | |    'A' .. 'Z' | 
|  | ; | 
|  |  | 
|  | fragment | 
|  | DIGIT | 
|  | :    '0' .. '9' | 
|  | ; | 
|  |  | 
|  | fragment | 
|  | EXPONENT | 
|  | :    ('e' | 'E') ('+' | '-')? DIGITS | 
|  | ; | 
|  |  | 
|  | fragment | 
|  | DIGITS | 
|  | :    DIGIT ('_'* DIGIT)* | 
|  | ; | 
|  |  | 
|  | fragment | 
|  | HEX_DIGIT | 
|  | :    ('a' | 'b' | 'c' | 'd' | 'e' | 'f') | 
|  | |    ('A' | 'B' | 'C' | 'D' | 'E' | 'F') | 
|  | |    DIGIT | 
|  | ; | 
|  |  | 
|  | fragment | 
|  | HEX_DIGITS | 
|  | :    HEX_DIGIT ('_'* HEX_DIGIT)* | 
|  | ; | 
|  |  | 
|  | // Reserved words (if updated, update `reservedWord` as well). | 
|  |  | 
|  | 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 (if updated, update `builtInIdentifier` as well). | 
|  |  | 
|  | ABSTRACT | 
|  | :    'abstract' | 
|  | ; | 
|  |  | 
|  | AS | 
|  | :    'as' | 
|  | ; | 
|  |  | 
|  | AUGMENT | 
|  | :    'augment' | 
|  | ; | 
|  |  | 
|  | 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 (if updated, update `otherIdentifier`, too). | 
|  |  | 
|  | ASYNC | 
|  | :    'async' | 
|  | ; | 
|  |  | 
|  | BASE | 
|  | :    'base' | 
|  | ; | 
|  |  | 
|  | HIDE | 
|  | :    'hide' | 
|  | ; | 
|  |  | 
|  | OF | 
|  | :    'of' | 
|  | ; | 
|  |  | 
|  | ON | 
|  | :    'on' | 
|  | ; | 
|  |  | 
|  | SEALED | 
|  | :    'sealed' | 
|  | ; | 
|  |  | 
|  | SHOW | 
|  | :    'show' | 
|  | ; | 
|  |  | 
|  | SYNC | 
|  | :    'sync' | 
|  | ; | 
|  |  | 
|  | TYPE | 
|  | :    'type' | 
|  | ; | 
|  |  | 
|  | WHEN | 
|  | :    'when' | 
|  | ; | 
|  |  | 
|  | // Lexical tokens that are not words. | 
|  |  | 
|  | NUMBER | 
|  | :    DIGITS ('.' DIGITS)? EXPONENT? | 
|  | |    '.' DIGITS EXPONENT? | 
|  | ; | 
|  |  | 
|  | HEX_NUMBER | 
|  | :    '0x' HEX_DIGITS | 
|  | |    '0X' HEX_DIGITS | 
|  | ; | 
|  |  | 
|  | 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(); } | 
|  | ; |