summaryrefslogtreecommitdiffstats
path: root/third_party/rust/jsparagus/js_parser
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /third_party/rust/jsparagus/js_parser
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/jsparagus/js_parser')
-rw-r--r--third_party/rust/jsparagus/js_parser/README.md67
-rw-r--r--third_party/rust/jsparagus/js_parser/__init__.py0
-rw-r--r--third_party/rust/jsparagus/js_parser/es-lexical-simplified.esgrammar485
-rw-r--r--third_party/rust/jsparagus/js_parser/es-simplified.esgrammar1453
-rw-r--r--third_party/rust/jsparagus/js_parser/es.esgrammar1668
-rw-r--r--third_party/rust/jsparagus/js_parser/esgrammar.pgen290
-rwxr-xr-xthird_party/rust/jsparagus/js_parser/extract_es_grammar.py567
-rwxr-xr-xthird_party/rust/jsparagus/js_parser/generate_js_parser_tables.py140
-rw-r--r--third_party/rust/jsparagus/js_parser/lexer.py315
-rw-r--r--third_party/rust/jsparagus/js_parser/load_es_grammar.py129
-rw-r--r--third_party/rust/jsparagus/js_parser/parse_esgrammar.py545
-rw-r--r--third_party/rust/jsparagus/js_parser/parser.py42
-rw-r--r--third_party/rust/jsparagus/js_parser/slash.esgrammar1683
-rwxr-xr-xthird_party/rust/jsparagus/js_parser/try_it.py59
14 files changed, 7443 insertions, 0 deletions
diff --git a/third_party/rust/jsparagus/js_parser/README.md b/third_party/rust/jsparagus/js_parser/README.md
new file mode 100644
index 0000000000..a8a814619d
--- /dev/null
+++ b/third_party/rust/jsparagus/js_parser/README.md
@@ -0,0 +1,67 @@
+## jsparagus/js_parser: Generating a parser for JavaScript
+
+In this directory:
+
+* **esgrammar.pgen** A grammar for the mini-language the ECMAScript
+ standard uses to describe ES grammar.
+
+* **es.esgrammar** - The actual grammar for ECMAScript, in emu-grammar
+ format, extracted automatically from the spec.
+
+* **extract_es_grammar.py** - The script that creates *es.esgrammar*.
+
+* **es-simplified.esgrammar** - A hacked version of *es.esgrammar* that
+ jsparagus can actually handle.
+
+* **generate_js_parser_tables.py** - A script to generate a JS parser
+ based on *es-simplified.esgrammar*. Read on for instructions.
+
+
+## How to run it
+
+To generate a parser, follow these steps:
+
+```console
+$ cd ..
+$ make init
+$ make all
+```
+
+**Note:** The last step currently takes about 35 seconds to run on my
+laptop. jsparagus is slow.
+
+Once you're done, to see your parser run, try this:
+
+```console
+$ cd crates/driver
+$ cargo run --release
+```
+
+The build also produces a copy of the JS parser in Python.
+After `make all`, you can use `make jsdemo` to run that.
+
+
+### How simplified is "es-simplified"?
+
+Here are the differences between *es.esgrammar*, the actual ES grammar,
+and *es-simplified.esgrammar*, the simplified version that jsparagus can
+actually handle:
+
+* The four productions with [~Yield] and [~Await] conditions are dropped.
+ This means that `yield` and `await` do not match *IdentifierReference*
+ or *LabelIdentifier*. I think it's better to do that in the lexer.
+
+* Truncated lookahead.
+
+ `ValueError: unsupported: lookahead > 1 token, [['{'], ['function'], ['async', ('no-LineTerminator-here',), 'function'], ['class'], ['let', '[']]`
+
+* Delete a rule that uses `but not` since it's not implemented.
+
+ Identifier :
+ IdentifierName but not ReservedWord
+
+ Making sense of this rule in the context of an LR parser is an
+ interesting task; see issue #28.
+
+* Ban loops of the form `for (async of EXPR) STMT` by adjusting a
+ lookahead assertion. The grammar is not LR(1).
diff --git a/third_party/rust/jsparagus/js_parser/__init__.py b/third_party/rust/jsparagus/js_parser/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/third_party/rust/jsparagus/js_parser/__init__.py
diff --git a/third_party/rust/jsparagus/js_parser/es-lexical-simplified.esgrammar b/third_party/rust/jsparagus/js_parser/es-lexical-simplified.esgrammar
new file mode 100644
index 0000000000..6b0fd1baf6
--- /dev/null
+++ b/third_party/rust/jsparagus/js_parser/es-lexical-simplified.esgrammar
@@ -0,0 +1,485 @@
+InputElementDiv ::
+ WhiteSpace
+ LineTerminator
+ Comment
+ CommonToken
+ DivPunctuator
+ RightBracePunctuator
+
+InputElementRegExp ::
+ WhiteSpace
+ LineTerminator
+ Comment
+ CommonToken
+ RightBracePunctuator
+ RegularExpressionLiteral
+
+InputElementRegExpOrTemplateTail ::
+ WhiteSpace
+ LineTerminator
+ Comment
+ CommonToken
+ RegularExpressionLiteral
+ TemplateSubstitutionTail
+
+InputElementTemplateTail ::
+ WhiteSpace
+ LineTerminator
+ Comment
+ CommonToken
+ DivPunctuator
+ TemplateSubstitutionTail
+
+
+WhiteSpace ::
+ <TAB>
+ <VT>
+ <FF>
+ <SP>
+ <NBSP>
+ <ZWNBSP>
+ <USP>
+
+
+LineTerminator ::
+ <LF>
+ <CR>
+ <LS>
+ <PS>
+
+LineTerminatorSequence ::
+ <LF>
+ <LS>
+ <PS>
+ <CR> <LF>
+
+
+MultiLineCommentChars ::
+ MultiLineCommentPiece
+ MultiLineCommentChars MultiLineCommentPiece
+
+MultiLineCommentPiece ::
+ MultiLineNotAsteriskChar
+ Stars MultiLineNotForwardSlashOrAsteriskChar
+
+MultiLineNotAsteriskChar ::
+ SourceCharacter but not `*`
+
+MultiLineNotForwardSlashOrAsteriskChar ::
+ SourceCharacter but not one of `/` or `*`
+
+SingleLineComment ::
+ `//` SingleLineCommentChars?
+
+SingleLineCommentChars ::
+ SingleLineCommentChar SingleLineCommentChars?
+
+SingleLineCommentChar ::
+ SourceCharacter but not LineTerminator
+
+
+CommonToken ::
+ IdentifierName
+ Punctuator
+ NumericLiteral
+ StringLiteral
+ Template
+
+
+Identifier ::
+ `TODO`
+
+IdentifierName ::
+ IdentifierStart
+ IdentifierName IdentifierPart
+
+IdentifierStart ::
+ UnicodeIDStart
+ `$`
+ `_`
+ `\` UnicodeEscapeSequence
+
+IdentifierPart ::
+ UnicodeIDContinue
+ `$`
+ `\` UnicodeEscapeSequence
+ <ZWNJ>
+ <ZWJ>
+
+UnicodeIDStart ::
+ `TODO`
+
+UnicodeIDContinue ::
+ `TODO`
+
+
+ReservedWord ::
+ Keyword
+ FutureReservedWord
+ NullLiteral
+ BooleanLiteral
+
+
+Keyword :: one of
+ `await`
+ `break`
+ `case` `catch` `class` `const` `continue`
+ `debugger` `default` `delete` `do`
+ `else` `export` `extends`
+ `finally` `for` `function`
+ `if` `import` `in` `instanceof`
+ `new`
+ `return`
+ `super` `switch`
+ `this` `throw` `try` `typeof`
+ `var` `void`
+ `while` `with`
+ `yield`
+
+
+FutureReservedWord ::
+ `enum`
+
+
+Punctuator :: one of
+ `{` `(` `)` `[` `]`
+ `.` `...` `;` `,`
+ `<` `>` `<=` `>=`
+ `==` `!=` `===` `!==`
+ `+` `-` `*` `%` `**`
+ `++` `--`
+ `<<` `>>` `>>>`
+ `&` `|` `^`
+ `!` `~`
+ `&&` `||`
+ `?` `:`
+ `=` `+=` `-=` `*=` `%=` `**=` `<<=` `>>=` `>>>=` `&=` `|=` `^=`
+ `=>`
+
+DivPunctuator ::
+ `/`
+ `/=`
+
+RightBracePunctuator ::
+ `}`
+
+
+NullLiteral ::
+ `null`
+
+
+BooleanLiteral ::
+ `true`
+ `false`
+
+
+DecimalLiteral ::
+ DecimalIntegerLiteral `.` DecimalDigits? ExponentPart?
+ `.` DecimalDigits ExponentPart?
+ DecimalIntegerLiteral ExponentPart?
+
+DecimalDigits ::
+ DecimalDigit
+ DecimalDigits DecimalDigit
+
+DecimalDigit :: one of
+ `0` `1` `2` `3` `4` `5` `6` `7` `8` `9`
+
+NonZeroDigit :: one of
+ `1` `2` `3` `4` `5` `6` `7` `8` `9`
+
+ExponentPart ::
+ ExponentIndicator SignedInteger
+
+ExponentIndicator :: one of
+ `e` `E`
+
+SignedInteger ::
+ DecimalDigits
+ `+` DecimalDigits
+ `-` DecimalDigits
+
+BinaryIntegerLiteral ::
+ `0b` BinaryDigits
+ `0B` BinaryDigits
+
+BinaryDigits ::
+ BinaryDigit
+ BinaryDigits BinaryDigit
+
+BinaryDigit :: one of
+ `0` `1`
+
+OctalIntegerLiteral ::
+ `0o` OctalDigits
+ `0O` OctalDigits
+
+OctalDigits ::
+ OctalDigit
+ OctalDigits OctalDigit
+
+OctalDigit :: one of
+ `0` `1` `2` `3` `4` `5` `6` `7`
+
+HexIntegerLiteral ::
+ `0x` HexDigits
+ `0X` HexDigits
+
+HexDigits ::
+ HexDigit
+ HexDigits HexDigit
+
+HexDigit :: one of
+ `0` `1` `2` `3` `4` `5` `6` `7` `8` `9` `a` `b` `c` `d` `e` `f` `A` `B` `C` `D` `E` `F`
+
+
+StringLiteral ::
+ `"` DoubleStringCharacters? `"`
+ `'` SingleStringCharacters? `'`
+
+DoubleStringCharacters ::
+ DoubleStringCharacter DoubleStringCharacters?
+
+SingleStringCharacters ::
+ SingleStringCharacter SingleStringCharacters?
+
+DoubleStringCharacter ::
+ SourceCharacter but not one of `"` or `\` or LineTerminator
+ <LS>
+ <PS>
+ `\` EscapeSequence
+ LineContinuation
+
+SingleStringCharacter ::
+ SourceCharacter but not one of `'` or `\` or LineTerminator
+ <LS>
+ <PS>
+ `\` EscapeSequence
+ LineContinuation
+
+LineContinuation ::
+ `\` LineTerminatorSequence
+
+
+CharacterEscapeSequence ::
+ SingleEscapeCharacter
+ NonEscapeCharacter
+
+SingleEscapeCharacter :: one of
+ `'` `"` `\` `b` `f` `n` `r` `t` `v`
+
+NonEscapeCharacter ::
+ SourceCharacter but not one of EscapeCharacter or LineTerminator
+
+EscapeCharacter ::
+ SingleEscapeCharacter
+ DecimalDigit
+ `x`
+ `u`
+
+HexEscapeSequence ::
+ `x` HexDigit HexDigit
+
+UnicodeEscapeSequence ::
+ `u` Hex4Digits
+ `u{` CodePoint `}`
+
+Hex4Digits ::
+ HexDigit HexDigit HexDigit HexDigit
+
+
+RegularExpressionLiteral ::
+ `/` RegularExpressionBody `/` RegularExpressionFlags
+
+RegularExpressionBody ::
+ RegularExpressionFirstChar RegularExpressionChars
+
+RegularExpressionChars ::
+ [empty]
+ RegularExpressionChars RegularExpressionChar
+
+RegularExpressionFirstChar ::
+ RegularExpressionNonTerminator but not one of `*` or `\` or `/` or `[`
+ RegularExpressionBackslashSequence
+ RegularExpressionClass
+
+RegularExpressionChar ::
+ RegularExpressionNonTerminator but not one of `\` or `/` or `[`
+ RegularExpressionBackslashSequence
+ RegularExpressionClass
+
+RegularExpressionBackslashSequence ::
+ `\` RegularExpressionNonTerminator
+
+RegularExpressionNonTerminator ::
+ SourceCharacter but not LineTerminator
+
+RegularExpressionClass ::
+ `[` RegularExpressionClassChars `]`
+
+RegularExpressionClassChars ::
+ [empty]
+ RegularExpressionClassChars RegularExpressionClassChar
+
+RegularExpressionClassChar ::
+ RegularExpressionNonTerminator but not one of `]` or `\`
+ RegularExpressionBackslashSequence
+
+RegularExpressionFlags ::
+ [empty]
+ RegularExpressionFlags IdentifierPart
+
+
+Template ::
+ NoSubstitutionTemplate
+ TemplateHead
+
+NoSubstitutionTemplate ::
+ ``` TemplateCharacters? ```
+
+TemplateHead ::
+ ``` TemplateCharacters? `${`
+
+TemplateSubstitutionTail ::
+ TemplateMiddle
+ TemplateTail
+
+TemplateMiddle ::
+ `}` TemplateCharacters? `${`
+
+TemplateTail ::
+ `}` TemplateCharacters? ```
+
+TemplateCharacters ::
+ TemplateCharacter TemplateCharacters?
+
+TemplateCharacter ::
+ `$` [lookahead != `{` ]
+ `\` EscapeSequence
+ `\` NotEscapeSequence
+ LineContinuation
+ LineTerminatorSequence
+ SourceCharacter but not one of ``` or `\` or `$` or LineTerminator
+
+NotEscapeSequence ::
+ `0` DecimalDigit
+ DecimalDigit but not `0`
+ `x` [lookahead <! HexDigit]
+ `x` HexDigit [lookahead <! HexDigit]
+ `u` [lookahead <! HexDigit] [lookahead != `{`]
+ `u` HexDigit [lookahead <! HexDigit]
+ `u` HexDigit HexDigit [lookahead <! HexDigit]
+ `u` HexDigit HexDigit HexDigit [lookahead <! HexDigit]
+ `u` `{` [lookahead <! HexDigit]
+ `u` `{` NotCodePoint [lookahead <! HexDigit]
+ `u` `{` CodePoint [lookahead <! HexDigit] [lookahead != `}`]
+
+NotCodePoint ::
+ HexDigits [> but only if MV of |HexDigits| > 0x10FFFF ]
+
+CodePoint ::
+ HexDigits [> but only if MV of |HexDigits| ≤ 0x10FFFF ]
+
+
+ControlLetter :: one of
+ `a` `b` `c` `d` `e` `f` `g` `h` `i` `j` `k` `l` `m` `n` `o` `p` `q` `r` `s` `t` `u` `v` `w` `x` `y` `z`
+ `A` `B` `C` `D` `E` `F` `G` `H` `I` `J` `K` `L` `M` `N` `O` `P` `Q` `R` `S` `T` `U` `V` `W` `X` `Y` `Z`
+
+
+NumericLiteral ::
+ DecimalLiteral
+ BinaryIntegerLiteral
+ OctalIntegerLiteral
+ HexIntegerLiteral
+ LegacyOctalIntegerLiteral
+
+LegacyOctalIntegerLiteral ::
+ `0` OctalDigit
+ LegacyOctalIntegerLiteral OctalDigit
+
+DecimalIntegerLiteral ::
+ `0`
+ NonZeroDigit DecimalDigits?
+ NonOctalDecimalIntegerLiteral
+
+NonOctalDecimalIntegerLiteral ::
+ `0` NonOctalDigit
+ LegacyOctalLikeDecimalIntegerLiteral NonOctalDigit
+ NonOctalDecimalIntegerLiteral DecimalDigit
+
+LegacyOctalLikeDecimalIntegerLiteral ::
+ `0` OctalDigit
+ LegacyOctalLikeDecimalIntegerLiteral OctalDigit
+
+NonOctalDigit :: one of
+ `8` `9`
+
+
+EscapeSequence ::
+ CharacterEscapeSequence
+ LegacyOctalEscapeSequence
+ HexEscapeSequence
+ UnicodeEscapeSequence
+
+LegacyOctalEscapeSequence ::
+ OctalDigit [lookahead <! OctalDigit]
+ ZeroToThree OctalDigit [lookahead <! OctalDigit]
+ FourToSeven OctalDigit
+ ZeroToThree OctalDigit OctalDigit
+
+ZeroToThree :: one of
+ `0` `1` `2` `3`
+
+FourToSeven :: one of
+ `4` `5` `6` `7`
+
+
+Comment ::
+ MultiLineComment
+ SingleLineComment
+ SingleLineHTMLOpenComment
+ SingleLineHTMLCloseComment
+ SingleLineDelimitedComment
+
+MultiLineComment ::
+ `/*` FirstCommentLine? LineTerminator MultiLineCommentChars? `*/` HTMLCloseComment?
+
+FirstCommentLine ::
+ SingleLineDelimitedCommentChars
+
+SingleLineHTMLOpenComment ::
+ `<!--` SingleLineCommentChars?
+
+SingleLineHTMLCloseComment ::
+ LineTerminatorSequence HTMLCloseComment
+
+SingleLineDelimitedComment ::
+ `/*` SingleLineDelimitedCommentChars? `*/`
+
+HTMLCloseComment ::
+ WhiteSpaceSequence? SingleLineDelimitedCommentSequence? `-->` SingleLineCommentChars?
+
+SingleLineDelimitedCommentChars ::
+ SingleLineDelimitedCommentPiece
+ SingleLineDelimitedCommentChars SingleLineDelimitedCommentPiece
+
+SingleLineDelimitedCommentPiece ::
+ SingleLineNotAsteriskChar
+ Stars SingleLineNotForwardSlashOrAsteriskChar
+
+Stars ::
+ `*`
+ Stars `*`
+
+SingleLineNotAsteriskChar ::
+ SourceCharacter but not one of `*` or LineTerminator
+
+SingleLineNotForwardSlashOrAsteriskChar ::
+ SourceCharacter but not one of `/` or `*` or LineTerminator
+
+WhiteSpaceSequence ::
+ WhiteSpace WhiteSpaceSequence?
+
+SingleLineDelimitedCommentSequence ::
+ SingleLineDelimitedComment WhiteSpaceSequence? SingleLineDelimitedCommentSequence?
+
diff --git a/third_party/rust/jsparagus/js_parser/es-simplified.esgrammar b/third_party/rust/jsparagus/js_parser/es-simplified.esgrammar
new file mode 100644
index 0000000000..f7ebbb2017
--- /dev/null
+++ b/third_party/rust/jsparagus/js_parser/es-simplified.esgrammar
@@ -0,0 +1,1453 @@
+@returns Identifier
+IdentifierReference[Yield, Await] :
+ Identifier
+ => identifier_reference($0)
+
+@returns BindingIdentifier
+BindingIdentifier[Yield, Await] :
+ Identifier
+ => binding_identifier($0)
+ `yield`
+ => binding_identifier_yield($0)
+ `await`
+ => binding_identifier_await($0)
+
+@returns Label
+LabelIdentifier[Yield, Await] :
+ Identifier
+ => label_identifier($0)
+
+@returns Expression
+PrimaryExpression[Yield, Await] :
+ `this`
+ => this_expr($0)
+ IdentifierReference[?Yield, ?Await]
+ => identifier_expr($0)
+ Literal
+ => $0
+ ArrayLiteral[?Yield, ?Await]
+ => $0
+ ObjectLiteral[?Yield, ?Await]
+ => $0
+ FunctionExpression
+ => $0
+ ClassExpression[?Yield, ?Await]
+ => $0
+ GeneratorExpression
+ => $0
+ AsyncFunctionExpression
+ => $0
+ AsyncGeneratorExpression
+ => $0
+ RegularExpressionLiteral
+ => regexp_literal($0)
+ TemplateLiteral[?Yield, ?Await, ~Tagged]
+ => untagged_template_expr($0)
+ CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await]
+ => uncover_parenthesized_expression($0)
+
+@returns CoverParenthesized
+CoverParenthesizedExpressionAndArrowParameterList[Yield, Await] :
+ `(` Expression[+In, ?Yield, ?Await] `)`
+ => cover_parenthesized_expression($0, $1, $2)
+ `(` Expression[+In, ?Yield, ?Await] `,` `)`
+ => cover_arrow_parameter_list($0, expression_to_parameter_list($1), None, $3)
+ `(` `)`
+ => cover_arrow_parameter_list($0, empty_parameter_list(), None, $1)
+ `(` `...` BindingIdentifier[?Yield, ?Await] `)`
+ => cover_arrow_parameter_list($0, empty_parameter_list(), Some(binding_identifier_to_binding($2)), $3)
+ `(` `...` BindingPattern[?Yield, ?Await] `)`
+ => cover_arrow_parameter_list($0, empty_parameter_list(), Some($2), $3)
+ `(` Expression[+In, ?Yield, ?Await] `,` `...` BindingIdentifier[?Yield, ?Await] `)`
+ => cover_arrow_parameter_list($0, expression_to_parameter_list($1), Some(binding_identifier_to_binding($4)), $5)
+ `(` Expression[+In, ?Yield, ?Await] `,` `...` BindingPattern[?Yield, ?Await] `)`
+ => cover_arrow_parameter_list($0, expression_to_parameter_list($1), Some($4), $5)
+
+
+@returns Expression
+Literal :
+ NullLiteral
+ => null_literal($0)
+ BooleanLiteral
+ => boolean_literal($0)
+ NumericLiteral
+ => numeric_literal($0)
+ BigIntLiteral
+ => bigint_literal($0)
+ StringLiteral
+ => string_literal($0)
+
+
+@returns Expression
+ArrayLiteral[Yield, Await] :
+ `[` Elision? `]`
+ => array_literal_empty($0, $1, $2)
+ `[` ElementList[?Yield, ?Await] `]`
+ => array_literal($0, $1, $2)
+ `[` ElementList[?Yield, ?Await] `,` Elision? `]`
+ => array_literal_with_trailing_elision($0,$1, $3, $4)
+
+@returns ArrayExpression
+ElementList[Yield, Await] :
+ Elision? AssignmentExpression[+In, ?Yield, ?Await]
+ => element_list_first($0, $1)
+ Elision? SpreadElement[?Yield, ?Await]
+ => element_list_first_spread($0, $1)
+ ElementList[?Yield, ?Await] `,` Elision? AssignmentExpression[+In, ?Yield, ?Await]
+ => element_list_append($0, $2, $3)
+ ElementList[?Yield, ?Await] `,` Elision? SpreadElement[?Yield, ?Await]
+ => element_list_append_spread($0, $2, $3)
+
+@returns ArrayExpression
+Elision :
+ `,`
+ => elision_single($0)
+ Elision `,`
+ => elision_append($0, $1)
+
+@returns Expression
+SpreadElement[Yield, Await] :
+ `...` AssignmentExpression[+In, ?Yield, ?Await]
+ => spread_element($1)
+
+
+@returns Expression
+ObjectLiteral[Yield, Await] :
+ `{` `}`
+ => object_literal_empty($0, $1)
+ `{` PropertyDefinitionList[?Yield, ?Await] `}`
+ => object_literal($0, $1, $2)
+ `{` PropertyDefinitionList[?Yield, ?Await] `,` `}`
+ => object_literal($0, $1, $2)
+
+@returns ObjectExpression
+PropertyDefinitionList[Yield, Await] :
+ PropertyDefinition[?Yield, ?Await]
+ => property_definition_list_single($0)
+ PropertyDefinitionList[?Yield, ?Await] `,` PropertyDefinition[?Yield, ?Await]
+ => property_definition_list_append($0, $2)
+
+@returns ObjectProperty
+PropertyDefinition[Yield, Await] :
+ IdentifierReference[?Yield, ?Await]
+ => shorthand_property($0)
+ CoverInitializedName[?Yield, ?Await]
+ => $0
+ PropertyName[?Yield, ?Await] `:` AssignmentExpression[+In, ?Yield, ?Await]
+ => property_definition($0, $2)
+ MethodDefinition[?Yield, ?Await]
+ => property_definition_method($0)
+ `...` AssignmentExpression[+In, ?Yield, ?Await]
+ => property_definition_spread($1)
+
+@returns PropertyName
+PropertyName[Yield, Await] :
+ LiteralPropertyName
+ => $0
+ ComputedPropertyName[?Yield, ?Await]
+ => $0
+
+@returns PropertyName
+LiteralPropertyName :
+ IdentifierName
+ => property_name_identifier($0)
+ StringLiteral
+ => property_name_string($0)
+ NumericLiteral
+ => property_name_numeric($0)
+ BigIntLiteral
+ => property_name_bigint($0)
+
+@returns PropertyName
+ComputedPropertyName[Yield, Await] :
+ `[` AssignmentExpression[+In, ?Yield, ?Await] `]`
+ => computed_property_name($0, $1, $2)
+
+@returns ObjectProperty
+CoverInitializedName[Yield, Await] :
+ IdentifierReference[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]
+ => cover_initialized_name($0, $1)
+
+@returns Expression
+Initializer[In, Yield, Await] :
+ `=` AssignmentExpression[?In, ?Yield, ?Await]
+ => $1
+
+
+@returns TemplateExpression
+TemplateLiteral[Yield, Await, Tagged] :
+ NoSubstitutionTemplate
+ => template_literal($0)
+ SubstitutionTemplate[?Yield, ?Await, ?Tagged]
+ => $0
+
+@returns TemplateExpression
+SubstitutionTemplate[Yield, Await, Tagged] :
+ TemplateHead Expression[+In, ?Yield, ?Await] TemplateSpans[?Yield, ?Await, ?Tagged]
+ => substitution_template($0, $1, $2)
+
+@returns Void
+TemplateSpans[Yield, Await, Tagged] :
+ TemplateTail
+ => template_spans(None, $0)
+ TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateTail
+ => template_spans(Some($0), $1)
+
+@returns Void
+TemplateMiddleList[Yield, Await, Tagged] :
+ TemplateMiddle Expression[+In, ?Yield, ?Await]
+ => template_middle_list_single($0, $1)
+ TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateMiddle Expression[+In, ?Yield, ?Await]
+ => template_middle_list_append($0, $1, $2)
+
+@returns Expression
+MemberExpression[Yield, Await] :
+ PrimaryExpression[?Yield, ?Await]
+ => $0
+ MemberExpression[?Yield, ?Await] `[` Expression[+In, ?Yield, ?Await] `]`
+ => computed_member_expr($0, $2, $3)
+ MemberExpression[?Yield, ?Await] `.` IdentifierName
+ => static_member_expr($0, $2)
+ MemberExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged]
+ => tagged_template_expr($0, $1)
+ SuperProperty[?Yield, ?Await]
+ => $0
+ MetaProperty
+ => $0
+ `new` MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]
+ => new_expr_with_arguments($0, $1, $2)
+ MemberExpression[?Yield, ?Await] `.` PrivateIdentifier
+ => private_field_expr($0, $2)
+
+@returns Expression
+SuperProperty[Yield, Await] :
+ `super` `[` Expression[+In, ?Yield, ?Await] `]`
+ => super_property_computed($0, $2, $3)
+ `super` `.` IdentifierName
+ => super_property_static($0, $2)
+
+@returns Expression
+MetaProperty :
+ NewTarget
+ => $0
+
+@returns Expression
+NewTarget :
+ `new` `.` `target`
+ => new_target_expr($0, $2)
+
+@returns Expression
+NewExpression[Yield, Await] :
+ MemberExpression[?Yield, ?Await]
+ => $0
+ `new` NewExpression[?Yield, ?Await]
+ => new_expr_without_arguments($0, $1)
+
+@returns Expression
+CallExpression[Yield, Await] :
+ CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await]
+ => $0
+ SuperCall[?Yield, ?Await]
+ => $0
+ ImportCall[?Yield, ?Await]
+ => $0
+ CallExpression[?Yield, ?Await] Arguments[?Yield, ?Await]
+ => call_expr($0, $1)
+ CallExpression[?Yield, ?Await] `[` Expression[+In, ?Yield, ?Await] `]`
+ => computed_member_expr($0, $2, $3)
+ CallExpression[?Yield, ?Await] `.` IdentifierName
+ => static_member_expr($0, $2)
+ CallExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged]
+ => tagged_template_expr($0, $1)
+ CallExpression[?Yield, ?Await] `.` PrivateIdentifier
+ => private_field_expr($0, $2)
+
+@returns Expression
+SuperCall[Yield, Await] :
+ `super` Arguments[?Yield, ?Await]
+ => super_call($0, $1)
+
+@returns Expression
+ImportCall[Yield, Await] :
+ `import` `(` AssignmentExpression[+In, ?Yield, ?Await] `)`
+ => import_call($0, $2, $3)
+
+@returns Arguments
+Arguments[Yield, Await] :
+ `(` `)`
+ => arguments_empty($0, $1)
+ `(` ArgumentList[?Yield, ?Await] `)`
+ => arguments($0, $1, $2)
+ `(` ArgumentList[?Yield, ?Await] `,` `)`
+ => arguments($0, $1, $3)
+
+@returns Arguments
+ArgumentList[Yield, Await] :
+ AssignmentExpression[+In, ?Yield, ?Await]
+ => arguments_single($0)
+ `...` AssignmentExpression[+In, ?Yield, ?Await]
+ => arguments_spread_single($1)
+ ArgumentList[?Yield, ?Await] `,` AssignmentExpression[+In, ?Yield, ?Await]
+ => arguments_append($0, $2)
+ ArgumentList[?Yield, ?Await] `,` `...` AssignmentExpression[+In, ?Yield, ?Await]
+ => arguments_append_spread($0, $3)
+
+@returns Expression
+OptionalExpression[Yield, Await] :
+ MemberExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await]
+ => optional_expr($0, $1)
+ CallExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await]
+ => optional_expr($0, $1)
+ OptionalExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await]
+ => optional_expr($0, $1)
+
+@returns Expression
+OptionalChain[Yield, Await] :
+ `?.` `[` Expression[+In, ?Yield, ?Await] `]`
+ => optional_computed_member_expr_tail($0, $2, $3)
+ `?.` IdentifierName
+ => optional_static_member_expr_tail($0, $1)
+ `?.` PrivateIdentifier
+ => optional_private_field_member_expr_tail($0, $1)
+ `?.` Arguments[?Yield, ?Await]
+ => optional_call_expr_tail($0, $1)
+ `?.` TemplateLiteral[?Yield, ?Await, +Tagged]
+ => error_optional_chain_with_template()
+ OptionalChain[?Yield, ?Await] `[` Expression[+In, ?Yield, ?Await] `]`
+ => optional_computed_member_expr($0, $2, $3)
+ OptionalChain[?Yield, ?Await] `.` IdentifierName
+ => optional_static_member_expr($0, $2)
+ OptionalChain[?Yield, ?Await] `.` PrivateIdentifier
+ => optional_private_field_member_expr($0, $2)
+ OptionalChain[?Yield, ?Await] Arguments[?Yield, ?Await]
+ => optional_call_expr($0, $1)
+ OptionalChain[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged]
+ => error_optional_chain_with_template()
+
+@returns Expression
+LeftHandSideExpression[Yield, Await] :
+ NewExpression[?Yield, ?Await]
+ => $0
+ CallExpression[?Yield, ?Await]
+ => $0
+ OptionalExpression[?Yield, ?Await]
+ => $0
+
+
+@returns Expression
+CallMemberExpression[Yield, Await] :
+ MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]
+ => call_expr($0, $1)
+
+
+@returns Expression
+UpdateExpression[Yield, Await] :
+ LeftHandSideExpression[?Yield, ?Await]
+ => $0
+ LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] `++`
+ => post_increment_expr($0, $1)
+ LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] `--`
+ => post_decrement_expr($0, $1)
+ `++` UnaryExpression[?Yield, ?Await]
+ => pre_decrement_expr($0, $1)
+ `--` UnaryExpression[?Yield, ?Await]
+ => pre_decrement_expr($0, $1)
+
+
+@returns Expression
+UnaryExpression[Yield, Await] :
+ UpdateExpression[?Yield, ?Await]
+ => $0
+ `delete` UnaryExpression[?Yield, ?Await]
+ => delete_expr($0, $1)
+ `void` UnaryExpression[?Yield, ?Await]
+ => void_expr($0, $1)
+ `typeof` UnaryExpression[?Yield, ?Await]
+ => typeof_expr($0, $1)
+ `+` UnaryExpression[?Yield, ?Await]
+ => unary_plus_expr($0, $1)
+ `-` UnaryExpression[?Yield, ?Await]
+ => unary_minus_expr($0, $1)
+ `~` UnaryExpression[?Yield, ?Await]
+ => bitwise_not_expr($0, $1)
+ `!` UnaryExpression[?Yield, ?Await]
+ => logical_not_expr($0, $1)
+ [+Await] AwaitExpression[?Yield]
+ => $0
+
+
+@returns Expression
+ExponentiationExpression[Yield, Await] :
+ UnaryExpression[?Yield, ?Await]
+ => $0
+ UpdateExpression[?Yield, ?Await] `**` ExponentiationExpression[?Yield, ?Await]
+ => binary_expr(pow_op($1), $0, $2)
+
+
+@returns Expression
+MultiplicativeExpression[Yield, Await] :
+ ExponentiationExpression[?Yield, ?Await]
+ => $0
+ MultiplicativeExpression[?Yield, ?Await] MultiplicativeOperator ExponentiationExpression[?Yield, ?Await]
+ => multiplicative_expr($0, $1, $2)
+
+@returns BinaryOperator
+MultiplicativeOperator :
+ `*`
+ => box_op(mul_op($0))
+ `/`
+ => box_op(div_op($0))
+ `%`
+ => box_op(mod_op($0))
+
+
+@returns Expression
+AdditiveExpression[Yield, Await] :
+ MultiplicativeExpression[?Yield, ?Await]
+ => $0
+ AdditiveExpression[?Yield, ?Await] `+` MultiplicativeExpression[?Yield, ?Await]
+ => binary_expr(add_op($1), $0, $2)
+ AdditiveExpression[?Yield, ?Await] `-` MultiplicativeExpression[?Yield, ?Await]
+ => binary_expr(sub_op($1), $0, $2)
+
+
+@returns Expression
+ShiftExpression[Yield, Await] :
+ AdditiveExpression[?Yield, ?Await]
+ => $0
+ ShiftExpression[?Yield, ?Await] `<<` AdditiveExpression[?Yield, ?Await]
+ => binary_expr(left_shift_op($1), $0, $2)
+ ShiftExpression[?Yield, ?Await] `>>` AdditiveExpression[?Yield, ?Await]
+ => binary_expr(right_shift_op($1), $0, $2)
+ ShiftExpression[?Yield, ?Await] `>>>` AdditiveExpression[?Yield, ?Await]
+ => binary_expr(right_shift_ext_op($1), $0, $2)
+
+
+@returns Expression
+RelationalExpression[In, Yield, Await] :
+ ShiftExpression[?Yield, ?Await]
+ => $0
+ RelationalExpression[?In, ?Yield, ?Await] `<` ShiftExpression[?Yield, ?Await]
+ => binary_expr(less_than_op($1), $0, $2)
+ RelationalExpression[?In, ?Yield, ?Await] `>` ShiftExpression[?Yield, ?Await]
+ => binary_expr(greater_than_op($1), $0, $2)
+ RelationalExpression[?In, ?Yield, ?Await] `<=` ShiftExpression[?Yield, ?Await]
+ => binary_expr(less_than_or_equal_op($1), $0, $2)
+ RelationalExpression[?In, ?Yield, ?Await] `>=` ShiftExpression[?Yield, ?Await]
+ => binary_expr(greater_than_or_equal_op($1), $0, $2)
+ RelationalExpression[?In, ?Yield, ?Await] `instanceof` ShiftExpression[?Yield, ?Await]
+ => binary_expr(instanceof_op($1), $0, $2)
+ [+In] RelationalExpression[+In, ?Yield, ?Await] `in` ShiftExpression[?Yield, ?Await]
+ => binary_expr(in_op($1), $0, $2)
+
+
+@returns Expression
+EqualityExpression[In, Yield, Await] :
+ RelationalExpression[?In, ?Yield, ?Await]
+ => $0
+ EqualityExpression[?In, ?Yield, ?Await] `==` RelationalExpression[?In, ?Yield, ?Await]
+ => binary_expr(equals_op($1), $0, $2)
+ EqualityExpression[?In, ?Yield, ?Await] `!=` RelationalExpression[?In, ?Yield, ?Await]
+ => binary_expr(not_equals_op($1), $0, $2)
+ EqualityExpression[?In, ?Yield, ?Await] `===` RelationalExpression[?In, ?Yield, ?Await]
+ => binary_expr(strict_equals_op($1), $0, $2)
+ EqualityExpression[?In, ?Yield, ?Await] `!==` RelationalExpression[?In, ?Yield, ?Await]
+ => binary_expr(strict_not_equals_op($1), $0, $2)
+
+
+@returns Expression
+BitwiseANDExpression[In, Yield, Await] :
+ EqualityExpression[?In, ?Yield, ?Await]
+ => $0
+ BitwiseANDExpression[?In, ?Yield, ?Await] `&` EqualityExpression[?In, ?Yield, ?Await]
+ => binary_expr(bitwise_and_op($1), $0, $2)
+
+@returns Expression
+BitwiseXORExpression[In, Yield, Await] :
+ BitwiseANDExpression[?In, ?Yield, ?Await]
+ => $0
+ BitwiseXORExpression[?In, ?Yield, ?Await] `^` BitwiseANDExpression[?In, ?Yield, ?Await]
+ => binary_expr(bitwise_xor_op($1), $0, $2)
+
+@returns Expression
+BitwiseORExpression[In, Yield, Await] :
+ BitwiseXORExpression[?In, ?Yield, ?Await]
+ => $0
+ BitwiseORExpression[?In, ?Yield, ?Await] `|` BitwiseXORExpression[?In, ?Yield, ?Await]
+ => binary_expr(bitwise_or_op($1), $0, $2)
+
+@returns Expression
+LogicalANDExpression[In, Yield, Await] :
+ BitwiseORExpression[?In, ?Yield, ?Await]
+ => $0
+ LogicalANDExpression[?In, ?Yield, ?Await] `&&` BitwiseORExpression[?In, ?Yield, ?Await]
+ => binary_expr(logical_and_op($1), $0, $2)
+
+@returns Expression
+LogicalORExpression[In, Yield, Await] :
+ LogicalANDExpression[?In, ?Yield, ?Await]
+ => $0
+ LogicalORExpression[?In, ?Yield, ?Await] `||` LogicalANDExpression[?In, ?Yield, ?Await]
+ => binary_expr(logical_or_op($1), $0, $2)
+
+@returns Expression
+ShortCircuitExpression[In, Yield, Await] :
+ LogicalORExpression[?In, ?Yield, ?Await]
+ => $0
+ CoalesceExpression[?In, ?Yield, ?Await]
+ => $0
+
+@returns Expression
+CoalesceExpression[In, Yield, Await] :
+ CoalesceExpressionHead[?In, ?Yield, ?Await] `??` BitwiseORExpression[?In, ?Yield, ?Await]
+ => binary_expr(coalesce_op($1), $0, $2)
+
+@returns Expression
+CoalesceExpressionHead[In, Yield, Await] :
+ CoalesceExpression[?In, ?Yield, ?Await]
+ => $0
+ BitwiseORExpression[?In, ?Yield, ?Await]
+ => $0
+
+@returns Expression
+ConditionalExpression[In, Yield, Await] :
+ ShortCircuitExpression[?In, ?Yield, ?Await]
+ => $0
+ ShortCircuitExpression[?In, ?Yield, ?Await] `?` AssignmentExpression[+In, ?Yield, ?Await] `:` AssignmentExpression[?In, ?Yield, ?Await]
+ => conditional_expr($0, $2, $4)
+
+
+@returns Expression
+AssignmentExpression[In, Yield, Await] :
+ ConditionalExpression[?In, ?Yield, ?Await]
+ => $0
+ [+Yield] YieldExpression[?In, ?Await]
+ => $0
+ ArrowFunction[?In, ?Yield, ?Await]
+ => $0
+ AsyncArrowFunction[?In, ?Yield, ?Await]
+ => $0
+ LeftHandSideExpression[?Yield, ?Await] `=` AssignmentExpression[?In, ?Yield, ?Await]
+ => assignment_expr($0, $2)
+ LeftHandSideExpression[?Yield, ?Await] AssignmentOperator AssignmentExpression[?In, ?Yield, ?Await]
+ => compound_assignment_expr($0, $1, $2)
+ LeftHandSideExpression[?Yield, ?Await] LogicalAssignmentOperator AssignmentExpression[?In, ?Yield, ?Await]
+ => compound_assignment_expr($0, $1, $2)
+
+@returns CompoundAssignmentOperator
+AssignmentOperator :
+ `*=`
+ => box_assign_op(mul_assign_op($0))
+ `/=`
+ => box_assign_op(div_assign_op($0))
+ `%=`
+ => box_assign_op(mod_assign_op($0))
+ `+=`
+ => box_assign_op(add_assign_op($0))
+ `-=`
+ => box_assign_op(sub_assign_op($0))
+ `<<=`
+ => box_assign_op(left_shift_assign_op($0))
+ `>>=`
+ => box_assign_op(right_shift_assign_op($0))
+ `>>>=`
+ => box_assign_op(right_shift_ext_assign_op($0))
+ `&=`
+ => box_assign_op(bitwise_and_assign_op($0))
+ `^=`
+ => box_assign_op(bitwise_xor_assign_op($0))
+ `|=`
+ => box_assign_op(bitwise_or_assign_op($0))
+ `**=`
+ => box_assign_op(pow_assign_op($0))
+
+@returns CompoundAssignmentOperator
+LogicalAssignmentOperator :
+ `&&=`
+ => box_assign_op(logical_and_assign_op($0))
+ `||=`
+ => box_assign_op(logical_or_assign_op($0))
+ `??=`
+ => box_assign_op(coalesce_assign_op($0))
+
+AssignmentPattern[Yield, Await] :
+ ObjectAssignmentPattern[?Yield, ?Await]
+ ArrayAssignmentPattern[?Yield, ?Await]
+
+ObjectAssignmentPattern[Yield, Await] :
+ `{` `}`
+ `{` AssignmentRestProperty[?Yield, ?Await] `}`
+ `{` AssignmentPropertyList[?Yield, ?Await] `}`
+ `{` AssignmentPropertyList[?Yield, ?Await] `,` AssignmentRestProperty[?Yield, ?Await]? `}`
+
+ArrayAssignmentPattern[Yield, Await] :
+ `[` Elision? AssignmentRestElement[?Yield, ?Await]? `]`
+ `[` AssignmentElementList[?Yield, ?Await] `]`
+ `[` AssignmentElementList[?Yield, ?Await] `,` Elision? AssignmentRestElement[?Yield, ?Await]? `]`
+
+AssignmentRestProperty[Yield, Await] :
+ `...` DestructuringAssignmentTarget[?Yield, ?Await]
+
+AssignmentPropertyList[Yield, Await] :
+ AssignmentProperty[?Yield, ?Await]
+ AssignmentPropertyList[?Yield, ?Await] `,` AssignmentProperty[?Yield, ?Await]
+
+AssignmentElementList[Yield, Await] :
+ AssignmentElisionElement[?Yield, ?Await]
+ AssignmentElementList[?Yield, ?Await] `,` AssignmentElisionElement[?Yield, ?Await]
+
+AssignmentElisionElement[Yield, Await] :
+ Elision? AssignmentElement[?Yield, ?Await]
+
+AssignmentProperty[Yield, Await] :
+ IdentifierReference[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]?
+ PropertyName[?Yield, ?Await] `:` AssignmentElement[?Yield, ?Await]
+
+AssignmentElement[Yield, Await] :
+ DestructuringAssignmentTarget[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]?
+
+AssignmentRestElement[Yield, Await] :
+ `...` DestructuringAssignmentTarget[?Yield, ?Await]
+
+DestructuringAssignmentTarget[Yield, Await] :
+ LeftHandSideExpression[?Yield, ?Await]
+
+
+@returns Expression
+Expression[In, Yield, Await] :
+ AssignmentExpression[?In, ?Yield, ?Await]
+ => $0
+ Expression[?In, ?Yield, ?Await] `,` AssignmentExpression[?In, ?Yield, ?Await]
+ => binary_expr(comma_op($1), $0, $2)
+
+
+@returns Statement
+Statement[Yield, Await, Return] :
+ BlockStatement[?Yield, ?Await, ?Return]
+ => $0
+ VariableStatement[?Yield, ?Await]
+ => $0
+ EmptyStatement
+ => $0
+ ExpressionStatement[?Yield, ?Await]
+ => $0
+ IfStatement[?Yield, ?Await, ?Return]
+ => $0
+ BreakableStatement[?Yield, ?Await, ?Return]
+ => $0
+ ContinueStatement[?Yield, ?Await]
+ => $0
+ BreakStatement[?Yield, ?Await]
+ => $0
+ [+Return] ReturnStatement[?Yield, ?Await]
+ => $0
+ WithStatement[?Yield, ?Await, ?Return]
+ => $0
+ LabelledStatement[?Yield, ?Await, ?Return]
+ => $0
+ ThrowStatement[?Yield, ?Await]
+ => $0
+ TryStatement[?Yield, ?Await, ?Return]
+ => $0
+ DebuggerStatement
+ => $0
+
+@returns Statement
+Declaration[Yield, Await] :
+ HoistableDeclaration[?Yield, ?Await, ~Default]
+ => $0
+ ClassDeclaration[?Yield, ?Await, ~Default]
+ => $0
+ LexicalDeclaration[+In, ?Yield, ?Await]
+ => $0
+
+@returns Statement
+HoistableDeclaration[Yield, Await, Default] :
+ FunctionDeclaration[?Yield, ?Await, ?Default]
+ => $0
+ GeneratorDeclaration[?Yield, ?Await, ?Default]
+ => $0
+ AsyncFunctionDeclaration[?Yield, ?Await, ?Default]
+ => $0
+ AsyncGeneratorDeclaration[?Yield, ?Await, ?Default]
+ => $0
+
+@returns Statement
+BreakableStatement[Yield, Await, Return] :
+ IterationStatement[?Yield, ?Await, ?Return]
+ => $0
+ SwitchStatement[?Yield, ?Await, ?Return]
+ => $0
+
+
+@returns Statement
+BlockStatement[Yield, Await, Return] :
+ Block[?Yield, ?Await, ?Return]
+ => block_statement($0)
+
+@returns Block
+Block[Yield, Await, Return] :
+ `{` StatementList[?Yield, ?Await, ?Return]? `}`
+ => block($0, $1, $2)
+
+@returns Vec<Statement>
+StatementList[Yield, Await, Return] :
+ StatementListItem[?Yield, ?Await, ?Return]
+ => statement_list_single($0)
+ StatementList[?Yield, ?Await, ?Return] StatementListItem[?Yield, ?Await, ?Return]
+ => statement_list_append($0, $1)
+
+@returns Statement
+StatementListItem[Yield, Await, Return] :
+ Statement[?Yield, ?Await, ?Return]
+ => $0
+ Declaration[?Yield, ?Await]
+ => $0
+
+
+@returns Statement
+LexicalDeclaration[In, Yield, Await] :
+ LetOrConst BindingList[?In, ?Yield, ?Await] `;`
+ => lexical_declaration($0, $1)
+
+@returns VariableDeclarationOrExpression
+ForLexicalDeclaration[In, Yield, Await] :
+ LetOrConst BindingList[?In, ?Yield, ?Await] `;`
+ => for_lexical_declaration($0, $1)
+
+@returns VariableDeclarationKind
+LetOrConst :
+ `let`
+ => let_kind($0)
+ `const`
+ => const_kind($0)
+
+@returns Vec<VariableDeclarator>
+BindingList[In, Yield, Await] :
+ LexicalBinding[?In, ?Yield, ?Await]
+ => variable_declaration_list_single($0)
+ BindingList[?In, ?Yield, ?Await] `,` LexicalBinding[?In, ?Yield, ?Await]
+ => variable_declaration_list_append($0, $2)
+
+@returns VariableDeclarator
+LexicalBinding[In, Yield, Await] :
+ BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]?
+ => variable_declaration(binding_identifier_to_binding($0), $1)
+ BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]
+ => variable_declaration($0, Some($1))
+
+
+@returns Statement
+VariableStatement[Yield, Await] :
+ `var` VariableDeclarationList[+In, ?Yield, ?Await] `;`
+ => variable_statement($0, $1)
+
+@returns Vec<VariableDeclarator>
+VariableDeclarationList[In, Yield, Await] :
+ VariableDeclaration[?In, ?Yield, ?Await]
+ => variable_declaration_list_single($0)
+ VariableDeclarationList[?In, ?Yield, ?Await] `,` VariableDeclaration[?In, ?Yield, ?Await]
+ => variable_declaration_list_append($0, $2)
+
+@returns VariableDeclarator
+VariableDeclaration[In, Yield, Await] :
+ BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]?
+ => variable_declaration(binding_identifier_to_binding($0), $1)
+ BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]
+ => variable_declaration($0, Some($1))
+
+
+@returns Binding
+BindingPattern[Yield, Await] :
+ ObjectBindingPattern[?Yield, ?Await]
+ => $0
+ ArrayBindingPattern[?Yield, ?Await]
+ => $0
+
+@returns Binding
+ObjectBindingPattern[Yield, Await] :
+ `{` `}`
+ => object_binding_pattern($0, binding_property_list_empty(), None, $1)
+ `{` BindingRestProperty[?Yield, ?Await] `}`
+ => object_binding_pattern($0, binding_property_list_empty(), Some($1), $2)
+ `{` BindingPropertyList[?Yield, ?Await] `}`
+ => object_binding_pattern($0, $1, None, $2)
+ `{` BindingPropertyList[?Yield, ?Await] `,` BindingRestProperty[?Yield, ?Await]? `}`
+ => object_binding_pattern($0, $1, $3, $4)
+
+@returns Binding
+ArrayBindingPattern[Yield, Await] :
+ `[` Elision? BindingRestElement[?Yield, ?Await]? `]`
+ => array_binding_pattern($0, binding_element_list_empty(), $1, $2, $3)
+ `[` BindingElementList[?Yield, ?Await] `]`
+ => array_binding_pattern($0, $1, None, None, $2)
+ `[` BindingElementList[?Yield, ?Await] `,` Elision? BindingRestElement[?Yield, ?Await]? `]`
+ => array_binding_pattern($0, $1, $3, $4, $5)
+
+@returns BindingIdentifier
+BindingRestProperty[Yield, Await] :
+ `...` BindingIdentifier[?Yield, ?Await]
+ => $1
+
+@returns Vec<BindingProperty>
+BindingPropertyList[Yield, Await] :
+ BindingProperty[?Yield, ?Await]
+ => binding_property_list_single($0)
+ BindingPropertyList[?Yield, ?Await] `,` BindingProperty[?Yield, ?Await]
+ => binding_property_list_append($0, $2)
+
+@returns Vec<Option<Parameter>>
+BindingElementList[Yield, Await] :
+ BindingElisionElement[?Yield, ?Await]
+ => $0
+ BindingElementList[?Yield, ?Await] `,` BindingElisionElement[?Yield, ?Await]
+ => binding_element_list_append($0, $2)
+
+@returns Vec<Option<Parameter>>
+BindingElisionElement[Yield, Await] :
+ Elision? BindingElement[?Yield, ?Await]
+ => binding_elision_element($0, $1)
+
+@returns BindingProperty
+BindingProperty[Yield, Await] :
+ SingleNameBinding[?Yield, ?Await]
+ => binding_property_shorthand($0)
+ PropertyName[?Yield, ?Await] `:` BindingElement[?Yield, ?Await]
+ => binding_property($0, $2)
+
+@returns Parameter
+BindingElement[Yield, Await] :
+ SingleNameBinding[?Yield, ?Await]
+ => $0
+ BindingPattern[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]?
+ => binding_element_pattern($0, $1)
+
+@returns Parameter
+SingleNameBinding[Yield, Await] :
+ BindingIdentifier[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]?
+ => single_name_binding($0, $1)
+
+@returns Binding
+BindingRestElement[Yield, Await] :
+ `...` BindingIdentifier[?Yield, ?Await]
+ => binding_identifier_to_binding($1)
+ `...` BindingPattern[?Yield, ?Await]
+ => $1
+
+
+@returns Statement
+EmptyStatement :
+ `;`
+ => empty_statement($0)
+
+@returns Statement
+ExpressionStatement[Yield, Await] :
+ [lookahead <! {`{`, `function`, `async`, `class`, `let`}] Expression[+In, ?Yield, ?Await] `;`
+ => expression_statement($0)
+
+
+@returns Statement
+IfStatement[Yield, Await, Return] :
+ `if` `(` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return] `else` Statement[?Yield, ?Await, ?Return]
+ => if_statement($0, $2, $4, Some($6))
+ `if` `(` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return] [lookahead != `else`]
+ => if_statement($0, $2, $4, None)
+ `if` `(` Expression[+In, ?Yield, ?Await] `)` FunctionDeclaration[?Yield, ?Await, ~Default] `else` Statement[?Yield, ?Await, ?Return]
+ => if_statement($0, $2, make_block_stmt_from_function_decl($4), Some($6))
+ `if` `(` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return] `else` FunctionDeclaration[?Yield, ?Await, ~Default]
+ => if_statement($0, $2, $4, Some(make_block_stmt_from_function_decl($6)))
+ `if` `(` Expression[+In, ?Yield, ?Await] `)` FunctionDeclaration[?Yield, ?Await, ~Default] `else` FunctionDeclaration[?Yield, ?Await, ~Default]
+ => if_statement($0, $2, make_block_stmt_from_function_decl($4), Some(make_block_stmt_from_function_decl($6)))
+ `if` `(` Expression[+In, ?Yield, ?Await] `)` FunctionDeclaration[?Yield, ?Await, ~Default] [lookahead != `else`]
+ => if_statement($0, $2, make_block_stmt_from_function_decl($4), None)
+
+
+@returns Statement
+IterationStatement[Yield, Await, Return] :
+ `do` Statement[?Yield, ?Await, ?Return] `while` `(` Expression[+In, ?Yield, ?Await] `)` `;`
+ => do_while_statement($0, $1, $4, $5)
+ `while` `(` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ => while_statement($0, $2, $4)
+ `for` `(` [lookahead != `let`] Expression[~In, ?Yield, ?Await]? `;` Expression[+In, ?Yield, ?Await]? `;` Expression[+In, ?Yield, ?Await]? `)` Statement[?Yield, ?Await, ?Return]
+ => for_statement($0, for_expression($2), $4, $6, $8)
+ `for` `(` `var` VariableDeclarationList[~In, ?Yield, ?Await] `;` Expression[+In, ?Yield, ?Await]? `;` Expression[+In, ?Yield, ?Await]? `)` Statement[?Yield, ?Await, ?Return]
+ => for_statement($0, Some(for_var_declaration($2, $3)), $5, $7, $9)
+ `for` `(` ForLexicalDeclaration[~In, ?Yield, ?Await] Expression[+In, ?Yield, ?Await]? `;` Expression[+In, ?Yield, ?Await]? `)` Statement[?Yield, ?Await, ?Return]
+ => for_statement_lexical($0, unbox_for_lexical_declaration($2), $3, $5, $7)
+ `for` `(` [lookahead != `let`] LeftHandSideExpression[?Yield, ?Await] `in` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ => for_in_statement($0, for_assignment_target($2), $4, $6)
+ `for` `(` `var` ForBinding[?Yield, ?Await] `in` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ => for_in_statement($0, for_in_or_of_var_declaration($2, $3, None), $5, $7)
+ `for` `(` `var` BindingIdentifier[?Yield, ?Await] Initializer[~In, ?Yield, ?Await] `in` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ => for_in_statement($0, for_in_or_of_var_declaration($2, binding_identifier_to_binding($3), Some($4)), $6, $8)
+ `for` `(` ForDeclaration[?Yield, ?Await] `in` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ => for_in_statement_lexical($0, unbox_for_declaration($2), $4, $6)
+ `for` `(` [lookahead <! {`async`, `let`} ] LeftHandSideExpression[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ => for_of_statement($0, for_assignment_target($2), $4, $6)
+ `for` `(` `var` ForBinding[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ => for_of_statement($0, for_in_or_of_var_declaration($2, $3, None), $5, $7)
+ `for` `(` ForDeclaration[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ => for_of_statement_lexical($0, unbox_for_declaration($2), $4, $6)
+ [+Await] `for` `await` `(` [lookahead <! {`async`, `let`} ] LeftHandSideExpression[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ => for_await_of_statement($0, for_assignment_target($3), $5, $7)
+ [+Await] `for` `await` `(` `var` ForBinding[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ => for_await_of_statement($0, for_in_or_of_var_declaration($3, $4, None), $6, $8)
+ [+Await] `for` `await` `(` ForDeclaration[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ => for_await_of_statement_lexical($0, unbox_for_declaration($3), $5, $7)
+
+@returns VariableDeclarationOrAssignmentTarget
+ForDeclaration[Yield, Await] :
+ LetOrConst ForBinding[?Yield, ?Await]
+ => for_declaration($0, $1)
+
+@returns Binding
+ForBinding[Yield, Await] :
+ BindingIdentifier[?Yield, ?Await]
+ => binding_identifier_to_binding($0)
+ BindingPattern[?Yield, ?Await]
+ => $0
+
+
+@returns Statement
+ContinueStatement[Yield, Await] :
+ `continue` `;`
+ => continue_statement($0, None)
+ `continue` [no LineTerminator here] LabelIdentifier[?Yield, ?Await] `;`
+ => continue_statement($0, Some($1))
+
+
+@returns Statement
+BreakStatement[Yield, Await] :
+ `break` `;`
+ => break_statement($0, None)
+ `break` [no LineTerminator here] LabelIdentifier[?Yield, ?Await] `;`
+ => break_statement($0, Some($1))
+
+
+@returns Statement
+ReturnStatement[Yield, Await] :
+ `return` `;`
+ => return_statement($0, None)
+ `return` [no LineTerminator here] Expression[+In, ?Yield, ?Await] `;`
+ => return_statement($0, Some($1))
+
+
+@returns Statement
+WithStatement[Yield, Await, Return] :
+ `with` `(` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ => with_statement($0, $2, $4)
+
+
+@returns Statement
+SwitchStatement[Yield, Await, Return] :
+ `switch` `(` Expression[+In, ?Yield, ?Await] `)` CaseBlock[?Yield, ?Await, ?Return]
+ => switch_statement($0, $2, $4)
+
+@returns Statement
+CaseBlock[Yield, Await, Return] :
+ `{` CaseClauses[?Yield, ?Await, ?Return]? `}`
+ => case_block($0, $1, $2)
+ `{` CaseClauses[?Yield, ?Await, ?Return]? DefaultClause[?Yield, ?Await, ?Return] CaseClauses[?Yield, ?Await, ?Return]? `}`
+ => case_block_with_default($0, $1, $2, $3, $4)
+
+@returns Vec<SwitchCase>
+CaseClauses[Yield, Await, Return] :
+ CaseClause[?Yield, ?Await, ?Return]
+ => case_clauses_single($0)
+ CaseClauses[?Yield, ?Await, ?Return] CaseClause[?Yield, ?Await, ?Return]
+ => case_clauses_append($0, $1)
+
+@returns SwitchCase
+CaseClause[Yield, Await, Return] :
+ `case` Expression[+In, ?Yield, ?Await] `:` StatementList[?Yield, ?Await, ?Return]?
+ => case_clause($0, $1, $2, $3)
+
+@returns SwitchDefault
+DefaultClause[Yield, Await, Return] :
+ `default` `:` StatementList[?Yield, ?Await, ?Return]?
+ => default_clause($0, $1, $2)
+
+
+@returns Statement
+LabelledStatement[Yield, Await, Return] :
+ LabelIdentifier[?Yield, ?Await] `:` LabelledItem[?Yield, ?Await, ?Return]
+ => labelled_statement($0, $2)
+
+@returns Statement
+LabelledItem[Yield, Await, Return] :
+ Statement[?Yield, ?Await, ?Return]
+ => $0
+ FunctionDeclaration[?Yield, ?Await, ~Default]
+ => $0
+
+
+@returns Statement
+ThrowStatement[Yield, Await] :
+ `throw` [no LineTerminator here] Expression[+In, ?Yield, ?Await] `;`
+ => throw_statement($0, $1)
+
+@returns Statement
+TryStatement[Yield, Await, Return] :
+ `try` Block[?Yield, ?Await, ?Return] Catch[?Yield, ?Await, ?Return]
+ => try_statement($0, $1, Some($2), None)
+ `try` Block[?Yield, ?Await, ?Return] Finally[?Yield, ?Await, ?Return]
+ => try_statement($0, $1, None, Some($2))
+ `try` Block[?Yield, ?Await, ?Return] Catch[?Yield, ?Await, ?Return] Finally[?Yield, ?Await, ?Return]
+ => try_statement($0, $1, Some($2), Some($3))
+
+@returns CatchClause
+Catch[Yield, Await, Return] :
+ `catch` `(` CatchParameter[?Yield, ?Await] `)` CatchBlock[?Yield, ?Await, ?Return]
+ => catch($0, $2, $4)
+ `catch` Block[?Yield, ?Await, ?Return]
+ => catch_no_param($0, $1)
+
+@returns Block
+CatchBlock[Yield, Await, Return] :
+ `{` StatementList[?Yield, ?Await, ?Return]? `}`
+ => catch_block($0, $1, $2)
+
+@returns Block
+Finally[Yield, Await, Return] :
+ `finally` Block[?Yield, ?Await, ?Return]
+ => $1
+
+@returns Binding
+CatchParameter[Yield, Await] :
+ BindingIdentifier[?Yield, ?Await]
+ => binding_identifier_to_binding($0)
+ BindingPattern[?Yield, ?Await]
+ => $0
+
+
+@returns Statement
+DebuggerStatement :
+ `debugger` `;`
+ => debugger_statement($0)
+
+
+@returns Statement
+FunctionDeclaration[Yield, Await, Default] :
+ `function` BindingIdentifier[?Yield, ?Await] `(` FormalParameters[~Yield, ~Await] `)` `{` FunctionBody[~Yield, ~Await] `}`
+ => function_decl(function($0, Some($1), $2, $3, $4, $5, $6, $7))
+ [+Default] `function` `(` FormalParameters[~Yield, ~Await] `)` `{` FunctionBody[~Yield, ~Await] `}`
+ => function_decl(function($0, None, $1, $2, $3, $4, $5, $6))
+
+@returns Expression
+FunctionExpression :
+ `function` BindingIdentifier[~Yield, ~Await]? `(` FormalParameters[~Yield, ~Await] `)` `{` FunctionBody[~Yield, ~Await] `}`
+ => function_expr(function($0, $1, $2, $3, $4, $5, $6, $7))
+
+@returns FormalParameters
+UniqueFormalParameters[Yield, Await] :
+ FormalParameters[?Yield, ?Await]
+ => unique_formal_parameters($0)
+
+@returns FormalParameters
+FormalParameters[Yield, Await] :
+ [empty]
+ => empty_formal_parameters()
+ FunctionRestParameter[?Yield, ?Await]
+ => with_rest_parameter(empty_formal_parameters(), $0)
+ FormalParameterList[?Yield, ?Await]
+ => $0
+ FormalParameterList[?Yield, ?Await] `,`
+ => $0
+ FormalParameterList[?Yield, ?Await] `,` FunctionRestParameter[?Yield, ?Await]
+ => with_rest_parameter($0, $2)
+
+@returns FormalParameters
+FormalParameterList[Yield, Await] :
+ FormalParameter[?Yield, ?Await]
+ => formal_parameter_list_single($0)
+ FormalParameterList[?Yield, ?Await] `,` FormalParameter[?Yield, ?Await]
+ => formal_parameter_list_append($0, $2)
+
+@returns Binding
+FunctionRestParameter[Yield, Await] :
+ BindingRestElement[?Yield, ?Await]
+ => $0
+
+@returns Parameter
+FormalParameter[Yield, Await] :
+ BindingElement[?Yield, ?Await]
+ => $0
+
+@returns FunctionBody
+FunctionBody[Yield, Await] :
+ FunctionStatementList[?Yield, ?Await]
+ => function_body($0)
+
+@returns Vec<Statement>
+FunctionStatementList[Yield, Await] :
+ StatementList[?Yield, ?Await, +Return]?
+ => function_statement_list($0)
+
+
+@returns Expression
+ArrowFunction[In, Yield, Await] :
+ ArrowParameters[?Yield, ?Await] [no LineTerminator here] `=>` ConciseBody[?In]
+ => arrow_function($0, $2)
+
+@returns FormalParameters
+ArrowParameters[Yield, Await] :
+ BindingIdentifier[?Yield, ?Await]
+ => arrow_parameters_bare($0)
+ CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await]
+ => uncover_arrow_parameters($0)
+
+@returns ArrowExpressionBody
+ConciseBody[In] :
+ [lookahead != `{` ] AssignmentExpression[?In, ~Yield, ~Await]
+ => concise_body_expression($0)
+ `{` FunctionBody[~Yield, ~Await] `}`
+ => concise_body_block($0, $1, $2)
+
+
+ArrowFormalParameters[Yield, Await] :
+ `(` UniqueFormalParameters[?Yield, ?Await] `)`
+
+
+@returns MethodDefinition
+MethodDefinition[Yield, Await] :
+ ClassElementName[?Yield, ?Await] `(` UniqueFormalParameters[~Yield, ~Await] `)` `{` FunctionBody[~Yield, ~Await] `}`
+ => method_definition($0, $1, $2, $3, $4, $5, $6)
+ GeneratorMethod[?Yield, ?Await]
+ => $0
+ AsyncMethod[?Yield, ?Await]
+ => $0
+ AsyncGeneratorMethod[?Yield, ?Await]
+ => $0
+ `get` ClassElementName[?Yield, ?Await] `(` `)` `{` FunctionBody[~Yield, ~Await] `}`
+ => getter($0, $1, $4, $5, $6)
+ `set` ClassElementName[?Yield, ?Await] `(` PropertySetParameterList `)` `{` FunctionBody[~Yield, ~Await] `}`
+ => setter($0, $1, $2, $3, $4, $5, $6, $7)
+
+@returns Parameter
+PropertySetParameterList :
+ FormalParameter[~Yield, ~Await]
+ => $0
+
+
+@returns MethodDefinition
+GeneratorMethod[Yield, Await] :
+ `*` ClassElementName[?Yield, ?Await] `(` UniqueFormalParameters[+Yield, ~Await] `)` `{` GeneratorBody `}`
+ => generator_method($0, $1, $2, $3, $4, $5, $6, $7)
+
+@returns Statement
+GeneratorDeclaration[Yield, Await, Default] :
+ `function` `*` BindingIdentifier[?Yield, ?Await] `(` FormalParameters[+Yield, ~Await] `)` `{` GeneratorBody `}`
+ => function_decl(generator($0, Some($2), $3, $4, $5, $6, $7, $8))
+ [+Default] `function` `*` `(` FormalParameters[+Yield, ~Await] `)` `{` GeneratorBody `}`
+ => function_decl(generator($0, None, $2, $3, $4, $5, $6, $7))
+
+@returns Expression
+GeneratorExpression :
+ `function` `*` BindingIdentifier[+Yield, ~Await]? `(` FormalParameters[+Yield, ~Await] `)` `{` GeneratorBody `}`
+ => function_expr(generator($0, $2, $3, $4, $5, $6, $7, $8))
+
+@returns FunctionBody
+GeneratorBody :
+ FunctionBody[+Yield, ~Await]
+ => $0
+
+@returns Expression
+YieldExpression[In, Await] :
+ `yield`
+ => yield_expr($0, None)
+ `yield` [no LineTerminator here] AssignmentExpression[?In, +Yield, ?Await]
+ => yield_expr($0, Some($1))
+ `yield` [no LineTerminator here] `*` AssignmentExpression[?In, +Yield, ?Await]
+ => yield_star_expr($0, $2)
+
+
+@returns MethodDefinition
+AsyncGeneratorMethod[Yield, Await] :
+ `async` [no LineTerminator here] `*` ClassElementName[?Yield, ?Await] `(` UniqueFormalParameters[+Yield, +Await] `)` `{` AsyncGeneratorBody `}`
+ => async_generator_method($0, $2, $3, $4, $5, $6, $7, $8)
+
+@returns Statement
+AsyncGeneratorDeclaration[Yield, Await, Default] :
+ `async` [no LineTerminator here] `function` `*` BindingIdentifier[?Yield, ?Await] `(` FormalParameters[+Yield, +Await] `)` `{` AsyncGeneratorBody `}`
+ => function_decl(async_generator($0, Some($3), $4, $5, $6, $7, $8, $9))
+ [+Default] `async` [no LineTerminator here] `function` `*` `(` FormalParameters[+Yield, +Await] `)` `{` AsyncGeneratorBody `}`
+ => function_decl(async_generator($0, None, $3, $4, $5, $6, $7, $8))
+
+@returns Expression
+AsyncGeneratorExpression :
+ `async` [no LineTerminator here] `function` `*` BindingIdentifier[+Yield, +Await]? `(` FormalParameters[+Yield, +Await] `)` `{` AsyncGeneratorBody `}`
+ => function_expr(async_function($0, $3, $4, $5, $6, $7, $8, $9))
+
+@returns FunctionBody
+AsyncGeneratorBody :
+ FunctionBody[+Yield, +Await]
+ => $0
+
+
+@returns Statement
+ClassDeclaration[Yield, Await, Default] :
+ `class` BindingIdentifier[?Yield, ?Await] ClassTail[?Yield, ?Await]
+ => class_declaration($0, Some($1), $2)
+ [+Default] `class` ClassTail[?Yield, ?Await]
+ => class_declaration($0, None, $1)
+
+@returns Expression
+ClassExpression[Yield, Await] :
+ `class` BindingIdentifier[?Yield, ?Await]? ClassTail[?Yield, ?Await]
+ => class_expression($0, $1, $2)
+
+@returns ClassExpression
+ClassTail[Yield, Await] :
+ ClassHeritage[?Yield, ?Await]? `{` ClassBody[?Yield, ?Await]? `}`
+ => class_tail($0, $2, $3)
+
+@returns Expression
+ClassHeritage[Yield, Await] :
+ `extends` LeftHandSideExpression[?Yield, ?Await]
+ => $1
+
+@returns Vec<Box<ClassElement>>
+ClassBody[Yield, Await] :
+ ClassElementList[?Yield, ?Await]
+ => $0
+
+@returns Vec<Box<ClassElement>>
+ClassElementList[Yield, Await] :
+ ClassElement[?Yield, ?Await]
+ => $0
+ ClassElementList[?Yield, ?Await] ClassElement[?Yield, ?Await]
+ => class_element_list_append($0, $1)
+
+@returns ClassElement
+FieldDefinition[Yield, Await] :
+ ClassElementName[?Yield, ?Await] Initializer[+In, ~Yield, ~Await]?
+ => class_field_definition($0, $1)
+
+@returns ClassElementName
+ClassElementName[Yield, Await] :
+ PropertyName[?Yield, ?Await]
+ => property_name_to_class_element_name($0)
+ PrivateIdentifier
+ => class_element_name_private($0)
+
+@returns Vec<Box<ClassElement>>
+ClassElement[Yield, Await] :
+ MethodDefinition[?Yield, ?Await]
+ => class_element($0)
+ `static` MethodDefinition[?Yield, ?Await]
+ => class_element_static($0, $1)
+ FieldDefinition[?Yield, ?Await] `;`
+ => class_element_to_vec($0)
+ `static` FieldDefinition[?Yield, ?Await] `;`
+ => class_element_static_field($0, $1)
+ `;`
+ => class_element_empty()
+
+
+@returns Statement
+AsyncFunctionDeclaration[Yield, Await, Default] :
+ `async` [no LineTerminator here] `function` BindingIdentifier[?Yield, ?Await] `(` FormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
+ => function_decl(async_function($0, Some($2), $3, $4, $5, $6, $7, $8))
+ [+Default] `async` [no LineTerminator here] `function` `(` FormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
+ => function_decl(async_function($0, None, $2, $3, $4, $5, $6, $7))
+
+@returns Expression
+AsyncFunctionExpression :
+ `async` [no LineTerminator here] `function` `(` FormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
+ => function_expr(async_function($0, None, $2, $3, $4, $5, $6, $7))
+ `async` [no LineTerminator here] `function` BindingIdentifier[~Yield, +Await] `(` FormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
+ => function_expr(async_function($0, Some($2), $3, $4, $5, $6, $7, $8))
+
+@returns MethodDefinition
+AsyncMethod[Yield, Await] :
+ `async` [no LineTerminator here] PropertyName[?Yield, ?Await] `(` UniqueFormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
+ => async_method($0, $1, $2, $3, $4, $5, $6, $7)
+
+@returns FunctionBody
+AsyncFunctionBody :
+ FunctionBody[~Yield, +Await]
+ => $0
+
+@returns Expression
+AwaitExpression[Yield] :
+ `await` UnaryExpression[?Yield, +Await]
+ => await_expr($0, $1)
+
+
+@returns Expression
+AsyncArrowFunction[In, Yield, Await] :
+ `async` [no LineTerminator here] AsyncArrowBindingIdentifier[?Yield] [no LineTerminator here] `=>` AsyncConciseBody[?In]
+ => async_arrow_function_bare($0, $1, $3)
+ CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] [no LineTerminator here] `=>` AsyncConciseBody[?In]
+ => async_arrow_function($0, $2)
+
+@returns ArrowExpressionBody
+AsyncConciseBody[In] :
+ [lookahead != `{`] AssignmentExpression[?In, ~Yield, +Await]
+ => concise_body_expression($0)
+ `{` AsyncFunctionBody `}`
+ => concise_body_block($0, $1, $2)
+
+@returns BindingIdentifier
+AsyncArrowBindingIdentifier[Yield] :
+ BindingIdentifier[?Yield, +Await]
+ => $0
+
+@returns Expression
+CoverCallExpressionAndAsyncArrowHead[Yield, Await] :
+ MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]
+ => call_expr($0, $1)
+
+
+AsyncArrowHead :
+ `async` [no LineTerminator here] ArrowFormalParameters[~Yield, +Await]
+
+
+@returns Script
+Script :
+ ScriptBody?
+ => script($0)
+
+@returns Script
+ScriptBody :
+ StatementList[~Yield, ~Await, ~Return]
+ => script_body($0)
+
+@returns Vec<Statement>
+Module :
+ ModuleBody?
+ => module($0)
+
+@returns Vec<Statement>
+ModuleBody :
+ ModuleItemList
+ => $0
+
+@returns Vec<Statement>
+ModuleItemList :
+ ModuleItem
+ => module_item_list_single($0)
+ ModuleItemList ModuleItem
+ => module_item_list_append($0, $1)
+
+@returns Statement
+ModuleItem :
+ ImportDeclaration
+ => $0
+ ExportDeclaration
+ => $0
+ StatementListItem[~Yield, ~Await, ~Return]
+ => $0
+
+
+@returns Statement
+ImportDeclaration :
+ `import` ImportClause FromClause `;`
+ => import_declaration(Some($1), $2)
+ `import` ModuleSpecifier `;`
+ => import_declaration(None, $1)
+
+@returns Void
+ImportClause :
+ ImportedDefaultBinding
+ => import_clause(Some($0), None, None)
+ NameSpaceImport
+ => import_clause(None, Some($0), None)
+ NamedImports
+ => import_clause(None, None, Some($0))
+ ImportedDefaultBinding `,` NameSpaceImport
+ => import_clause(Some($0), Some($2), None)
+ ImportedDefaultBinding `,` NamedImports
+ => import_clause(Some($0), None, Some($2))
+
+@returns BindingIdentifier
+ImportedDefaultBinding :
+ ImportedBinding
+ => $0
+
+@returns Void
+NameSpaceImport :
+ `*` `as` ImportedBinding
+ => name_space_import($2)
+
+@returns Void
+NamedImports :
+ `{` `}`
+ => imports_list_empty()
+ `{` ImportsList `}`
+ => $1
+ `{` ImportsList `,` `}`
+ => $1
+
+@returns Token
+FromClause :
+ `from` ModuleSpecifier
+ => $1
+
+@returns Void
+ImportsList :
+ ImportSpecifier
+ => imports_list_append(imports_list_empty(), $0)
+ ImportsList `,` ImportSpecifier
+ => imports_list_append($0, $2)
+
+@returns Void
+ImportSpecifier :
+ ImportedBinding
+ => import_specifier($0)
+ IdentifierName `as` ImportedBinding
+ => import_specifier_renaming($0, $2)
+
+@returns Token
+ModuleSpecifier :
+ StringLiteral
+ => module_specifier($0)
+
+@returns BindingIdentifier
+ImportedBinding :
+ BindingIdentifier[~Yield, ~Await]
+ => $0
+
+
+@returns Statement
+ExportDeclaration :
+ `export` `*` FromClause `;`
+ => export_all_from($2)
+ `export` ExportClause FromClause `;`
+ => export_set_from($1, $2)
+ `export` ExportClause `;`
+ => export_set($1)
+ `export` VariableStatement[~Yield, ~Await]
+ => export_vars($1)
+ `export` Declaration[~Yield, ~Await]
+ => export_declaration($1)
+ `export` `default` HoistableDeclaration[~Yield, ~Await, +Default]
+ => export_default_hoistable($2)
+ `export` `default` ClassDeclaration[~Yield, ~Await, +Default]
+ => export_default_class($2)
+ `export` `default` [lookahead <! {`function`, `async`, `class`}] AssignmentExpression[+In, ~Yield, ~Await] `;`
+ => export_default_value($2)
+
+@returns Void
+ExportClause :
+ `{` `}`
+ => exports_list_empty()
+ `{` ExportsList `}`
+ => $1
+ `{` ExportsList `,` `}`
+ => $1
+
+@returns Void
+ExportsList :
+ ExportSpecifier
+ => exports_list_append(exports_list_empty(), $0)
+ ExportsList `,` ExportSpecifier
+ => exports_list_append($0, $2)
+
+@returns Void
+ExportSpecifier :
+ IdentifierName
+ => export_specifier($0)
+ IdentifierName `as` IdentifierName
+ => export_specifier_renaming($0, $2)
+
diff --git a/third_party/rust/jsparagus/js_parser/es.esgrammar b/third_party/rust/jsparagus/js_parser/es.esgrammar
new file mode 100644
index 0000000000..955fbdfe00
--- /dev/null
+++ b/third_party/rust/jsparagus/js_parser/es.esgrammar
@@ -0,0 +1,1668 @@
+
+StringNumericLiteral :::
+ StrWhiteSpace?
+ StrWhiteSpace? StrNumericLiteral StrWhiteSpace?
+
+StrWhiteSpace :::
+ StrWhiteSpaceChar StrWhiteSpace?
+
+StrWhiteSpaceChar :::
+ WhiteSpace
+ LineTerminator
+
+StrNumericLiteral :::
+ StrDecimalLiteral
+ BinaryIntegerLiteral
+ OctalIntegerLiteral
+ HexIntegerLiteral
+
+StrDecimalLiteral :::
+ StrUnsignedDecimalLiteral
+ `+` StrUnsignedDecimalLiteral
+ `-` StrUnsignedDecimalLiteral
+
+StrUnsignedDecimalLiteral :::
+ `Infinity`
+ DecimalDigits `.` DecimalDigits? ExponentPart?
+ `.` DecimalDigits ExponentPart?
+ DecimalDigits ExponentPart?
+
+
+SourceCharacter ::
+ > any Unicode code point
+
+
+InputElementDiv ::
+ WhiteSpace
+ LineTerminator
+ Comment
+ CommonToken
+ DivPunctuator
+ RightBracePunctuator
+
+InputElementRegExp ::
+ WhiteSpace
+ LineTerminator
+ Comment
+ CommonToken
+ RightBracePunctuator
+ RegularExpressionLiteral
+
+InputElementRegExpOrTemplateTail ::
+ WhiteSpace
+ LineTerminator
+ Comment
+ CommonToken
+ RegularExpressionLiteral
+ TemplateSubstitutionTail
+
+InputElementTemplateTail ::
+ WhiteSpace
+ LineTerminator
+ Comment
+ CommonToken
+ DivPunctuator
+ TemplateSubstitutionTail
+
+
+WhiteSpace ::
+ <TAB>
+ <VT>
+ <FF>
+ <SP>
+ <NBSP>
+ <ZWNBSP>
+ <USP>
+
+
+LineTerminator ::
+ <LF>
+ <CR>
+ <LS>
+ <PS>
+
+LineTerminatorSequence ::
+ <LF>
+ <CR> [lookahead != <LF> ]
+ <LS>
+ <PS>
+ <CR> <LF>
+
+
+Comment ::
+ MultiLineComment
+ SingleLineComment
+
+MultiLineComment ::
+ `/*` MultiLineCommentChars? `*/`
+
+MultiLineCommentChars ::
+ MultiLineNotAsteriskChar MultiLineCommentChars?
+ `*` PostAsteriskCommentChars?
+
+PostAsteriskCommentChars ::
+ MultiLineNotForwardSlashOrAsteriskChar MultiLineCommentChars?
+ `*` PostAsteriskCommentChars?
+
+MultiLineNotAsteriskChar ::
+ SourceCharacter but not `*`
+
+MultiLineNotForwardSlashOrAsteriskChar ::
+ SourceCharacter but not one of `/` or `*`
+
+SingleLineComment ::
+ `//` SingleLineCommentChars?
+
+SingleLineCommentChars ::
+ SingleLineCommentChar SingleLineCommentChars?
+
+SingleLineCommentChar ::
+ SourceCharacter but not LineTerminator
+
+
+CommonToken ::
+ IdentifierName
+ Punctuator
+ NumericLiteral
+ StringLiteral
+ Template
+
+
+IdentifierName ::
+ IdentifierStart
+ IdentifierName IdentifierPart
+
+IdentifierStart ::
+ UnicodeIDStart
+ `$`
+ `_`
+ `\` UnicodeEscapeSequence
+
+IdentifierPart ::
+ UnicodeIDContinue
+ `$`
+ `\` UnicodeEscapeSequence
+ <ZWNJ>
+ <ZWJ>
+
+UnicodeIDStart ::
+ > any Unicode code point with the Unicode property “ID_Start”
+
+UnicodeIDContinue ::
+ > any Unicode code point with the Unicode property “ID_Continue”
+
+
+ReservedWord ::
+ Keyword
+ FutureReservedWord
+ NullLiteral
+ BooleanLiteral
+
+
+Keyword :: one of
+ `await`
+ `break`
+ `case` `catch` `class` `const` `continue`
+ `debugger` `default` `delete` `do`
+ `else` `export` `extends`
+ `finally` `for` `function`
+ `if` `import` `in` `instanceof`
+ `new`
+ `return`
+ `super` `switch`
+ `this` `throw` `try` `typeof`
+ `var` `void`
+ `while` `with`
+ `yield`
+
+
+FutureReservedWord ::
+ `enum`
+
+
+Punctuator :: one of
+ `{` `(` `)` `[` `]`
+ `.` `...` `;` `,`
+ `<` `>` `<=` `>=`
+ `==` `!=` `===` `!==`
+ `+` `-` `*` `%` `**`
+ `++` `--`
+ `<<` `>>` `>>>`
+ `&` `|` `^`
+ `!` `~`
+ `&&` `||`
+ `?` `:`
+ `=` `+=` `-=` `*=` `%=` `**=` `<<=` `>>=` `>>>=` `&=` `|=` `^=`
+ `=>`
+
+DivPunctuator ::
+ `/`
+ `/=`
+
+RightBracePunctuator ::
+ `}`
+
+
+NullLiteral ::
+ `null`
+
+
+BooleanLiteral ::
+ `true`
+ `false`
+
+
+NumericLiteral ::
+ DecimalLiteral
+ BinaryIntegerLiteral
+ OctalIntegerLiteral
+ HexIntegerLiteral
+
+DecimalLiteral ::
+ DecimalIntegerLiteral `.` DecimalDigits? ExponentPart?
+ `.` DecimalDigits ExponentPart?
+ DecimalIntegerLiteral ExponentPart?
+
+DecimalIntegerLiteral ::
+ `0`
+ NonZeroDigit DecimalDigits?
+
+DecimalDigits ::
+ DecimalDigit
+ DecimalDigits DecimalDigit
+
+DecimalDigit :: one of
+ `0` `1` `2` `3` `4` `5` `6` `7` `8` `9`
+
+NonZeroDigit :: one of
+ `1` `2` `3` `4` `5` `6` `7` `8` `9`
+
+ExponentPart ::
+ ExponentIndicator SignedInteger
+
+ExponentIndicator :: one of
+ `e` `E`
+
+SignedInteger ::
+ DecimalDigits
+ `+` DecimalDigits
+ `-` DecimalDigits
+
+BinaryIntegerLiteral ::
+ `0b` BinaryDigits
+ `0B` BinaryDigits
+
+BinaryDigits ::
+ BinaryDigit
+ BinaryDigits BinaryDigit
+
+BinaryDigit :: one of
+ `0` `1`
+
+OctalIntegerLiteral ::
+ `0o` OctalDigits
+ `0O` OctalDigits
+
+OctalDigits ::
+ OctalDigit
+ OctalDigits OctalDigit
+
+OctalDigit :: one of
+ `0` `1` `2` `3` `4` `5` `6` `7`
+
+HexIntegerLiteral ::
+ `0x` HexDigits
+ `0X` HexDigits
+
+HexDigits ::
+ HexDigit
+ HexDigits HexDigit
+
+HexDigit :: one of
+ `0` `1` `2` `3` `4` `5` `6` `7` `8` `9` `a` `b` `c` `d` `e` `f` `A` `B` `C` `D` `E` `F`
+
+
+StringLiteral ::
+ `"` DoubleStringCharacters? `"`
+ `'` SingleStringCharacters? `'`
+
+DoubleStringCharacters ::
+ DoubleStringCharacter DoubleStringCharacters?
+
+SingleStringCharacters ::
+ SingleStringCharacter SingleStringCharacters?
+
+DoubleStringCharacter ::
+ SourceCharacter but not one of `"` or `\` or LineTerminator
+ <LS>
+ <PS>
+ `\` EscapeSequence
+ LineContinuation
+
+SingleStringCharacter ::
+ SourceCharacter but not one of `'` or `\` or LineTerminator
+ <LS>
+ <PS>
+ `\` EscapeSequence
+ LineContinuation
+
+LineContinuation ::
+ `\` LineTerminatorSequence
+
+EscapeSequence ::
+ CharacterEscapeSequence
+ `0` [lookahead <! DecimalDigit]
+ HexEscapeSequence
+ UnicodeEscapeSequence
+
+
+CharacterEscapeSequence ::
+ SingleEscapeCharacter
+ NonEscapeCharacter
+
+SingleEscapeCharacter :: one of
+ `'` `"` `\` `b` `f` `n` `r` `t` `v`
+
+NonEscapeCharacter ::
+ SourceCharacter but not one of EscapeCharacter or LineTerminator
+
+EscapeCharacter ::
+ SingleEscapeCharacter
+ DecimalDigit
+ `x`
+ `u`
+
+HexEscapeSequence ::
+ `x` HexDigit HexDigit
+
+UnicodeEscapeSequence ::
+ `u` Hex4Digits
+ `u{` CodePoint `}`
+
+Hex4Digits ::
+ HexDigit HexDigit HexDigit HexDigit
+
+
+RegularExpressionLiteral ::
+ `/` RegularExpressionBody `/` RegularExpressionFlags
+
+RegularExpressionBody ::
+ RegularExpressionFirstChar RegularExpressionChars
+
+RegularExpressionChars ::
+ [empty]
+ RegularExpressionChars RegularExpressionChar
+
+RegularExpressionFirstChar ::
+ RegularExpressionNonTerminator but not one of `*` or `\` or `/` or `[`
+ RegularExpressionBackslashSequence
+ RegularExpressionClass
+
+RegularExpressionChar ::
+ RegularExpressionNonTerminator but not one of `\` or `/` or `[`
+ RegularExpressionBackslashSequence
+ RegularExpressionClass
+
+RegularExpressionBackslashSequence ::
+ `\` RegularExpressionNonTerminator
+
+RegularExpressionNonTerminator ::
+ SourceCharacter but not LineTerminator
+
+RegularExpressionClass ::
+ `[` RegularExpressionClassChars `]`
+
+RegularExpressionClassChars ::
+ [empty]
+ RegularExpressionClassChars RegularExpressionClassChar
+
+RegularExpressionClassChar ::
+ RegularExpressionNonTerminator but not one of `]` or `\`
+ RegularExpressionBackslashSequence
+
+RegularExpressionFlags ::
+ [empty]
+ RegularExpressionFlags IdentifierPart
+
+
+Template ::
+ NoSubstitutionTemplate
+ TemplateHead
+
+NoSubstitutionTemplate ::
+ ``` TemplateCharacters? ```
+
+TemplateHead ::
+ ``` TemplateCharacters? `${`
+
+TemplateSubstitutionTail ::
+ TemplateMiddle
+ TemplateTail
+
+TemplateMiddle ::
+ `}` TemplateCharacters? `${`
+
+TemplateTail ::
+ `}` TemplateCharacters? ```
+
+TemplateCharacters ::
+ TemplateCharacter TemplateCharacters?
+
+TemplateCharacter ::
+ `$` [lookahead != `{` ]
+ `\` EscapeSequence
+ `\` NotEscapeSequence
+ LineContinuation
+ LineTerminatorSequence
+ SourceCharacter but not one of ``` or `\` or `$` or LineTerminator
+
+NotEscapeSequence ::
+ `0` DecimalDigit
+ DecimalDigit but not `0`
+ `x` [lookahead <! HexDigit]
+ `x` HexDigit [lookahead <! HexDigit]
+ `u` [lookahead <! HexDigit] [lookahead != `{`]
+ `u` HexDigit [lookahead <! HexDigit]
+ `u` HexDigit HexDigit [lookahead <! HexDigit]
+ `u` HexDigit HexDigit HexDigit [lookahead <! HexDigit]
+ `u` `{` [lookahead <! HexDigit]
+ `u` `{` NotCodePoint [lookahead <! HexDigit]
+ `u` `{` CodePoint [lookahead <! HexDigit] [lookahead != `}`]
+
+NotCodePoint ::
+ HexDigits [> but only if MV of |HexDigits| > 0x10FFFF ]
+
+CodePoint ::
+ HexDigits [> but only if MV of |HexDigits| ≤ 0x10FFFF ]
+
+
+IdentifierReference[Yield, Await] :
+ Identifier
+ [~Yield] `yield`
+ [~Await] `await`
+
+BindingIdentifier[Yield, Await] :
+ Identifier
+ `yield`
+ `await`
+
+LabelIdentifier[Yield, Await] :
+ Identifier
+ [~Yield] `yield`
+ [~Await] `await`
+
+Identifier :
+ IdentifierName but not ReservedWord
+
+
+PrimaryExpression[Yield, Await] :
+ `this`
+ IdentifierReference[?Yield, ?Await]
+ Literal
+ ArrayLiteral[?Yield, ?Await]
+ ObjectLiteral[?Yield, ?Await]
+ FunctionExpression
+ ClassExpression[?Yield, ?Await]
+ GeneratorExpression
+ AsyncFunctionExpression
+ AsyncGeneratorExpression
+ RegularExpressionLiteral
+ TemplateLiteral[?Yield, ?Await, ~Tagged]
+ CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] #parencover
+
+CoverParenthesizedExpressionAndArrowParameterList[Yield, Await] :
+ `(` Expression[+In, ?Yield, ?Await] `)`
+ `(` Expression[+In, ?Yield, ?Await] `,` `)`
+ `(` `)`
+ `(` `...` BindingIdentifier[?Yield, ?Await] `)`
+ `(` `...` BindingPattern[?Yield, ?Await] `)`
+ `(` Expression[+In, ?Yield, ?Await] `,` `...` BindingIdentifier[?Yield, ?Await] `)`
+ `(` Expression[+In, ?Yield, ?Await] `,` `...` BindingPattern[?Yield, ?Await] `)`
+
+
+ParenthesizedExpression[Yield, Await] :
+ `(` Expression[+In, ?Yield, ?Await] `)`
+
+
+Literal :
+ NullLiteral
+ BooleanLiteral
+ NumericLiteral
+ StringLiteral
+
+
+ArrayLiteral[Yield, Await] :
+ `[` Elision? `]`
+ `[` ElementList[?Yield, ?Await] `]`
+ `[` ElementList[?Yield, ?Await] `,` Elision? `]`
+
+ElementList[Yield, Await] :
+ Elision? AssignmentExpression[+In, ?Yield, ?Await]
+ Elision? SpreadElement[?Yield, ?Await]
+ ElementList[?Yield, ?Await] `,` Elision? AssignmentExpression[+In, ?Yield, ?Await]
+ ElementList[?Yield, ?Await] `,` Elision? SpreadElement[?Yield, ?Await]
+
+Elision :
+ `,`
+ Elision `,`
+
+SpreadElement[Yield, Await] :
+ `...` AssignmentExpression[+In, ?Yield, ?Await]
+
+
+ObjectLiteral[Yield, Await] :
+ `{` `}`
+ `{` PropertyDefinitionList[?Yield, ?Await] `}`
+ `{` PropertyDefinitionList[?Yield, ?Await] `,` `}`
+
+PropertyDefinitionList[Yield, Await] :
+ PropertyDefinition[?Yield, ?Await]
+ PropertyDefinitionList[?Yield, ?Await] `,` PropertyDefinition[?Yield, ?Await]
+
+PropertyDefinition[Yield, Await] :
+ IdentifierReference[?Yield, ?Await]
+ CoverInitializedName[?Yield, ?Await]
+ PropertyName[?Yield, ?Await] `:` AssignmentExpression[+In, ?Yield, ?Await]
+ MethodDefinition[?Yield, ?Await]
+ `...` AssignmentExpression[+In, ?Yield, ?Await]
+
+PropertyName[Yield, Await] :
+ LiteralPropertyName
+ ComputedPropertyName[?Yield, ?Await]
+
+LiteralPropertyName :
+ IdentifierName
+ StringLiteral
+ NumericLiteral
+
+ComputedPropertyName[Yield, Await] :
+ `[` AssignmentExpression[+In, ?Yield, ?Await] `]`
+
+CoverInitializedName[Yield, Await] :
+ IdentifierReference[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]
+
+Initializer[In, Yield, Await] :
+ `=` AssignmentExpression[?In, ?Yield, ?Await]
+
+
+TemplateLiteral[Yield, Await, Tagged] :
+ NoSubstitutionTemplate
+ SubstitutionTemplate[?Yield, ?Await, ?Tagged]
+
+SubstitutionTemplate[Yield, Await, Tagged] :
+ TemplateHead Expression[+In, ?Yield, ?Await] TemplateSpans[?Yield, ?Await, ?Tagged]
+
+TemplateSpans[Yield, Await, Tagged] :
+ TemplateTail
+ TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateTail
+
+TemplateMiddleList[Yield, Await, Tagged] :
+ TemplateMiddle Expression[+In, ?Yield, ?Await]
+ TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateMiddle Expression[+In, ?Yield, ?Await]
+
+
+MemberExpression[Yield, Await] :
+ PrimaryExpression[?Yield, ?Await]
+ MemberExpression[?Yield, ?Await] `[` Expression[+In, ?Yield, ?Await] `]`
+ MemberExpression[?Yield, ?Await] `.` IdentifierName
+ MemberExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged]
+ SuperProperty[?Yield, ?Await]
+ MetaProperty
+ `new` MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]
+
+SuperProperty[Yield, Await] :
+ `super` `[` Expression[+In, ?Yield, ?Await] `]`
+ `super` `.` IdentifierName
+
+MetaProperty :
+ NewTarget
+
+NewTarget :
+ `new` `.` `target`
+
+NewExpression[Yield, Await] :
+ MemberExpression[?Yield, ?Await]
+ `new` NewExpression[?Yield, ?Await]
+
+CallExpression[Yield, Await] :
+ CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] #callcover
+ SuperCall[?Yield, ?Await]
+ ImportCall[?Yield, ?Await]
+ CallExpression[?Yield, ?Await] Arguments[?Yield, ?Await]
+ CallExpression[?Yield, ?Await] `[` Expression[+In, ?Yield, ?Await] `]`
+ CallExpression[?Yield, ?Await] `.` IdentifierName
+ CallExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged]
+
+SuperCall[Yield, Await] :
+ `super` Arguments[?Yield, ?Await]
+
+ImportCall[Yield, Await] :
+ `import` `(` AssignmentExpression[+In, ?Yield, ?Await] `)`
+
+Arguments[Yield, Await] :
+ `(` `)`
+ `(` ArgumentList[?Yield, ?Await] `)`
+ `(` ArgumentList[?Yield, ?Await] `,` `)`
+
+ArgumentList[Yield, Await] :
+ AssignmentExpression[+In, ?Yield, ?Await]
+ `...` AssignmentExpression[+In, ?Yield, ?Await]
+ ArgumentList[?Yield, ?Await] `,` AssignmentExpression[+In, ?Yield, ?Await]
+ ArgumentList[?Yield, ?Await] `,` `...` AssignmentExpression[+In, ?Yield, ?Await]
+
+LeftHandSideExpression[Yield, Await] :
+ NewExpression[?Yield, ?Await]
+ CallExpression[?Yield, ?Await]
+
+
+CallMemberExpression[Yield, Await] :
+ MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]
+
+
+UpdateExpression[Yield, Await] :
+ LeftHandSideExpression[?Yield, ?Await]
+ LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] `++`
+ LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] `--`
+ `++` UnaryExpression[?Yield, ?Await]
+ `--` UnaryExpression[?Yield, ?Await]
+
+
+UnaryExpression[Yield, Await] :
+ UpdateExpression[?Yield, ?Await]
+ `delete` UnaryExpression[?Yield, ?Await]
+ `void` UnaryExpression[?Yield, ?Await]
+ `typeof` UnaryExpression[?Yield, ?Await]
+ `+` UnaryExpression[?Yield, ?Await]
+ `-` UnaryExpression[?Yield, ?Await]
+ `~` UnaryExpression[?Yield, ?Await]
+ `!` UnaryExpression[?Yield, ?Await]
+ [+Await] AwaitExpression[?Yield]
+
+
+ExponentiationExpression[Yield, Await] :
+ UnaryExpression[?Yield, ?Await]
+ UpdateExpression[?Yield, ?Await] `**` ExponentiationExpression[?Yield, ?Await]
+
+
+MultiplicativeExpression[Yield, Await] :
+ ExponentiationExpression[?Yield, ?Await]
+ MultiplicativeExpression[?Yield, ?Await] MultiplicativeOperator ExponentiationExpression[?Yield, ?Await]
+
+MultiplicativeOperator : one of
+ `*` `/` `%`
+
+
+AdditiveExpression[Yield, Await] :
+ MultiplicativeExpression[?Yield, ?Await]
+ AdditiveExpression[?Yield, ?Await] `+` MultiplicativeExpression[?Yield, ?Await]
+ AdditiveExpression[?Yield, ?Await] `-` MultiplicativeExpression[?Yield, ?Await]
+
+
+ShiftExpression[Yield, Await] :
+ AdditiveExpression[?Yield, ?Await]
+ ShiftExpression[?Yield, ?Await] `<<` AdditiveExpression[?Yield, ?Await]
+ ShiftExpression[?Yield, ?Await] `>>` AdditiveExpression[?Yield, ?Await]
+ ShiftExpression[?Yield, ?Await] `>>>` AdditiveExpression[?Yield, ?Await]
+
+
+RelationalExpression[In, Yield, Await] :
+ ShiftExpression[?Yield, ?Await]
+ RelationalExpression[?In, ?Yield, ?Await] `<` ShiftExpression[?Yield, ?Await]
+ RelationalExpression[?In, ?Yield, ?Await] `>` ShiftExpression[?Yield, ?Await]
+ RelationalExpression[?In, ?Yield, ?Await] `<=` ShiftExpression[?Yield, ?Await]
+ RelationalExpression[?In, ?Yield, ?Await] `>=` ShiftExpression[?Yield, ?Await]
+ RelationalExpression[?In, ?Yield, ?Await] `instanceof` ShiftExpression[?Yield, ?Await]
+ [+In] RelationalExpression[+In, ?Yield, ?Await] `in` ShiftExpression[?Yield, ?Await]
+
+
+EqualityExpression[In, Yield, Await] :
+ RelationalExpression[?In, ?Yield, ?Await]
+ EqualityExpression[?In, ?Yield, ?Await] `==` RelationalExpression[?In, ?Yield, ?Await]
+ EqualityExpression[?In, ?Yield, ?Await] `!=` RelationalExpression[?In, ?Yield, ?Await]
+ EqualityExpression[?In, ?Yield, ?Await] `===` RelationalExpression[?In, ?Yield, ?Await]
+ EqualityExpression[?In, ?Yield, ?Await] `!==` RelationalExpression[?In, ?Yield, ?Await]
+
+
+BitwiseANDExpression[In, Yield, Await] :
+ EqualityExpression[?In, ?Yield, ?Await]
+ BitwiseANDExpression[?In, ?Yield, ?Await] `&` EqualityExpression[?In, ?Yield, ?Await]
+
+BitwiseXORExpression[In, Yield, Await] :
+ BitwiseANDExpression[?In, ?Yield, ?Await]
+ BitwiseXORExpression[?In, ?Yield, ?Await] `^` BitwiseANDExpression[?In, ?Yield, ?Await]
+
+BitwiseORExpression[In, Yield, Await] :
+ BitwiseXORExpression[?In, ?Yield, ?Await]
+ BitwiseORExpression[?In, ?Yield, ?Await] `|` BitwiseXORExpression[?In, ?Yield, ?Await]
+
+
+LogicalANDExpression[In, Yield, Await] :
+ BitwiseORExpression[?In, ?Yield, ?Await]
+ LogicalANDExpression[?In, ?Yield, ?Await] `&&` BitwiseORExpression[?In, ?Yield, ?Await]
+
+LogicalORExpression[In, Yield, Await] :
+ LogicalANDExpression[?In, ?Yield, ?Await]
+ LogicalORExpression[?In, ?Yield, ?Await] `||` LogicalANDExpression[?In, ?Yield, ?Await]
+
+
+ConditionalExpression[In, Yield, Await] :
+ LogicalORExpression[?In, ?Yield, ?Await]
+ LogicalORExpression[?In, ?Yield, ?Await] `?` AssignmentExpression[+In, ?Yield, ?Await] `:` AssignmentExpression[?In, ?Yield, ?Await]
+
+
+AssignmentExpression[In, Yield, Await] :
+ ConditionalExpression[?In, ?Yield, ?Await]
+ [+Yield] YieldExpression[?In, ?Await]
+ ArrowFunction[?In, ?Yield, ?Await]
+ AsyncArrowFunction[?In, ?Yield, ?Await]
+ LeftHandSideExpression[?Yield, ?Await] `=` AssignmentExpression[?In, ?Yield, ?Await] #assignment
+ LeftHandSideExpression[?Yield, ?Await] AssignmentOperator AssignmentExpression[?In, ?Yield, ?Await]
+
+AssignmentOperator : one of
+ `*=` `/=` `%=` `+=` `-=` `<<=` `>>=` `>>>=` `&=` `^=` `|=` `**=`
+
+
+AssignmentPattern[Yield, Await] :
+ ObjectAssignmentPattern[?Yield, ?Await]
+ ArrayAssignmentPattern[?Yield, ?Await]
+
+ObjectAssignmentPattern[Yield, Await] :
+ `{` `}`
+ `{` AssignmentRestProperty[?Yield, ?Await] `}`
+ `{` AssignmentPropertyList[?Yield, ?Await] `}`
+ `{` AssignmentPropertyList[?Yield, ?Await] `,` AssignmentRestProperty[?Yield, ?Await]? `}`
+
+ArrayAssignmentPattern[Yield, Await] :
+ `[` Elision? AssignmentRestElement[?Yield, ?Await]? `]`
+ `[` AssignmentElementList[?Yield, ?Await] `]`
+ `[` AssignmentElementList[?Yield, ?Await] `,` Elision? AssignmentRestElement[?Yield, ?Await]? `]`
+
+AssignmentRestProperty[Yield, Await] :
+ `...` DestructuringAssignmentTarget[?Yield, ?Await]
+
+AssignmentPropertyList[Yield, Await] :
+ AssignmentProperty[?Yield, ?Await]
+ AssignmentPropertyList[?Yield, ?Await] `,` AssignmentProperty[?Yield, ?Await]
+
+AssignmentElementList[Yield, Await] :
+ AssignmentElisionElement[?Yield, ?Await]
+ AssignmentElementList[?Yield, ?Await] `,` AssignmentElisionElement[?Yield, ?Await]
+
+AssignmentElisionElement[Yield, Await] :
+ Elision? AssignmentElement[?Yield, ?Await]
+
+AssignmentProperty[Yield, Await] :
+ IdentifierReference[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]?
+ PropertyName[?Yield, ?Await] `:` AssignmentElement[?Yield, ?Await]
+
+AssignmentElement[Yield, Await] :
+ DestructuringAssignmentTarget[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]?
+
+AssignmentRestElement[Yield, Await] :
+ `...` DestructuringAssignmentTarget[?Yield, ?Await]
+
+DestructuringAssignmentTarget[Yield, Await] :
+ LeftHandSideExpression[?Yield, ?Await]
+
+
+Expression[In, Yield, Await] :
+ AssignmentExpression[?In, ?Yield, ?Await]
+ Expression[?In, ?Yield, ?Await] `,` AssignmentExpression[?In, ?Yield, ?Await]
+
+
+Statement[Yield, Await, Return] :
+ BlockStatement[?Yield, ?Await, ?Return]
+ VariableStatement[?Yield, ?Await]
+ EmptyStatement
+ ExpressionStatement[?Yield, ?Await]
+ IfStatement[?Yield, ?Await, ?Return]
+ BreakableStatement[?Yield, ?Await, ?Return]
+ ContinueStatement[?Yield, ?Await]
+ BreakStatement[?Yield, ?Await]
+ [+Return] ReturnStatement[?Yield, ?Await]
+ WithStatement[?Yield, ?Await, ?Return]
+ LabelledStatement[?Yield, ?Await, ?Return]
+ ThrowStatement[?Yield, ?Await]
+ TryStatement[?Yield, ?Await, ?Return]
+ DebuggerStatement
+
+Declaration[Yield, Await] :
+ HoistableDeclaration[?Yield, ?Await, ~Default]
+ ClassDeclaration[?Yield, ?Await, ~Default]
+ LexicalDeclaration[+In, ?Yield, ?Await]
+
+HoistableDeclaration[Yield, Await, Default] :
+ FunctionDeclaration[?Yield, ?Await, ?Default]
+ GeneratorDeclaration[?Yield, ?Await, ?Default]
+ AsyncFunctionDeclaration[?Yield, ?Await, ?Default]
+ AsyncGeneratorDeclaration[?Yield, ?Await, ?Default]
+
+BreakableStatement[Yield, Await, Return] :
+ IterationStatement[?Yield, ?Await, ?Return]
+ SwitchStatement[?Yield, ?Await, ?Return]
+
+
+BlockStatement[Yield, Await, Return] :
+ Block[?Yield, ?Await, ?Return]
+
+Block[Yield, Await, Return] :
+ `{` StatementList[?Yield, ?Await, ?Return]? `}`
+
+StatementList[Yield, Await, Return] :
+ StatementListItem[?Yield, ?Await, ?Return]
+ StatementList[?Yield, ?Await, ?Return] StatementListItem[?Yield, ?Await, ?Return]
+
+StatementListItem[Yield, Await, Return] :
+ Statement[?Yield, ?Await, ?Return]
+ Declaration[?Yield, ?Await]
+
+
+LexicalDeclaration[In, Yield, Await] :
+ LetOrConst BindingList[?In, ?Yield, ?Await] `;`
+
+LetOrConst :
+ `let`
+ `const`
+
+BindingList[In, Yield, Await] :
+ LexicalBinding[?In, ?Yield, ?Await]
+ BindingList[?In, ?Yield, ?Await] `,` LexicalBinding[?In, ?Yield, ?Await]
+
+LexicalBinding[In, Yield, Await] :
+ BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]?
+ BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]
+
+
+VariableStatement[Yield, Await] :
+ `var` VariableDeclarationList[+In, ?Yield, ?Await] `;`
+
+VariableDeclarationList[In, Yield, Await] :
+ VariableDeclaration[?In, ?Yield, ?Await]
+ VariableDeclarationList[?In, ?Yield, ?Await] `,` VariableDeclaration[?In, ?Yield, ?Await]
+
+VariableDeclaration[In, Yield, Await] :
+ BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]?
+ BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]
+
+
+BindingPattern[Yield, Await] :
+ ObjectBindingPattern[?Yield, ?Await]
+ ArrayBindingPattern[?Yield, ?Await]
+
+ObjectBindingPattern[Yield, Await] :
+ `{` `}`
+ `{` BindingRestProperty[?Yield, ?Await] `}`
+ `{` BindingPropertyList[?Yield, ?Await] `}`
+ `{` BindingPropertyList[?Yield, ?Await] `,` BindingRestProperty[?Yield, ?Await]? `}`
+
+ArrayBindingPattern[Yield, Await] :
+ `[` Elision? BindingRestElement[?Yield, ?Await]? `]`
+ `[` BindingElementList[?Yield, ?Await] `]`
+ `[` BindingElementList[?Yield, ?Await] `,` Elision? BindingRestElement[?Yield, ?Await]? `]`
+
+BindingRestProperty[Yield, Await] :
+ `...` BindingIdentifier[?Yield, ?Await]
+
+BindingPropertyList[Yield, Await] :
+ BindingProperty[?Yield, ?Await]
+ BindingPropertyList[?Yield, ?Await] `,` BindingProperty[?Yield, ?Await]
+
+BindingElementList[Yield, Await] :
+ BindingElisionElement[?Yield, ?Await]
+ BindingElementList[?Yield, ?Await] `,` BindingElisionElement[?Yield, ?Await]
+
+BindingElisionElement[Yield, Await] :
+ Elision? BindingElement[?Yield, ?Await]
+
+BindingProperty[Yield, Await] :
+ SingleNameBinding[?Yield, ?Await]
+ PropertyName[?Yield, ?Await] `:` BindingElement[?Yield, ?Await]
+
+BindingElement[Yield, Await] :
+ SingleNameBinding[?Yield, ?Await]
+ BindingPattern[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]?
+
+SingleNameBinding[Yield, Await] :
+ BindingIdentifier[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]?
+
+BindingRestElement[Yield, Await] :
+ `...` BindingIdentifier[?Yield, ?Await]
+ `...` BindingPattern[?Yield, ?Await]
+
+
+EmptyStatement :
+ `;`
+
+
+ExpressionStatement[Yield, Await] :
+ [lookahead <! {`{`, `function`, `async` [no |LineTerminator| here] `function`, `class`, `let` `[`}] Expression[+In, ?Yield, ?Await] `;`
+
+
+IfStatement[Yield, Await, Return] :
+ `if` `(` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return] `else` Statement[?Yield, ?Await, ?Return]
+ `if` `(` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+
+
+IterationStatement[Yield, Await, Return] :
+ `do` Statement[?Yield, ?Await, ?Return] `while` `(` Expression[+In, ?Yield, ?Await] `)` `;`
+ `while` `(` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` [lookahead != `let` `[`] Expression[~In, ?Yield, ?Await]? `;` Expression[+In, ?Yield, ?Await]? `;` Expression[+In, ?Yield, ?Await]? `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` `var` VariableDeclarationList[~In, ?Yield, ?Await] `;` Expression[+In, ?Yield, ?Await]? `;` Expression[+In, ?Yield, ?Await]? `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` LexicalDeclaration[~In, ?Yield, ?Await] Expression[+In, ?Yield, ?Await]? `;` Expression[+In, ?Yield, ?Await]? `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` [lookahead != `let` `[`] LeftHandSideExpression[?Yield, ?Await] `in` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` `var` ForBinding[?Yield, ?Await] `in` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` ForDeclaration[?Yield, ?Await] `in` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` [lookahead != `let` ] LeftHandSideExpression[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` `var` ForBinding[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` ForDeclaration[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ [+Await] `for` `await` `(` [lookahead != `let` ] LeftHandSideExpression[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ [+Await] `for` `await` `(` `var` ForBinding[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ [+Await] `for` `await` `(` ForDeclaration[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+
+ForDeclaration[Yield, Await] :
+ LetOrConst ForBinding[?Yield, ?Await]
+
+ForBinding[Yield, Await] :
+ BindingIdentifier[?Yield, ?Await]
+ BindingPattern[?Yield, ?Await]
+
+
+ContinueStatement[Yield, Await] :
+ `continue` `;`
+ `continue` [no LineTerminator here] LabelIdentifier[?Yield, ?Await] `;`
+
+
+BreakStatement[Yield, Await] :
+ `break` `;`
+ `break` [no LineTerminator here] LabelIdentifier[?Yield, ?Await] `;`
+
+
+ReturnStatement[Yield, Await] :
+ `return` `;`
+ `return` [no LineTerminator here] Expression[+In, ?Yield, ?Await] `;`
+
+
+WithStatement[Yield, Await, Return] :
+ `with` `(` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+
+
+SwitchStatement[Yield, Await, Return] :
+ `switch` `(` Expression[+In, ?Yield, ?Await] `)` CaseBlock[?Yield, ?Await, ?Return]
+
+CaseBlock[Yield, Await, Return] :
+ `{` CaseClauses[?Yield, ?Await, ?Return]? `}`
+ `{` CaseClauses[?Yield, ?Await, ?Return]? DefaultClause[?Yield, ?Await, ?Return] CaseClauses[?Yield, ?Await, ?Return]? `}`
+
+CaseClauses[Yield, Await, Return] :
+ CaseClause[?Yield, ?Await, ?Return]
+ CaseClauses[?Yield, ?Await, ?Return] CaseClause[?Yield, ?Await, ?Return]
+
+CaseClause[Yield, Await, Return] :
+ `case` Expression[+In, ?Yield, ?Await] `:` StatementList[?Yield, ?Await, ?Return]?
+
+DefaultClause[Yield, Await, Return] :
+ `default` `:` StatementList[?Yield, ?Await, ?Return]?
+
+
+LabelledStatement[Yield, Await, Return] :
+ LabelIdentifier[?Yield, ?Await] `:` LabelledItem[?Yield, ?Await, ?Return]
+
+LabelledItem[Yield, Await, Return] :
+ Statement[?Yield, ?Await, ?Return]
+ FunctionDeclaration[?Yield, ?Await, ~Default]
+
+
+ThrowStatement[Yield, Await] :
+ `throw` [no LineTerminator here] Expression[+In, ?Yield, ?Await] `;`
+
+
+TryStatement[Yield, Await, Return] :
+ `try` Block[?Yield, ?Await, ?Return] Catch[?Yield, ?Await, ?Return]
+ `try` Block[?Yield, ?Await, ?Return] Finally[?Yield, ?Await, ?Return]
+ `try` Block[?Yield, ?Await, ?Return] Catch[?Yield, ?Await, ?Return] Finally[?Yield, ?Await, ?Return]
+
+Catch[Yield, Await, Return] :
+ `catch` `(` CatchParameter[?Yield, ?Await] `)` Block[?Yield, ?Await, ?Return]
+ `catch` Block[?Yield, ?Await, ?Return]
+
+Finally[Yield, Await, Return] :
+ `finally` Block[?Yield, ?Await, ?Return]
+
+CatchParameter[Yield, Await] :
+ BindingIdentifier[?Yield, ?Await]
+ BindingPattern[?Yield, ?Await]
+
+
+DebuggerStatement :
+ `debugger` `;`
+
+
+FunctionDeclaration[Yield, Await, Default] :
+ `function` BindingIdentifier[?Yield, ?Await] `(` FormalParameters[~Yield, ~Await] `)` `{` FunctionBody[~Yield, ~Await] `}`
+ [+Default] `function` `(` FormalParameters[~Yield, ~Await] `)` `{` FunctionBody[~Yield, ~Await] `}`
+
+FunctionExpression :
+ `function` BindingIdentifier[~Yield, ~Await]? `(` FormalParameters[~Yield, ~Await] `)` `{` FunctionBody[~Yield, ~Await] `}`
+
+UniqueFormalParameters[Yield, Await] :
+ FormalParameters[?Yield, ?Await]
+
+FormalParameters[Yield, Await] :
+ [empty]
+ FunctionRestParameter[?Yield, ?Await]
+ FormalParameterList[?Yield, ?Await]
+ FormalParameterList[?Yield, ?Await] `,`
+ FormalParameterList[?Yield, ?Await] `,` FunctionRestParameter[?Yield, ?Await]
+
+FormalParameterList[Yield, Await] :
+ FormalParameter[?Yield, ?Await]
+ FormalParameterList[?Yield, ?Await] `,` FormalParameter[?Yield, ?Await]
+
+FunctionRestParameter[Yield, Await] :
+ BindingRestElement[?Yield, ?Await]
+
+FormalParameter[Yield, Await] :
+ BindingElement[?Yield, ?Await]
+
+FunctionBody[Yield, Await] :
+ FunctionStatementList[?Yield, ?Await]
+
+FunctionStatementList[Yield, Await] :
+ StatementList[?Yield, ?Await, +Return]?
+
+
+ArrowFunction[In, Yield, Await] :
+ ArrowParameters[?Yield, ?Await] [no LineTerminator here] `=>` ConciseBody[?In]
+
+ArrowParameters[Yield, Await] :
+ BindingIdentifier[?Yield, ?Await]
+ CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] #parencover
+
+ConciseBody[In] :
+ [lookahead != `{` ] AssignmentExpression[?In, ~Yield, ~Await]
+ `{` FunctionBody[~Yield, ~Await] `}`
+
+
+ArrowFormalParameters[Yield, Await] :
+ `(` UniqueFormalParameters[?Yield, ?Await] `)`
+
+
+MethodDefinition[Yield, Await] :
+ PropertyName[?Yield, ?Await] `(` UniqueFormalParameters[~Yield, ~Await] `)` `{` FunctionBody[~Yield, ~Await] `}`
+ GeneratorMethod[?Yield, ?Await]
+ AsyncMethod[?Yield, ?Await]
+ AsyncGeneratorMethod[?Yield, ?Await]
+ `get` PropertyName[?Yield, ?Await] `(` `)` `{` FunctionBody[~Yield, ~Await] `}`
+ `set` PropertyName[?Yield, ?Await] `(` PropertySetParameterList `)` `{` FunctionBody[~Yield, ~Await] `}`
+
+PropertySetParameterList :
+ FormalParameter[~Yield, ~Await]
+
+
+GeneratorMethod[Yield, Await] :
+ `*` PropertyName[?Yield, ?Await] `(` UniqueFormalParameters[+Yield, ~Await] `)` `{` GeneratorBody `}`
+
+GeneratorDeclaration[Yield, Await, Default] :
+ `function` `*` BindingIdentifier[?Yield, ?Await] `(` FormalParameters[+Yield, ~Await] `)` `{` GeneratorBody `}`
+ [+Default] `function` `*` `(` FormalParameters[+Yield, ~Await] `)` `{` GeneratorBody `}`
+
+GeneratorExpression :
+ `function` `*` BindingIdentifier[+Yield, ~Await]? `(` FormalParameters[+Yield, ~Await] `)` `{` GeneratorBody `}`
+
+GeneratorBody :
+ FunctionBody[+Yield, ~Await]
+
+YieldExpression[In, Await] :
+ `yield`
+ `yield` [no LineTerminator here] AssignmentExpression[?In, +Yield, ?Await]
+ `yield` [no LineTerminator here] `*` AssignmentExpression[?In, +Yield, ?Await]
+
+
+AsyncGeneratorMethod[Yield, Await] :
+ `async` [no LineTerminator here] `*` PropertyName[?Yield, ?Await] `(` UniqueFormalParameters[+Yield, +Await] `)` `{` AsyncGeneratorBody `}`
+
+AsyncGeneratorDeclaration[Yield, Await, Default] :
+ `async` [no LineTerminator here] `function` `*` BindingIdentifier[?Yield, ?Await] `(` FormalParameters[+Yield, +Await] `)` `{` AsyncGeneratorBody `}`
+ [+Default] `async` [no LineTerminator here] `function` `*` `(` FormalParameters[+Yield, +Await] `)` `{` AsyncGeneratorBody `}`
+
+AsyncGeneratorExpression :
+ `async` [no LineTerminator here] `function` `*` BindingIdentifier[+Yield, +Await]? `(` FormalParameters[+Yield, +Await] `)` `{` AsyncGeneratorBody `}`
+
+AsyncGeneratorBody :
+ FunctionBody[+Yield, +Await]
+
+
+ClassDeclaration[Yield, Await, Default] :
+ `class` BindingIdentifier[?Yield, ?Await] ClassTail[?Yield, ?Await]
+ [+Default] `class` ClassTail[?Yield, ?Await]
+
+ClassExpression[Yield, Await] :
+ `class` BindingIdentifier[?Yield, ?Await]? ClassTail[?Yield, ?Await]
+
+ClassTail[Yield, Await] :
+ ClassHeritage[?Yield, ?Await]? `{` ClassBody[?Yield, ?Await]? `}`
+
+ClassHeritage[Yield, Await] :
+ `extends` LeftHandSideExpression[?Yield, ?Await]
+
+ClassBody[Yield, Await] :
+ ClassElementList[?Yield, ?Await]
+
+ClassElementList[Yield, Await] :
+ ClassElement[?Yield, ?Await]
+ ClassElementList[?Yield, ?Await] ClassElement[?Yield, ?Await]
+
+ClassElement[Yield, Await] :
+ MethodDefinition[?Yield, ?Await]
+ `static` MethodDefinition[?Yield, ?Await]
+ `;`
+
+
+AsyncFunctionDeclaration[Yield, Await, Default] :
+ `async` [no LineTerminator here] `function` BindingIdentifier[?Yield, ?Await] `(` FormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
+ [+Default] `async` [no LineTerminator here] `function` `(` FormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
+
+AsyncFunctionExpression :
+ `async` [no LineTerminator here] `function` `(` FormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
+ `async` [no LineTerminator here] `function` BindingIdentifier[~Yield, +Await] `(` FormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
+
+AsyncMethod[Yield, Await] :
+ `async` [no LineTerminator here] PropertyName[?Yield, ?Await] `(` UniqueFormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
+
+AsyncFunctionBody :
+ FunctionBody[~Yield, +Await]
+
+AwaitExpression[Yield] :
+ `await` UnaryExpression[?Yield, +Await]
+
+
+AsyncArrowFunction[In, Yield, Await] :
+ `async` [no LineTerminator here] AsyncArrowBindingIdentifier[?Yield] [no LineTerminator here] `=>` AsyncConciseBody[?In]
+ CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] [no LineTerminator here] `=>` AsyncConciseBody[?In] #callcover
+
+AsyncConciseBody[In] :
+ [lookahead != `{`] AssignmentExpression[?In, ~Yield, +Await]
+ `{` AsyncFunctionBody `}`
+
+AsyncArrowBindingIdentifier[Yield] :
+ BindingIdentifier[?Yield, +Await]
+
+CoverCallExpressionAndAsyncArrowHead[Yield, Await] :
+ MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]
+
+
+AsyncArrowHead :
+ `async` [no LineTerminator here] ArrowFormalParameters[~Yield, +Await]
+
+
+Script :
+ ScriptBody?
+
+ScriptBody :
+ StatementList[~Yield, ~Await, ~Return]
+
+
+Module :
+ ModuleBody?
+
+ModuleBody :
+ ModuleItemList
+
+ModuleItemList :
+ ModuleItem
+ ModuleItemList ModuleItem
+
+ModuleItem :
+ ImportDeclaration
+ ExportDeclaration
+ StatementListItem[~Yield, ~Await, ~Return]
+
+
+ImportDeclaration :
+ `import` ImportClause FromClause `;`
+ `import` ModuleSpecifier `;`
+
+ImportClause :
+ ImportedDefaultBinding
+ NameSpaceImport
+ NamedImports
+ ImportedDefaultBinding `,` NameSpaceImport
+ ImportedDefaultBinding `,` NamedImports
+
+ImportedDefaultBinding :
+ ImportedBinding
+
+NameSpaceImport :
+ `*` `as` ImportedBinding
+
+NamedImports :
+ `{` `}`
+ `{` ImportsList `}`
+ `{` ImportsList `,` `}`
+
+FromClause :
+ `from` ModuleSpecifier
+
+ImportsList :
+ ImportSpecifier
+ ImportsList `,` ImportSpecifier
+
+ImportSpecifier :
+ ImportedBinding
+ IdentifierName `as` ImportedBinding
+
+ModuleSpecifier :
+ StringLiteral
+
+ImportedBinding :
+ BindingIdentifier[~Yield, ~Await]
+
+
+ExportDeclaration :
+ `export` `*` FromClause `;`
+ `export` ExportClause FromClause `;`
+ `export` ExportClause `;`
+ `export` VariableStatement[~Yield, ~Await]
+ `export` Declaration[~Yield, ~Await]
+ `export` `default` HoistableDeclaration[~Yield, ~Await, +Default]
+ `export` `default` ClassDeclaration[~Yield, ~Await, +Default]
+ `export` `default` [lookahead <! {`function`, `async` [no |LineTerminator| here] `function`, `class`}] AssignmentExpression[+In, ~Yield, ~Await] `;`
+
+ExportClause :
+ `{` `}`
+ `{` ExportsList `}`
+ `{` ExportsList `,` `}`
+
+ExportsList :
+ ExportSpecifier
+ ExportsList `,` ExportSpecifier
+
+ExportSpecifier :
+ IdentifierName
+ IdentifierName `as` IdentifierName
+
+
+uri :::
+ uriCharacters?
+
+uriCharacters :::
+ uriCharacter uriCharacters?
+
+uriCharacter :::
+ uriReserved
+ uriUnescaped
+ uriEscaped
+
+uriReserved ::: one of
+ `;` `/` `?` `:` `@` `&` `=` `+` `$` `,`
+
+uriUnescaped :::
+ uriAlpha
+ DecimalDigit
+ uriMark
+
+uriEscaped :::
+ `%` HexDigit HexDigit
+
+uriAlpha ::: one of
+ `a` `b` `c` `d` `e` `f` `g` `h` `i` `j` `k` `l` `m` `n` `o` `p` `q` `r` `s` `t` `u` `v` `w` `x` `y` `z`
+ `A` `B` `C` `D` `E` `F` `G` `H` `I` `J` `K` `L` `M` `N` `O` `P` `Q` `R` `S` `T` `U` `V` `W` `X` `Y` `Z`
+
+uriMark ::: one of
+ `-` `_` `.` `!` `~` `*` `'` `(` `)`
+
+
+NativeFunction :
+ `function` PropertyName[~Yield, ~Await]? `(` FormalParameters[~Yield, ~Await] `)` `{` `[` `native` `code` `]` `}`
+
+
+Pattern[U, N] ::
+ Disjunction[?U, ?N]
+
+Disjunction[U, N] ::
+ Alternative[?U, ?N]
+ Alternative[?U, ?N] `|` Disjunction[?U, ?N]
+
+Alternative[U, N] ::
+ [empty]
+ Alternative[?U, ?N] Term[?U, ?N]
+
+Term[U, N] ::
+ Assertion[?U, ?N]
+ Atom[?U, ?N]
+ Atom[?U, ?N] Quantifier
+
+Assertion[U, N] ::
+ `^`
+ `$`
+ `\` `b`
+ `\` `B`
+ `(` `?` `=` Disjunction[?U, ?N] `)`
+ `(` `?` `!` Disjunction[?U, ?N] `)`
+ `(` `?` `<=` Disjunction[?U, ?N] `)`
+ `(` `?` `<!` Disjunction[?U, ?N] `)`
+
+Quantifier ::
+ QuantifierPrefix
+ QuantifierPrefix `?`
+
+QuantifierPrefix ::
+ `*`
+ `+`
+ `?`
+ `{` DecimalDigits `}`
+ `{` DecimalDigits `,` `}`
+ `{` DecimalDigits `,` DecimalDigits `}`
+
+Atom[U, N] ::
+ PatternCharacter
+ `.`
+ `\` AtomEscape[?U, ?N]
+ CharacterClass[?U]
+ `(` GroupSpecifier[?U] Disjunction[?U, ?N] `)`
+ `(` `?` `:` Disjunction[?U, ?N] `)`
+
+SyntaxCharacter :: one of
+ `^` `$` `\` `.` `*` `+` `?` `(` `)` `[` `]` `{` `}` `|`
+
+PatternCharacter ::
+ SourceCharacter but not SyntaxCharacter
+
+AtomEscape[U, N] ::
+ DecimalEscape
+ CharacterClassEscape[?U]
+ CharacterEscape[?U]
+ [+N] `k` GroupName[?U]
+
+CharacterEscape[U] ::
+ ControlEscape
+ `c` ControlLetter
+ `0` [lookahead <! DecimalDigit]
+ HexEscapeSequence
+ RegExpUnicodeEscapeSequence[?U]
+ IdentityEscape[?U]
+
+ControlEscape :: one of
+ `f` `n` `r` `t` `v`
+
+ControlLetter :: one of
+ `a` `b` `c` `d` `e` `f` `g` `h` `i` `j` `k` `l` `m` `n` `o` `p` `q` `r` `s` `t` `u` `v` `w` `x` `y` `z`
+ `A` `B` `C` `D` `E` `F` `G` `H` `I` `J` `K` `L` `M` `N` `O` `P` `Q` `R` `S` `T` `U` `V` `W` `X` `Y` `Z`
+
+GroupSpecifier[U] ::
+ [empty]
+ `?` GroupName[?U]
+
+GroupName[U] ::
+ `<` RegExpIdentifierName[?U] `>`
+
+RegExpIdentifierName[U] ::
+ RegExpIdentifierStart[?U]
+ RegExpIdentifierName[?U] RegExpIdentifierPart[?U]
+
+RegExpIdentifierStart[U] ::
+ UnicodeIDStart
+ `$`
+ `_`
+ `\` RegExpUnicodeEscapeSequence[?U]
+
+RegExpIdentifierPart[U] ::
+ UnicodeIDContinue
+ `$`
+ `\` RegExpUnicodeEscapeSequence[?U]
+ <ZWNJ>
+ <ZWJ>
+
+RegExpUnicodeEscapeSequence[U] ::
+ [+U] `u` LeadSurrogate `\u` TrailSurrogate
+ [+U] `u` LeadSurrogate
+ [+U] `u` TrailSurrogate
+ [+U] `u` NonSurrogate
+ [~U] `u` Hex4Digits
+ [+U] `u{` CodePoint `}`
+
+
+LeadSurrogate ::
+ Hex4Digits [> but only if the SV of |Hex4Digits| is in the inclusive range 0xD800 to 0xDBFF]
+
+TrailSurrogate ::
+ Hex4Digits [> but only if the SV of |Hex4Digits| is in the inclusive range 0xDC00 to 0xDFFF]
+
+NonSurrogate ::
+ Hex4Digits [> but only if the SV of |Hex4Digits| is not in the inclusive range 0xD800 to 0xDFFF]
+
+IdentityEscape[U] ::
+ [+U] SyntaxCharacter
+ [+U] `/`
+ [~U] SourceCharacter but not UnicodeIDContinue
+
+DecimalEscape ::
+ NonZeroDigit DecimalDigits? [lookahead <! DecimalDigit]
+
+CharacterClassEscape[U] ::
+ `d`
+ `D`
+ `s`
+ `S`
+ `w`
+ `W`
+ [+U] `p{` UnicodePropertyValueExpression `}`
+ [+U] `P{` UnicodePropertyValueExpression `}`
+
+UnicodePropertyValueExpression ::
+ UnicodePropertyName `=` UnicodePropertyValue
+ LoneUnicodePropertyNameOrValue
+
+UnicodePropertyName ::
+ UnicodePropertyNameCharacters
+
+UnicodePropertyNameCharacters ::
+ UnicodePropertyNameCharacter UnicodePropertyNameCharacters?
+
+UnicodePropertyValue ::
+ UnicodePropertyValueCharacters
+
+LoneUnicodePropertyNameOrValue ::
+ UnicodePropertyValueCharacters
+
+UnicodePropertyValueCharacters ::
+ UnicodePropertyValueCharacter UnicodePropertyValueCharacters?
+
+UnicodePropertyValueCharacter ::
+ UnicodePropertyNameCharacter
+ `0`
+ `1`
+ `2`
+ `3`
+ `4`
+ `5`
+ `6`
+ `7`
+ `8`
+ `9`
+
+UnicodePropertyNameCharacter ::
+ ControlLetter
+ `_`
+
+CharacterClass[U] ::
+ `[` [lookahead != `^`] ClassRanges[?U] `]`
+ `[` `^` ClassRanges[?U] `]`
+
+ClassRanges[U] ::
+ [empty]
+ NonemptyClassRanges[?U]
+
+NonemptyClassRanges[U] ::
+ ClassAtom[?U]
+ ClassAtom[?U] NonemptyClassRangesNoDash[?U]
+ ClassAtom[?U] `-` ClassAtom[?U] ClassRanges[?U]
+
+NonemptyClassRangesNoDash[U] ::
+ ClassAtom[?U]
+ ClassAtomNoDash[?U] NonemptyClassRangesNoDash[?U]
+ ClassAtomNoDash[?U] `-` ClassAtom[?U] ClassRanges[?U]
+
+ClassAtom[U] ::
+ `-`
+ ClassAtomNoDash[?U]
+
+ClassAtomNoDash[U] ::
+ SourceCharacter but not one of `\` or `]` or `-`
+ `\` ClassEscape[?U]
+
+ClassEscape[U] ::
+ `b`
+ [+U] `-`
+ CharacterClassEscape[?U]
+ CharacterEscape[?U]
+
+
+NumericLiteral ::
+ DecimalLiteral
+ BinaryIntegerLiteral
+ OctalIntegerLiteral
+ HexIntegerLiteral
+ LegacyOctalIntegerLiteral
+
+LegacyOctalIntegerLiteral ::
+ `0` OctalDigit
+ LegacyOctalIntegerLiteral OctalDigit
+
+DecimalIntegerLiteral ::
+ `0`
+ NonZeroDigit DecimalDigits?
+ NonOctalDecimalIntegerLiteral
+
+NonOctalDecimalIntegerLiteral ::
+ `0` NonOctalDigit
+ LegacyOctalLikeDecimalIntegerLiteral NonOctalDigit
+ NonOctalDecimalIntegerLiteral DecimalDigit
+
+LegacyOctalLikeDecimalIntegerLiteral ::
+ `0` OctalDigit
+ LegacyOctalLikeDecimalIntegerLiteral OctalDigit
+
+NonOctalDigit :: one of
+ `8` `9`
+
+
+EscapeSequence ::
+ CharacterEscapeSequence
+ LegacyOctalEscapeSequence
+ HexEscapeSequence
+ UnicodeEscapeSequence
+
+LegacyOctalEscapeSequence ::
+ OctalDigit [lookahead <! OctalDigit]
+ ZeroToThree OctalDigit [lookahead <! OctalDigit]
+ FourToSeven OctalDigit
+ ZeroToThree OctalDigit OctalDigit
+
+ZeroToThree :: one of
+ `0` `1` `2` `3`
+
+FourToSeven :: one of
+ `4` `5` `6` `7`
+
+
+Comment ::
+ MultiLineComment
+ SingleLineComment
+ SingleLineHTMLOpenComment
+ SingleLineHTMLCloseComment
+ SingleLineDelimitedComment
+
+MultiLineComment ::
+ `/*` FirstCommentLine? LineTerminator MultiLineCommentChars? `*/` HTMLCloseComment?
+
+FirstCommentLine ::
+ SingleLineDelimitedCommentChars
+
+SingleLineHTMLOpenComment ::
+ `<!--` SingleLineCommentChars?
+
+SingleLineHTMLCloseComment ::
+ LineTerminatorSequence HTMLCloseComment
+
+SingleLineDelimitedComment ::
+ `/*` SingleLineDelimitedCommentChars? `*/`
+
+HTMLCloseComment ::
+ WhiteSpaceSequence? SingleLineDelimitedCommentSequence? `-->` SingleLineCommentChars?
+
+SingleLineDelimitedCommentChars ::
+ SingleLineNotAsteriskChar SingleLineDelimitedCommentChars?
+ `*` SingleLinePostAsteriskCommentChars?
+
+SingleLineNotAsteriskChar ::
+ SourceCharacter but not one of `*` or LineTerminator
+
+SingleLinePostAsteriskCommentChars ::
+ SingleLineNotForwardSlashOrAsteriskChar SingleLineDelimitedCommentChars?
+ `*` SingleLinePostAsteriskCommentChars?
+
+SingleLineNotForwardSlashOrAsteriskChar ::
+ SourceCharacter but not one of `/` or `*` or LineTerminator
+
+WhiteSpaceSequence ::
+ WhiteSpace WhiteSpaceSequence?
+
+SingleLineDelimitedCommentSequence ::
+ SingleLineDelimitedComment WhiteSpaceSequence? SingleLineDelimitedCommentSequence?
+
+
+Term[U, N] ::
+ [+U] Assertion[+U, ?N]
+ [+U] Atom[+U, ?N]
+ [+U] Atom[+U, ?N] Quantifier
+ [~U] QuantifiableAssertion[?N] Quantifier
+ [~U] Assertion[~U, ?N]
+ [~U] ExtendedAtom[?N] Quantifier
+ [~U] ExtendedAtom[?N]
+
+Assertion[U, N] ::
+ `^`
+ `$`
+ `\` `b`
+ `\` `B`
+ [+U] `(` `?` `=` Disjunction[+U, ?N] `)`
+ [+U] `(` `?` `!` Disjunction[+U, ?N] `)`
+ [~U] QuantifiableAssertion[?N]
+ `(` `?` `<=` Disjunction[?U, ?N] `)`
+ `(` `?` `<!` Disjunction[?U, ?N] `)`
+
+QuantifiableAssertion[N] ::
+ `(` `?` `=` Disjunction[~U, ?N] `)`
+ `(` `?` `!` Disjunction[~U, ?N] `)`
+
+ExtendedAtom[N] ::
+ `.`
+ `\` AtomEscape[~U, ?N]
+ `\` [lookahead == `c`]
+ CharacterClass[~U]
+ `(` Disjunction[~U, ?N] `)`
+ `(` `?` `:` Disjunction[~U, ?N] `)`
+ InvalidBracedQuantifier
+ ExtendedPatternCharacter
+
+InvalidBracedQuantifier ::
+ `{` DecimalDigits `}`
+ `{` DecimalDigits `,` `}`
+ `{` DecimalDigits `,` DecimalDigits `}`
+
+ExtendedPatternCharacter ::
+ SourceCharacter but not one of `^` `$` `\` `.` `*` `+` `?` `(` `)` `[` `|`
+
+AtomEscape[U, N] ::
+ [+U] DecimalEscape
+ [~U] DecimalEscape [> but only if the CapturingGroupNumber of |DecimalEscape| is <= _NcapturingParens_]
+ CharacterClassEscape[?U]
+ CharacterEscape[~U, ?N]
+ [+N] `k` GroupName[?U]
+
+CharacterEscape[U, N] ::
+ ControlEscape
+ `c` ControlLetter
+ `0` [lookahead <! DecimalDigit]
+ HexEscapeSequence
+ RegExpUnicodeEscapeSequence[?U]
+ [~U] LegacyOctalEscapeSequence
+ IdentityEscape[?U, ?N]
+
+IdentityEscape[U, N] ::
+ [+U] SyntaxCharacter
+ [+U] `/`
+ [~U] SourceCharacterIdentityEscape[?N]
+
+SourceCharacterIdentityEscape[N] ::
+ [~N] SourceCharacter but not `c`
+ [+N] SourceCharacter but not one of `c` or `k`
+
+ClassAtomNoDash[U, N] ::
+ SourceCharacter but not one of `\` or `]` or `-`
+ `\` ClassEscape[?U, ?N]
+ `\` [lookahead == `c`]
+
+ClassEscape[U, N] ::
+ `b`
+ [+U] `-`
+ [~U] `c` ClassControlLetter
+ CharacterClassEscape[?U]
+ CharacterEscape[?U, ?N]
+
+ClassControlLetter ::
+ DecimalDigit
+ `_`
+
+
+IfStatement[Yield, Await, Return] :
+ `if` `(` Expression[+In, ?Yield, ?Await] `)` FunctionDeclaration[?Yield, ?Await, ~Default] `else` Statement[?Yield, ?Await, ?Return]
+ `if` `(` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return] `else` FunctionDeclaration[?Yield, ?Await, ~Default]
+ `if` `(` Expression[+In, ?Yield, ?Await] `)` FunctionDeclaration[?Yield, ?Await, ~Default] `else` FunctionDeclaration[?Yield, ?Await, ~Default]
+ `if` `(` Expression[+In, ?Yield, ?Await] `)` FunctionDeclaration[?Yield, ?Await, ~Default]
+
+
+IterationStatement[Yield, Await, Return] :
+ `for` `(` `var` BindingIdentifier[?Yield, ?Await] Initializer[~In, ?Yield, ?Await] `in` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+
diff --git a/third_party/rust/jsparagus/js_parser/esgrammar.pgen b/third_party/rust/jsparagus/js_parser/esgrammar.pgen
new file mode 100644
index 0000000000..7a0b4cb7b9
--- /dev/null
+++ b/third_party/rust/jsparagus/js_parser/esgrammar.pgen
@@ -0,0 +1,290 @@
+# Grammar for ECMArkup grammar descriptions
+
+var token CHR; # <NL>
+var token EQ; # ::
+var token MATCH_REF; # $0
+var token NL; # (actual newline character)
+var token NT; # IdentifierName
+var token NTALT; # |LineTerminator|
+var token NTCALL; # Expression (when followed by `[` or `<`)
+var token PRODID; # #comment
+var token PROSE; # > any text following a greater than sign
+var token T; # `var`
+var token WPROSE; # [> any text after greater than sign, wrapped in brackets]
+var token RUSTCOMMENT;# //comment
+
+token But = "but";
+token Empty = "empty";
+token Here = "here";
+token Lookahead = "lookahead";
+token No = "no";
+token Not = "not";
+token Of = "of";
+token One = "one";
+token Or = "or";
+token Through = "through";
+token Returns = "returns";
+token Some = "Some";
+token None = "None";
+token Arrow = "=>";
+token Comma = ",";
+token OpenBracket = "[";
+token CloseBracket = "]";
+token QuestionMark = "?";
+token Tilde = "~";
+token PlusSign = "+";
+token Equal = "=";
+token Equals = "==";
+token IsNotEqualTo = "!=";
+token IsNotIn = "<!";
+token OpenBrace = "{";
+token CloseBrace = "}";
+token OpenParen = "(";
+token CloseParen = ")";
+token AtSign = "@";
+token OpenAngle = "<";
+token CloseAngle = ">";
+token Impl = "impl";
+token For = "for";
+token Let = "let";
+token SemiColon = ";";
+token Lifetime = "'";
+
+// Entry point for grammar_extension! macro's content.
+goal nt rust_edsl {
+ rust_impl rust_nt_def_list => rust_edsl($0, $1);
+}
+
+nt rust_impl {
+ "impl" nt_type "for" nt_type "{" "}" ";" => rust_impl($1, $3);
+ "impl" "<" nt_type_params ">" nt_type "for" nt_type "{" "}" ";" => rust_param_impl($4, $6, $2);
+}
+
+nt rust_nt_def_list {
+ rust_nt_def_or_blank_line;
+ rust_nt_def_list rust_nt_def_or_blank_line => concat($0, $1);
+}
+
+nt rust_nt_def_or_blank_line {
+ NL => blank_line();
+ RUSTCOMMENT => blank_line();
+ rust_nt_def => nt_def_to_list($0);
+}
+
+// grammar extension syntax for adding/removing/extending the productions.
+nt rust_nt_def {
+ "let" nt_lhs "=" "{" rust_rhs_line "}" ";" => rust_nt_def($1, $4);
+}
+
+nt rust_rhs_line {
+ rust_symbols => rust_rhs_line($0);
+}
+
+nt rust_symbols {
+ rust_symbol;
+ rust_symbols rust_symbol => concat($0, $1);
+}
+
+nt rust_symbol {
+ "{" rust_expr "}" => single($1);
+ symbol => single($0);
+ NL => empty();
+}
+
+nt rust_expr {
+ expr => rust_expr($0);
+}
+
+// Entry point for esgrammar files.
+goal nt grammar {
+ nt_def_list;
+}
+
+nt nt_def_list {
+ nt_def_or_blank_line;
+ nt_def_list nt_def_or_blank_line => concat($0, $1);
+}
+
+nt nt_def_or_blank_line {
+ NL => blank_line();
+ nt_def => nt_def_to_list($0);
+}
+
+nt nt_def {
+ nt_type_line? nt_lhs EQ NL rhs_lines NL => nt_def($0, $1, $2, $4);
+ nt_type_line? nt_lhs EQ "one" "of" NL t_list_lines NL => nt_def_one_of($0, $1, $2, $6);
+}
+
+nt nt_lhs {
+ NT => nt_lhs_no_params($0);
+ NTCALL "[" params "]" => nt_lhs_with_params($0, $2);
+}
+
+nt params {
+ param => single($0);
+ params "," param => append($0, $2);
+}
+
+nt param {
+ NT;
+}
+
+nt nt_type_line {
+ "@" "returns" nt_type NL => $2;
+}
+
+// Define a type as understood by Rust type-system.
+nt nt_type {
+ NT => simple_type($0);
+ NTCALL "<" nt_type_params ">" => parameterized_type($0, $2);
+}
+
+nt nt_type_params {
+ nt_type_param => single($0);
+ nt_type_params "," nt_type_param => append($0, $2);
+}
+
+nt nt_type_param {
+ nt_type;
+ "'" NT => lifetime_type($0);
+}
+
+nt t_list_lines {
+ t_list_line;
+ t_list_lines t_list_line => concat($0, $1);
+}
+
+nt t_list_line {
+ terminal_seq NL => t_list_line($0);
+}
+
+nt terminal_seq {
+ terminal => single($0);
+ terminal_seq terminal => append($0, $1);
+}
+
+nt terminal {
+ T => terminal($0);
+ CHR => chr($0);
+}
+
+nt rhs_lines {
+ rhs_line => single($0);
+ rhs_lines rhs_line => append($0, $1);
+}
+
+nt rhs_line {
+ ifdef? rhs reducer? PRODID? NL => rhs_line($0, $1, $2, $3);
+ PROSE NL => rhs_line_prose($0);
+}
+
+nt rhs {
+ symbols;
+ "[" "empty" "]" => empty_rhs();
+}
+
+nt reducer {
+ NL? "=>" expr => $2;
+}
+
+nt expr {
+ MATCH_REF => expr_match_ref($0);
+ NT "(" expr_args? ")" expr_try? => expr_call($0, $2, $4);
+ "Some" "(" expr ")" => expr_some($2);
+ "None" => expr_none();
+}
+
+nt expr_try {
+ "?";
+}
+
+nt expr_args {
+ expr => single($0);
+ expr_args "," expr => append($0, $2);
+}
+
+nt ifdef {
+ "[" definite_sigil NT "]" => ifdef($1, $2);
+}
+
+nt symbols {
+ symbol => single($0);
+ symbols symbol => append($0, $1);
+}
+
+nt symbol {
+ terminal;
+ nonterminal;
+ nonterminal "?" => optional($0);
+ nonterminal "but" "not" exclusion => but_not($0, $3);
+ nonterminal "but" "not" "one" "of" exclusion_list => but_not_one_of($0, $5);
+ "[" "lookahead" lookahead_assertion "]" => $2;
+ no_line_terminator_here;
+ WPROSE => $0;
+}
+
+nt no_line_terminator_here {
+ "[" "no" line_terminator "here" "]" => no_line_terminator_here($2);
+}
+
+nt nonterminal {
+ NT => nonterminal($0);
+ NTCALL "[" args "]" => nonterminal_apply($0, $2);
+}
+
+nt args {
+ arg => single($0);
+ args "," arg => append($0, $2);
+}
+
+nt arg {
+ sigil NT => arg_expr($0, $1);
+}
+
+nt sigil {
+ definite_sigil;
+ "?";
+}
+
+nt definite_sigil {
+ "~" => sigil_false();
+ "+" => sigil_true();
+}
+
+nt exclusion_list {
+ exclusion => single($0);
+ exclusion_list "or" exclusion => append($0, $2);
+}
+
+nt exclusion {
+ terminal => exclusion_terminal($0);
+ nonterminal => exclusion_nonterminal($0);
+ CHR "through" CHR => exclusion_chr_range($0, $2);
+}
+
+nt lookahead_assertion {
+ "==" terminal => la_eq($1);
+ "!=" terminal => la_ne($1);
+ "<!" NT => la_not_in_nonterminal($1);
+ "<!" "{" lookahead_exclusions "}" => la_not_in_set($2);
+}
+
+nt lookahead_exclusions {
+ lookahead_exclusion => single($0);
+ lookahead_exclusions "," lookahead_exclusion => append($0, $2);
+}
+
+nt lookahead_exclusion {
+ lookahead_exclusion_element => single($0);
+ lookahead_exclusion lookahead_exclusion_element => append($0, $1);
+}
+
+nt lookahead_exclusion_element {
+ terminal;
+ no_line_terminator_here;
+}
+
+nt line_terminator {
+ NT;
+ NTALT;
+}
diff --git a/third_party/rust/jsparagus/js_parser/extract_es_grammar.py b/third_party/rust/jsparagus/js_parser/extract_es_grammar.py
new file mode 100755
index 0000000000..b1fc35473f
--- /dev/null
+++ b/third_party/rust/jsparagus/js_parser/extract_es_grammar.py
@@ -0,0 +1,567 @@
+"""extract_es_grammar.py - Extract the grammar from the ECMAScript spec
+
+To run this script, you first need to get the source of the version of
+the ECMAScript spec you're interested in.
+
+ cd ../..
+ mkdir tc39
+ cd tc39
+ git clone git@github.com:tc39/ecma262.git
+
+Then:
+
+ make js_parser/es.esgrammar
+
+You can also use this script on a random HTTPS URL, like:
+
+ URL=https://raw.githubusercontent.com/tc39/proposal-class-fields/master/spec.html
+ python extract_esgrammar.py $URL
+
+"""
+
+import argparse
+import urllib
+import html5lib # type: ignore
+import re
+from textwrap import dedent
+
+
+HTML = "{http://www.w3.org/1999/xhtml}"
+INS_TAG = HTML + "ins"
+DEL_TAG = HTML + "del"
+
+INS = '+'
+DEL = '-'
+KEEP = ' '
+
+
+def pre_with_code_filter_factory(e):
+ """Checks if the <pre> is used in the following pattern:
+
+ ```
+ <pre><code>
+ </code></pre>
+ ```
+
+ If so, return a filter that formats the content, removing extra spaces.
+ line-wrap, and backquote added by <code>.
+
+ """
+ if e.text and e.text.strip() != '':
+ return False
+
+ if len(e) != 1:
+ return False
+
+ if e[0].tag != '{http://www.w3.org/1999/xhtml}code':
+ return False
+
+ if e[0].tail and e[0].tail.strip() != '':
+ return False
+
+ def children_filter(texts):
+ while len(texts) > 0 and texts[0].strip() == '':
+ texts.pop(0)
+ if len(texts) > 0 and texts[0].strip() == '`':
+ texts.pop(0)
+ while len(texts) > 0 and texts[0].strip() == '':
+ texts.pop(0)
+
+ while len(texts) > 0 and texts[-1].strip() == '':
+ texts.pop()
+ if len(texts) > 0 and texts[-1].strip() == '`':
+ texts.pop()
+ while len(texts) > 0 and texts[-1].strip() == '':
+ texts.pop()
+
+ is_first = True
+ for text in texts:
+ for line in text.split('\n'):
+ line = line.strip()
+ if line == '':
+ continue
+
+ if not is_first:
+ yield '\n'
+ is_first = False
+
+ yield line
+
+ return children_filter
+
+
+# Rules for extracting text, used by extracting Early Errors.
+EXTRA_RULES_FOR_EE = {
+ 'b': {},
+ 'br': {},
+ 'code': {
+ 'prefix': '`',
+ 'postfix': '`',
+ },
+ 'emu-alg': {},
+ 'emu-grammar': {},
+ 'emu-note': {
+ 'prefix': ['NOTE', '\n'],
+ 'strip': True,
+ },
+ 'emu-xref': {
+ 'prefix': lambda e: e.attrib.get('href'),
+ },
+ 'ins': {
+ 'ignore_highlighted': True,
+ },
+ 'p': {
+ 'strip': True,
+ },
+ 'pre': {
+ 'prefix': ['\n', '\n', '```', '\n'],
+ 'postfix': ['\n', '```', '\n', '\n'],
+ 'strip': True,
+ 'children_filter_factroy': pre_with_code_filter_factory,
+ },
+ 'sub': {
+ 'prefix': '_',
+ },
+ 'sup': {
+ 'prefix': '^',
+ },
+}
+
+
+def apply_prefix_postfix_rule(e, rule, name):
+ """If rule is provided, apply prefix/postfix rule to the element `e`.
+ """
+ if not rule:
+ return
+
+ fix = rule.get(name)
+ if callable(fix):
+ yield fix(e)
+ elif isinstance(fix, list):
+ for item in fix:
+ yield item
+ elif fix:
+ yield fix
+
+
+def apply_strip_rule(text, rule):
+ """If rule is provided, apply strip rule to the text.
+ """
+ if not text:
+ return
+
+ if not rule:
+ yield text
+ return
+
+ strip = rule.get('strip')
+ if strip:
+ yield text.strip()
+ else:
+ yield text
+
+
+def fragment_child_chunks(e, extra_rules={}):
+ """Partly interpret the content of `e`, yielding `text`,
+ applying extra_rules.
+
+ Concatenating the yielded `text` values gives the full text of `e`.
+ """
+ rule = extra_rules[e.tag.replace(HTML, '')]
+
+ children_filter = None
+ factroy = rule.get('children_filter_factroy')
+ if factroy:
+ children_filter = factroy(e)
+
+ yield from apply_prefix_postfix_rule(e, rule, 'prefix')
+ yield from apply_strip_rule(e.text, rule)
+
+ for child in e:
+ if child.tag.replace(HTML, '') not in extra_rules:
+ raise ValueError("unrecognized element: " + child.tag)
+
+ texts = []
+ for text in fragment_child_chunks(child, extra_rules):
+ if children_filter:
+ texts.append(text)
+ else:
+ yield text
+
+ if children_filter:
+ for text in children_filter(texts):
+ yield text
+
+ yield from apply_strip_rule(e.tail, rule)
+ yield from apply_prefix_postfix_rule(e, rule, 'postfix')
+
+
+def is_highlighted_ins(e):
+ """Returns True if e matches the following pattern:
+
+ <ins>highlighted</ins> text:
+
+ See `fragment_chunks` comment for the details
+ """
+ if len(e) != 0:
+ return False
+
+ if not e.text:
+ return False
+
+ if e.text != 'highlighted':
+ return False
+
+ if not e.tail:
+ return False
+
+ if not e.tail.startswith(' text:'):
+ return False
+
+ return True
+
+
+def is_negligible_ins(e, extra_rules):
+ """Returns True if the 'ignore_highlighted' rule is defined for <ins>,
+ and it matches to the negligible pattern.
+
+ See `fragment_chunks` comment for the details
+ """
+
+ rule = extra_rules.get(e.tag.replace(HTML, ''))
+ if not rule:
+ return False
+
+ if rule.get('ignore_highlighted'):
+ if is_highlighted_ins(e):
+ return True
+
+ return False
+
+
+def fragment_chunks(e, extra_rules={}):
+ """Partly interpret the content of `e`, yielding pairs (ty, text).
+
+ If `extra_rules` isn't provided, the content of `e` must be text with 0
+ or more <ins>/<del> elements.
+
+ The goal is to turn the tree `e` into a simple series of tagged strings.
+
+ Yields pairs (ty, text) where ty in (INS, DEL, KEEP). Concatenating the
+ yielded `text` values gives the full text of `e`.
+
+ `extra_rules` is a dictionary that defines extra elements that is allowed
+ as the content of `e`.
+ Each item defines a rule for the tag, with the following:
+ * prefix
+ Put a prefix before the text
+ Possible values:
+ * string
+ * list of string
+ * function
+ receives `Element` and returns a prefix string
+ * postfix
+ Put a postfix after the text
+ value uses the same format as prefix
+ * strip
+ True to strip whitespaces before/after element's text
+ * children_filter_factroy
+ A function that receives `Element`, and returns a filter function or None
+ The filter function receives a list of texts for child nodes, and
+ returns a list of filtered text
+ * ignore_highlighted
+ Effective only with <ins>
+ Do not treat <ins> as an insertion if it matches the following pattern:
+
+ <ins>highlighted</ins> text:
+
+ This pattern is used in Annex B description.
+ """
+
+ rule = extra_rules.get(e.tag.replace(HTML, ''))
+
+ for text in apply_prefix_postfix_rule(e, rule, 'prefix'):
+ yield KEEP, text
+ for text in apply_strip_rule(e.text, rule):
+ yield KEEP, text
+
+ for child in e:
+ if child.tag == INS_TAG and not is_negligible_ins(child, extra_rules):
+ ty = INS
+ elif child.tag == DEL_TAG:
+ ty = DEL
+ else:
+ if child.tag.replace(HTML, '') not in extra_rules:
+ raise ValueError("unrecognized element: " + child.tag)
+
+ for text in fragment_child_chunks(child, extra_rules):
+ yield KEEP, text
+ continue
+
+ if child.text:
+ yield ty, child.text
+ if len(child) != 0:
+ for grandchild in child:
+ if grandchild.tag.replace(HTML, '') not in extra_rules:
+ raise ValueError("unsupported nested element {} in {}"
+ .format(grandchild.tag, child.tag))
+
+ for text in fragment_child_chunks(grandchild, extra_rules):
+ yield ty, text
+ if child.tail:
+ yield KEEP, child.tail
+
+ for text in apply_strip_rule(e.tail, rule):
+ yield KEEP, text
+ for text in apply_prefix_postfix_rule(e, rule, 'postfix'):
+ yield KEEP, text
+
+
+def fragment_parts(e, **kwargs):
+ """Like fragment_chunks, but with two fixups.
+
+ 1. Break up pairs that include both a newline and any other text.
+
+ 2. Move newlines inside of a preceding INS or DEL element that spans its
+ whole line.
+ """
+ line_has_ins = False
+ line_has_del = False
+ for chunk_ty, text in fragment_chunks(e, **kwargs):
+ for piece in re.split(r'(\n)', text):
+ ty = chunk_ty
+ if piece != '':
+ if piece == '\n':
+ # Possibly move newline inside preceding INS or DEL.
+ if line_has_ins and not line_has_del:
+ ty = INS
+ elif line_has_del and not line_has_ins:
+ ty = DEL
+ else:
+ ty = KEEP
+ line_has_del = False
+ line_has_ins = False
+ elif piece.strip() != '':
+ if ty in (INS, KEEP):
+ line_has_ins = True
+ if ty in (DEL, KEEP):
+ line_has_del = True
+ yield ty, piece
+
+
+def generate_fragment_patch(e, **kwargs):
+ line_before = ''
+ line_after = ''
+
+ def end_line(ty):
+ nonlocal line_before, line_after
+ if line_before.rstrip() == line_after.rstrip():
+ yield " ", line_after
+ else:
+ if line_before.strip() != '' or ty != INS:
+ yield "-", line_before
+ if line_after.strip() != '' or ty != DEL:
+ yield "+", line_after
+ line_before = ''
+ line_after = ''
+
+ for ty, text in fragment_parts(e, **kwargs):
+ if text == '\n':
+ yield from end_line(ty)
+ else:
+ if ty in (KEEP, DEL):
+ line_before += text
+ if ty in (KEEP, INS):
+ line_after += text
+ if line_before or line_after:
+ yield from end_line(KEEP)
+
+
+def dedent_pairs(pairs):
+ """Dedent the `pairs`'s `text` part
+ """
+ pairs = list(pairs)
+
+ # Using textwrap.dedent on this requires a few lines of hackery.
+ types = [ty for ty, _line in pairs]
+ dedented_lines = dedent(''.join(line + '\n' for ty, line in pairs)).splitlines()
+ assert len(dedented_lines) == len(pairs)
+
+ return zip(types, dedented_lines)
+
+
+def print_pairs(pairs):
+ last_line_was_empty = False
+
+ for ty, line in pairs:
+ if ty == KEEP and line == '':
+ if last_line_was_empty:
+ continue
+ last_line_was_empty = True
+ else:
+ last_line_was_empty = False
+
+ print(ty + line)
+
+
+def print_fragment_patch(e):
+ print_pairs(dedent_pairs(generate_fragment_patch(e)))
+
+
+def is_annex_early_errors(e):
+ """Returns True if the <emu-annex> element contains Early Errors.
+ """
+ h1 = e.find('{http://www.w3.org/1999/xhtml}h1')
+ if 'Early Errors' in h1.text:
+ return True
+
+ p = e.find('{http://www.w3.org/1999/xhtml}p')
+ if p:
+ if 'Early Error' in html5lib.serializer.serialize(p):
+ return True
+
+ return False
+
+
+def get_parent_map(document):
+ """Returns a map from a element to parent element.
+ This is necessary because `xml.etree.ElementTree.Element` doesn't have
+ a reference to parent element.
+ """
+ parent_map = dict()
+ for parent in document.iter():
+ for child in parent:
+ parent_map[child] = parent
+ return parent_map
+
+
+def get_titles(parent_map, e):
+ """Returns a list of section titles for a section.
+ """
+ titles = []
+ while e.tag != '{http://www.w3.org/1999/xhtml}body':
+ h1 = e.find('{http://www.w3.org/1999/xhtml}h1')
+ titles.insert(0, h1.text)
+ e = parent_map[e]
+
+ return titles
+
+
+def generate_ul_fragment_patch(e, depth):
+ """Similar to generate_fragment_patch, but for <ul>
+ """
+ first_line_prefix = '{}* '.format(' ' * depth)
+ other_line_prefix = '{} '.format(' ' * depth)
+
+ for item in e:
+ if item.tag != '{http://www.w3.org/1999/xhtml}li':
+ raise ValueError("unrecognized element: " + item.tag)
+
+ pairs = generate_fragment_patch(item,
+ extra_rules=EXTRA_RULES_FOR_EE)
+
+ is_first_line = True
+
+ for ty, line in dedent_pairs(pairs):
+ if is_first_line and line.strip() == '':
+ continue
+
+ if is_first_line:
+ is_first_line = False
+ yield ty, '{}{}'.format(first_line_prefix, line.strip())
+ else:
+ yield ty, '{}{}'.format(other_line_prefix, line.strip())
+
+
+def generate_early_errors_fragment_patch(parent_map, e):
+ for t in get_titles(parent_map, e):
+ yield KEEP, '# {}'.format(t)
+ yield KEEP, '# #{}'.format(e.attrib.get('id'))
+ yield KEEP, ''
+
+ for child in e:
+ if child.tag == '{http://www.w3.org/1999/xhtml}h1':
+ continue
+
+ if child.tag == '{http://www.w3.org/1999/xhtml}emu-grammar':
+ pairs = generate_fragment_patch(child)
+ yield from dedent_pairs(pairs)
+ yield KEEP, ''
+ elif child.tag == '{http://www.w3.org/1999/xhtml}ul':
+ yield from generate_ul_fragment_patch(child, 0)
+ elif child.tag == '{http://www.w3.org/1999/xhtml}emu-note':
+ pairs = generate_fragment_patch(child,
+ extra_rules=EXTRA_RULES_FOR_EE)
+ yield from dedent_pairs(pairs)
+ yield KEEP, ''
+ elif child.tag == '{http://www.w3.org/1999/xhtml}p':
+ pairs = generate_fragment_patch(child,
+ extra_rules=EXTRA_RULES_FOR_EE)
+ yield from dedent_pairs(pairs)
+ yield KEEP, ''
+ elif (child.tag == '{http://www.w3.org/1999/xhtml}emu-alg'
+ and e.attrib.get('id') == 'sec-__proto__-property-names-in-object-initializers'):
+ # "__proto__ Property Names in Object Initializers" section
+ # contains changes both for early errors and algorithm.
+ # Ignore algorithm part.
+ pass
+ else:
+ raise ValueError('unsupported element in early errors section: {}'
+ .format(child.tag))
+
+
+def print_early_errors(parent_map, e):
+ pairs = generate_early_errors_fragment_patch(parent_map, e)
+ print_pairs(dedent_pairs(pairs))
+
+
+def extract(filename, unfiltered, target):
+ if filename.startswith("https:"):
+ file_obj = urllib.request.urlopen(filename)
+ else:
+ file_obj = open(filename, "rb")
+
+ with file_obj:
+ document = html5lib.parse(file_obj)
+
+ if target == 'grammar':
+ for e in document.iter("{http://www.w3.org/1999/xhtml}emu-grammar"):
+ if unfiltered or e.attrib.get("type") == "definition":
+ print_fragment_patch(e)
+ elif target == 'ee':
+ parent_map = get_parent_map(document)
+ for e in document.iter("{http://www.w3.org/1999/xhtml}emu-clause"):
+ if e.attrib.get("id").endswith("-early-errors"):
+ print_early_errors(parent_map, e)
+ elif target == 'ee-annex':
+ parent_map = get_parent_map(document)
+ for e in document.iter("{http://www.w3.org/1999/xhtml}emu-annex"):
+ if is_annex_early_errors(e):
+ print_early_errors(parent_map, e)
+ else:
+ raise ValueError('Unknown target: {}'.format(target))
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(
+ description="Extract esgrammar from ECMAScript specifications.")
+ parser.add_argument(
+ 'url',
+ nargs=1,
+ help="the https: url or local filename of an HTML file containing <emu-grammar> tags")
+ parser.add_argument(
+ '--unfiltered',
+ action='store_true',
+ help="Include even <emu-grammar> elements that don't have `type=definition`")
+ parser.add_argument(
+ '--target',
+ default='grammar',
+ choices=['grammar', 'ee', 'ee-annex'],
+ help="What to extract (\
+ grammar = esgrammar, \
+ ee = early errors, \
+ ee-annex = early errors in Annex\
+ )")
+
+ args = parser.parse_args()
+ extract(args.url[0], args.unfiltered, args.target)
diff --git a/third_party/rust/jsparagus/js_parser/generate_js_parser_tables.py b/third_party/rust/jsparagus/js_parser/generate_js_parser_tables.py
new file mode 100755
index 0000000000..f85f7aca86
--- /dev/null
+++ b/third_party/rust/jsparagus/js_parser/generate_js_parser_tables.py
@@ -0,0 +1,140 @@
+"""generate_js_parser_tables.py - Generate tables from the ES grammar."""
+
+import argparse
+import os
+import jsparagus.gen
+import jsparagus.grammar
+from . import load_es_grammar
+
+
+def hack_grammar(g):
+ # We throw away most of the boolean parameters in the grammar, as the
+ # current parser generator's approach of fully expanding them is a huge
+ # pain.
+
+ PARAM_WHITELIST = ['In', 'Default']
+
+ def filter_params(params):
+ return tuple(p for p in params if p in PARAM_WHITELIST)
+
+ def filter_args(args):
+ return tuple(pair for pair in args if pair[0] in PARAM_WHITELIST)
+
+ def filter_element(e):
+ """ Strip nt arguments. """
+ if isinstance(e, jsparagus.grammar.Nt):
+ return jsparagus.grammar.Nt(e.name, filter_args(e.args))
+ elif isinstance(e, jsparagus.grammar.Optional):
+ return jsparagus.grammar.Optional(filter_element(e.inner))
+ else:
+ return e
+
+ def filter_condition(c):
+ if c is None or c[0] not in PARAM_WHITELIST:
+ return None
+ return c
+
+ def filter_production(p):
+ """ Discard production conditions and nt arguments. """
+ body = [filter_element(e) for e in p.body]
+ return jsparagus.grammar.Production(body, p.reducer,
+ condition=filter_condition(p.condition))
+
+ nonterminals = {}
+ for nt, nt_def in g.nonterminals.items():
+ params = tuple(filter_params(nt_def.params))
+ rhs_list = [filter_production(p) for p in nt_def.rhs_list]
+ nonterminals[nt] = jsparagus.grammar.NtDef(params, rhs_list, nt_def.type)
+ return g.with_nonterminals(nonterminals)
+
+
+def main():
+ # Read command-line options.
+ parser = argparse.ArgumentParser(
+ description='Ponder the ECMAScript grammar.',
+ allow_abbrev=False)
+ default_filename = os.path.join(os.path.dirname(__file__),
+ "es-simplified.esgrammar")
+ parser.add_argument(
+ 'filename', metavar='FILE', nargs='?', default=default_filename,
+ help=".esgrammar (or .jsparagus_dump) input file")
+ parser.add_argument(
+ 'handler_info', metavar='HANDLER_INFO', nargs='?',
+ help="JSON file that contains information about handler")
+ parser.add_argument(
+ '-e', '--extend', action='append', default=[],
+ help="name of a files which contains a grammar_extension Rust macro.")
+ parser.add_argument(
+ '-o', '--output', metavar='FILE', default='/dev/stdout',
+ help="output filename for parser tables")
+ parser.add_argument(
+ '-v', '--verbose', action='store_true',
+ help="print some debug output")
+ parser.add_argument(
+ '--progress', action='store_true',
+ help="print a dot each time a state is analyzed (thousands of them)")
+ parser.add_argument(
+ '--debug', action='store_true',
+ help="annotate the generated code with grammar productions")
+ args = parser.parse_args()
+
+ # Check filenames.
+ in_filename = args.filename
+ if in_filename.endswith('.esgrammar'):
+ from_source = True
+ elif in_filename.endswith('.jsparagus_dump'):
+ from_source = False
+ else:
+ raise ValueError("input file extension should be .esgrammar or .jsparagus_dump")
+
+ out_filename = args.output
+ if out_filename.endswith('.py'):
+ target = 'python'
+ elif out_filename.endswith('.rs'):
+ target = 'rust'
+ elif out_filename.endswith('.jsparagus_dump'):
+ target = 'dump'
+ else:
+ raise ValueError("-o file extension should be .py, .rs, or .jsparagus_dump")
+
+ in_extend = args.extend
+ if from_source:
+ assert all(f.endswith('.rs') for f in in_extend), "Extension are only supposed to be Rust files."
+ else:
+ assert in_extend == [], "Cannot add extensions to the generated parse table."
+
+ # Load input and analyze it.
+ if from_source:
+ grammar = load_es_grammar.load_syntactic_grammar(in_filename, in_extend)
+ grammar = hack_grammar(grammar)
+ if args.verbose:
+ grammar.dump()
+
+ states = jsparagus.gen.generate_parser_states(
+ grammar, verbose=args.verbose, progress=args.progress)
+ else:
+ states = jsparagus.gen.ParseTable.load(in_filename)
+
+ # Generate output.
+ try:
+ if target in ('python', 'rust'):
+ with open(out_filename, 'w') as f:
+ jsparagus.gen.generate_parser(f, states,
+ target=target,
+ verbose=args.verbose,
+ debug=args.debug,
+ handler_info=args.handler_info)
+ else:
+ assert target == 'dump'
+ states.save(out_filename)
+ except Exception:
+ # On failure, don't leave a partial output file lying around.
+ try:
+ os.remove(out_filename)
+ except Exception:
+ pass
+ raise
+
+
+if __name__ == '__main__':
+ main()
diff --git a/third_party/rust/jsparagus/js_parser/lexer.py b/third_party/rust/jsparagus/js_parser/lexer.py
new file mode 100644
index 0000000000..2d8ed530ed
--- /dev/null
+++ b/third_party/rust/jsparagus/js_parser/lexer.py
@@ -0,0 +1,315 @@
+"""Vague approximation of an ECMAScript lexer.
+
+A parser has two levels: the *lexer* scans bytes to produce tokens. The
+*parser* consumes tokens and produces ASTs.
+
+In a traditional design, the parser drives the process. It *pulls* one token at
+a time from the lexer. However, for a parser that can accept arbitrary slabs of
+data, scan them, then keep going, it makes more sense for the user to feed
+those slabs to the lexer, which then *pushes* tokens to the parser. So that's
+what we do.
+
+Usage:
+
+ from js_parser.lexer import JSLexer
+ from js_parser.parser import JSParser
+
+ lexer = JSLexer(JSParser())
+ lexer.write(some_source_text)
+ lexer.write(some_more_source_text)
+ ast = lexer.close()
+"""
+
+import re
+import jsparagus.lexer
+
+
+def _get_punctuators():
+ punctuators = '''
+ &&= ||= ??=
+ { ( ) [ ] . ... ; , < > <= >= == != === !== + - * % ** ++ --
+ << >> >>> & | ^ ! ~ && || ? : = += -= *= %=
+ **= ><<= >>= >>>= &= |= ^= =>
+ '''.split()
+
+ return '|'.join(
+ re.escape(token)
+ for token in sorted(punctuators, key=len, reverse=True))
+
+
+TOKEN_RE = re.compile(r'''(?x)
+ (?:
+ # WhiteSpace
+ [\ \t\v\r\n\u00a0\u2028\u2029\ufeff]
+ # SingleLineComment
+ | // [^\r\n\u2028\u2029]* (?= [\r\n\u2028\u2029] | \Z )
+ # MultiLineComment
+ | /\* (?: [^*] | \*+[^/] )* \*+/
+ )*
+ (
+ # Incomplete MultiLineComment
+ /\* (?: [^*] | \*+[^/] )* \**
+ | # Incomplete SingleLineComment
+ // [^\r\n\u2028\u2029]*
+ | # IdentifierName
+ (?: [$_A-Za-z] | \\ u [0-9A-Fa-f]{4} | \\ u \{ [0-9A-Fa-f]+ \})
+ (?: [$_0-9A-Za-z] | \\ u [0-9A-Fa-f]{4} | \\ u \{ [0-9A-Fa-f]+ \})*
+ | # NumericLiteral
+ [0-9][0-9A-Za-z]*(?:\.[0-9A-Za-z]*)?
+ | \.[0-9][0-9A-Za-z]*
+ | # Punctuator
+ <INSERT_PUNCTUATORS>
+ | # The slash special case
+ /
+ | # The curly brace special case
+ }
+ | # StringLiteral
+ '
+ # SingleStringCharacters
+ (?:
+ # SourceCharacter but not one of ' or \\ or LineTerminator
+ # but also allow LINE SEPARATOR or PARAGRAPH SEPARATOR
+ [^'\\\r\n]
+ | \\ [^0-9xu\r\n\u2028\u2029] # CharacterEscapeSequence
+ | \\ x [0-9A-Fa-f]{2} # HexEscapeSequence
+ | \\ u [0-9A-Fa-f]{4} # UnicodeEscapeSequence
+ | \\ u \{ [0-9A-Fa-f]+ \}
+ | \\\r\n? # LineContinuation
+ | \\[\n\u2028\u2029]
+ )*
+ '
+ | "
+ # DoubleStringCharacters
+ (?:
+ # SourceCharacter but not one of " or \\ or LineTerminator
+ # but also allow LINE SEPARATOR or PARAGRAPH SEPARATOR
+ [^"\\\r\n]
+ | \\ [^0-9xu\r\n\u2028\u2029] # CharacterEscapeSequence
+ | \\ x [0-9A-Fa-f]{2} # HexEscapeSequence
+ | \\ u [0-9A-Fa-f]{4} # UnicodeEscapeSequence
+ | \\ u \{ [0-9A-Fa-f]+ \}
+ | \\\r\n? # LineContinuation
+ | \\[\n\u2028\u2029]
+ )*
+ "
+ | # Template
+ ` (?: [^`\\$] | \\. )* (?: \${ | ` )
+ | # illegal character or end of input (this branch matches no characters)
+ )
+'''.replace("<INSERT_PUNCTUATORS>", _get_punctuators()))
+
+DIV_RE = re.compile(r'(/=?)')
+
+REGEXP_RE = re.compile(r'''(?x)
+(
+ /
+ (?:
+ # RegularExpressionFirstChar - implemented using
+ # RegularExpressionChars on the theory that we have already
+ # ruled out the possibility of a comment.
+ # RegularExpressionChars
+ (?:
+ # RegularExpressionNonTerminator but not one of \\ or / or [
+ [^/\\\[\r\n\u2028\u2029]
+ | # RegularExpressionBackslashSequence
+ \\ [^\r\n\u2028\u2029]
+ | # RegularExpressionClass
+ \[
+ # RegularExpressionClassChars
+ (?:
+ # RegularExpressionNonTerminator but not one of ] or \\
+ [^]\\\r\n\u2028\u2029]
+ | # RegularExpressionBackslashSequence
+ \\ [^\r\n\u2028\u2029]
+ )*
+ \]
+ )+
+ )
+ /
+ (?: \w* )
+)
+''')
+
+# Words that never match Identifier. (`await` and `yield` nonetheless
+# conditionally match IdentifierReference, BindingIdentifier, and
+# LabelIdentifier.)
+#
+# Technically the term for these is "reserved word", not "keyword", but
+# whatever.
+ECMASCRIPT_FULL_KEYWORDS = [
+ 'await',
+ 'break',
+ 'case',
+ 'catch',
+ 'class',
+ 'const',
+ 'continue',
+ 'debugger',
+ 'default',
+ 'delete',
+ 'do',
+ 'else',
+ 'enum',
+ 'export',
+ 'extends',
+ 'finally',
+ 'for',
+ 'function',
+ 'if',
+ 'import',
+ 'in',
+ 'instanceof',
+ 'new',
+ 'null',
+ 'return',
+ 'super',
+ 'switch',
+ 'this',
+ 'throw',
+ 'true',
+ 'false',
+ 'try',
+ 'typeof',
+ 'var',
+ 'void',
+ 'while',
+ 'with',
+ 'yield',
+]
+
+ECMASCRIPT_CONDITIONAL_KEYWORDS = [
+ # Words that are identifiers except in strict mode
+ 'let', # this one is also banned at the beginning of an ExpressionStatement
+ 'static',
+ 'implements',
+ 'interface',
+ 'package',
+ 'private',
+ 'protected',
+ 'public',
+
+ # Words that are always allowed as identifiers, but are also keywords in
+ # other contexts.
+ 'as',
+ 'async',
+ 'from',
+ 'get',
+ 'of',
+ 'set',
+ 'target',
+]
+
+# Technically this set includes a reserved word that isn't currently being used
+# as a keyword in the grammar: `enum`.
+ALL_KEYWORDS = set(ECMASCRIPT_FULL_KEYWORDS + ECMASCRIPT_CONDITIONAL_KEYWORDS)
+
+
+class JSLexer(jsparagus.lexer.FlatStringLexer):
+ """Vague approximation of an ECMAScript lexer. """
+ def __init__(self, parser, filename=None):
+ super().__init__(parser, filename)
+
+ def _match(self, closing):
+ match = TOKEN_RE.match(self.src, self.point)
+ assert match is not None
+
+ if match.end() == len(self.src) and not closing:
+ # The current token runs right up against the end of the current
+ # chunk of source and thus might continue in the next chunk. Do not
+ # move self.point.
+ return None
+
+ token = match.group(1)
+ if token == '':
+ # Whitespace followed by end of input or illegal character.
+ if match.end() == len(self.src):
+ # End of input. Success!
+ assert closing
+ self.point = match.end()
+ return None
+ else:
+ c = self.src[match.end()]
+ self.throw("unexpected character: {!r}".format(c))
+
+ c = token[0]
+ t = None
+ if c.isdigit() or c == '.' and token != '.':
+ t = 'NumericLiteral'
+ elif c.isalpha() or c in '$_':
+ if token in ALL_KEYWORDS: # TODO support strict mode
+ if token == 'null':
+ t = 'NullLiteral'
+ elif token in ('true', 'false'):
+ t = 'BooleanLiteral'
+ else:
+ t = token
+ else:
+ t = 'Name'
+ elif c == '/':
+ if token.startswith(('/*', '//')):
+ # Incomplete comment. (In non-closing mode, this is handled
+ # above, immediately after the match.)
+ assert match.end() == len(self.src)
+ assert closing
+ self.point = len(self.src)
+ self.throw("incomplete comment at end of source")
+
+ # We choose RegExp vs. division based on what the parser can
+ # accept, a literal implementation of the spec.
+ #
+ # To make this correct in combination with end-of-line ASI, make
+ # the parser rewind the lexer one token and ask for it again in
+ # that case, so that the lexer asks the can-accept question again.
+ point = match.start(1)
+ if self.parser.can_accept_terminal(self, 'RegularExpressionLiteral'):
+ match = REGEXP_RE.match(self.src, point)
+ if match is None:
+ if closing:
+ self.throw("unterminated regexp literal")
+ else:
+ return None
+ token = 'RegularExpressionLiteral'
+ else:
+ match = DIV_RE.match(self.src, point)
+ token = match.group(1)
+
+ if not closing and match.end() == len(self.src):
+ # At the end of a chunk, `/a*b/` could be the start of
+ # `/a*b/g`, and `/` could be the start of `/=`.
+ return None
+
+ t = token
+ elif c == '`':
+ if token.endswith('`'):
+ t = 'NoSubstitutionTemplate'
+ else:
+ t = 'TemplateHead'
+ elif c == '"' or c == "'":
+ t = 'StringLiteral'
+ elif c == '}':
+ # TODO: TemplateTail
+ t = token
+ elif c in '{()[];,~?:.<>=!+-*%&|^':
+ t = token
+ else:
+ assert False
+
+ self._current_match = match
+ self.previous_token_end = self.point
+ self.current_token_start = match.start(1)
+ self.point = match.end()
+ return t
+
+ def take(self):
+ return self._current_match.group(1)
+
+ def saw_line_terminator(self):
+ """True if there's a LineTerminator before the current token."""
+ i = self.previous_token_end
+ j = self.current_token_start
+ ws_between = self.src[i:j]
+ return any(c in ws_between for c in '\r\n\u2028\u2029')
+
+ def can_close(self):
+ match = TOKEN_RE.match(self.src)
+ return match.group(1) == '' and self.parser.can_close()
diff --git a/third_party/rust/jsparagus/js_parser/load_es_grammar.py b/third_party/rust/jsparagus/js_parser/load_es_grammar.py
new file mode 100644
index 0000000000..c50688534d
--- /dev/null
+++ b/third_party/rust/jsparagus/js_parser/load_es_grammar.py
@@ -0,0 +1,129 @@
+""" Functions for loading the ECMAScript lexical and syntactic grammars. """
+
+from jsparagus.ordered import OrderedSet, OrderedFrozenSet
+from jsparagus import gen, grammar
+from .lexer import ECMASCRIPT_FULL_KEYWORDS, ECMASCRIPT_CONDITIONAL_KEYWORDS
+from .parse_esgrammar import parse_esgrammar
+
+
+ECMASCRIPT_LEXICAL_SYNTHETIC_TERMINALS: grammar.SyntheticTerminalsDict = {
+ # Theoretically, this should be the set of all Unicode characters, but that
+ # would take a lot of memory, and in practice, the set is not used.
+ 'SourceCharacter': OrderedFrozenSet([]),
+}
+
+ECMASCRIPT_LEXICAL_GOAL_NTS = [
+ 'WhiteSpace',
+ 'InputElementDiv',
+ 'InputElementRegExp',
+]
+
+
+def load_lexical_grammar(filename):
+ """Load the ECMAScript lexical grammar."""
+ with open(filename) as f:
+ grammar_text = f.read()
+ g = parse_esgrammar(
+ grammar_text,
+ filename=filename,
+ goals=ECMASCRIPT_LEXICAL_GOAL_NTS,
+ synthetic_terminals=ECMASCRIPT_LEXICAL_SYNTHETIC_TERMINALS,
+ terminal_names=ECMASCRIPT_LEXICAL_SYNTHETIC_TERMINALS.keys())
+ return gen.expand_parameterized_nonterminals(g)
+
+
+ECMASCRIPT_SYNTACTIC_GOAL_NTS = [
+ 'Script',
+ 'Module',
+ # 'FormalParameters',
+ # 'FunctionBody',
+]
+
+# Identifiers are complicated. A "synthetic terminal" is a shorthand symbol
+# that stands for any one of a set of terminals. For example, *IdentifierName*
+# stands for any token that looks like an identifier, including keywords.
+#
+# These sets must use the names of the terminals produced by the lexer. Except
+# for `Name`, our lexer output uses the terminal symbols of the syntactic
+# grammar, which include some nonterminals of the lexical grammar. The
+# syntactic grammar uses `BooleanLiteral`, not `true` and `false`; and it uses
+# `NullLiteral` instead of `null`.
+ECMASCRIPT_SYNTHETIC_TERMINALS = {
+ 'IdentifierName': OrderedSet([
+ 'Name',
+ 'BooleanLiteral',
+ 'NullLiteral',
+ 'NameWithEscape',
+ *ECMASCRIPT_FULL_KEYWORDS,
+ *ECMASCRIPT_CONDITIONAL_KEYWORDS
+ ]) - OrderedSet(['true', 'false', 'null']),
+ 'Identifier': OrderedSet([
+ 'Name',
+ 'NameWithEscape',
+ *ECMASCRIPT_CONDITIONAL_KEYWORDS
+ ]),
+}
+
+# Lexical nonterminals that are used as terminals in the syntactic grammar.
+ECMASCRIPT_TOKEN_NAMES = [
+ 'BooleanLiteral',
+ 'IdentifierName',
+ 'PrivateIdentifier',
+ 'NoSubstitutionTemplate',
+ 'NullLiteral',
+ 'NumericLiteral',
+ 'BigIntLiteral',
+ 'RegularExpressionLiteral',
+ 'StringLiteral',
+ 'TemplateHead',
+ 'TemplateMiddle',
+ 'TemplateTail',
+]
+
+# List of all terminals, other than keywords, that our (hand-coded) lexer
+# produces.
+#
+# (What our lexer implements for IdentifierName and friends is a slight
+# variation on the spec. See `ECMASCRIPT_SYNTHETIC_TERMINALS` above.)
+TERMINAL_NAMES_FOR_SYNTACTIC_GRAMMAR = ECMASCRIPT_TOKEN_NAMES + [
+ 'Identifier',
+ 'Name',
+]
+
+
+def load_syntactic_grammar(filename, extensions):
+ """Load the ECMAScript syntactic grammar."""
+ with open(filename) as f:
+ grammar_text = f.read()
+
+ extensions_content = []
+ for ext_filename in extensions:
+ # Extract grammar_extension! macro content, and store in a list.
+ with open(ext_filename) as ext_file:
+ content = None
+ start_line = 0
+ for lineno, line in enumerate(ext_file):
+ if line.startswith("grammar_extension!"):
+ assert line.endswith("{\n")
+ content = ""
+ # +2: enumerate starts at 0, while the first line is 1.
+ # Also, the first line added to the content variable is the
+ # next one.
+ start_line = lineno + 2
+ continue
+ if line.startswith("}") and content:
+ extensions_content.append((ext_filename, start_line, content))
+ content = None
+ continue
+ if content is not None:
+ content += line
+
+ g = parse_esgrammar(
+ grammar_text,
+ filename=filename,
+ extensions=extensions_content,
+ goals=ECMASCRIPT_SYNTACTIC_GOAL_NTS,
+ synthetic_terminals=ECMASCRIPT_SYNTHETIC_TERMINALS,
+ terminal_names=TERMINAL_NAMES_FOR_SYNTACTIC_GRAMMAR)
+
+ return g
diff --git a/third_party/rust/jsparagus/js_parser/parse_esgrammar.py b/third_party/rust/jsparagus/js_parser/parse_esgrammar.py
new file mode 100644
index 0000000000..efcb640406
--- /dev/null
+++ b/third_party/rust/jsparagus/js_parser/parse_esgrammar.py
@@ -0,0 +1,545 @@
+"""Parse a grammar written in ECMArkup."""
+
+from __future__ import annotations
+# mypy: no-implicit-optional
+
+import os
+import collections
+from typing import Dict, Iterable, Optional, Tuple
+
+from jsparagus import parse_pgen, gen, grammar, extension, types
+from jsparagus.lexer import LexicalGrammar
+from jsparagus.ordered import OrderedSet, OrderedFrozenSet
+
+
+ESGrammarLexer = LexicalGrammar(
+ # the operators and keywords:
+ "[ ] { } , ~ + ? <! = == != => ( ) @ < > ' ; "
+ "but empty here lookahead no not of one or returns through Some None impl for let",
+
+ NL="\n",
+
+ # any number of colons together
+ EQ=r':+',
+
+ # terminals of the ES grammar, quoted with backticks
+ T=r'`[^` \n]+`|```',
+
+ # also terminals, denoting control characters
+ CHR=r'<[A-Z ]+>|U\+[0-9A-f]{4}',
+
+ # nonterminals/types that will be followed by parameters
+ NTCALL=r'[A-Za-z]\w*(?=[\[<])',
+
+ # nonterminals (also, boolean parameters and type names)
+ NT=r'[A-Za-z]\w*',
+
+ # nonterminals wrapped in vertical bars for no apparent reason
+ NTALT=r'\|[A-Z]\w+\|',
+
+ # the spec also gives a few productions names
+ PRODID=r'#[A-Za-z]\w*',
+
+ # prose not wrapped in square brackets
+ # To avoid conflict with the `>` token, this is recognized only after a space.
+ PROSE=r'(?<= )>[^\n]*',
+
+ # prose wrapped in square brackets
+ WPROSE=r'\[>[^]]*\]',
+
+ # expression denoting a matched terminal or nonterminal
+ MATCH_REF=r'\$(?:0|[1-9][0-9]*)',
+
+ # the spec also gives a few productions names
+ RUSTCOMMENT=r'//.*\n',
+)
+
+
+ESGrammarParser = gen.compile(
+ parse_pgen.load_grammar(
+ os.path.join(os.path.dirname(__file__), "esgrammar.pgen")))
+
+
+SIGIL_FALSE = '~'
+SIGIL_TRUE = '+'
+
+# Abbreviations for single-character terminals, used in the lexical grammar.
+ECMASCRIPT_CODE_POINTS = {
+ # From <https://tc39.es/ecma262/#table-31>
+ '<ZWNJ>': grammar.Literal('\u200c'),
+ '<ZWJ>': grammar.Literal('\u200d'),
+ '<ZWNBSP>': grammar.Literal('\ufeff'),
+
+ # From <https://tc39.es/ecma262/#table-32>
+ '<TAB>': grammar.Literal('\t'),
+ '<VT>': grammar.Literal('\u000b'),
+ '<FF>': grammar.Literal('\u000c'),
+ '<SP>': grammar.Literal(' '),
+ '<NBSP>': grammar.Literal('\u00a0'),
+ # <ZWNBSP> already defined above
+ '<USP>': grammar.UnicodeCategory('Zs'),
+
+ # From <https://tc39.es/ecma262/#table-33>
+ '<LF>': grammar.Literal('\u000a'),
+ '<CR>': grammar.Literal('\u000d'),
+ '<LS>': grammar.Literal('\u2028'),
+ '<PS>': grammar.Literal('\u2028'),
+}
+
+
+class ESGrammarBuilder:
+ def __init__(self, terminal_names):
+ # Names of terminals that are written as nonterminals in the grammar.
+ # For example, "BooleanLiteral" is a terminal name when parsing the
+ # syntactic grammar.
+ if terminal_names is None:
+ terminal_names = frozenset()
+ self.terminal_names = frozenset(terminal_names)
+ self.reset()
+
+ def reset(self):
+ self.lexer = None
+ # This is how full-parsing and lazy-parsing are implemented, using
+ # different traits.
+ #
+ # This field contains the Rust's trait used for calling the method.
+ # When a CallMethod is generated, it is assumed to be a function of
+ # this trait. The trait is used by the Rust backend to generate
+ # multiple backends which are implementing different set of traits.
+ # Having the trait on the function call is useful as a way to filter
+ # functions calls at code-generation time.
+ #
+ # This field is updated by the `rust_param_impl`, which is used in
+ # grammar extensions, and visited before producing any CallMethod.
+ self.method_trait = "AstBuilder"
+
+ def rust_edsl(self, impl, grammar):
+ return extension.GrammarExtension(impl, grammar, self.lexer.filename)
+
+ def rust_param_impl(self, trait, for_type, param):
+ self.method_trait = trait
+ return extension.ImplFor(param, trait, for_type)
+
+ def rust_impl(self, trait, impl_type):
+ return self.rust_param_impl(trait, impl_type, [])
+
+ def rust_nt_def(self, lhs, rhs_line):
+ # Right now, only focus on the syntactic grammar, and assume that all
+ # rules are patching existing grammar production by adding code.
+ return extension.ExtPatch(self.nt_def(None, lhs, ':', [rhs_line]))
+
+ def rust_rhs_line(self, symbols):
+ return self.rhs_line(None, symbols, None, None)
+
+ def rust_expr(self, expr):
+ assert isinstance(expr, grammar.CallMethod)
+ return expr
+
+ def empty(self):
+ return []
+
+ def single(self, x):
+ return [x]
+
+ def append(self, x, y):
+ return x + [y]
+
+ def concat(self, x, y):
+ return x + y
+
+ def blank_line(self):
+ return []
+
+ def nt_def_to_list(self, nt_def):
+ return [nt_def]
+
+ def to_production(self, lhs, i, rhs, is_sole_production):
+ """Wrap a list of grammar symbols `rhs` in a Production object."""
+ body, reducer, condition = rhs
+ if reducer is None:
+ reducer = self.default_reducer(lhs, i, body, is_sole_production)
+ return grammar.Production(body, reducer, condition=condition)
+
+ def default_reducer(self, lhs, i, body, is_sole_production):
+ assert isinstance(lhs, grammar.Nt)
+ nt_name = lhs.name
+
+ nargs = sum(1 for e in body if grammar.is_concrete_element(e))
+ if is_sole_production:
+ method_name = nt_name
+ else:
+ method_name = '{} {}'.format(nt_name, i)
+ return self.expr_call(method_name, tuple(range(nargs)), None)
+
+ def needs_asi(self, lhs, p):
+ """True if p is a production in which ASI can happen."""
+ # The purpose of the fake ForLexicalDeclaration production is to have a
+ # copy of LexicalDeclaration that does not trigger ASI.
+ #
+ # Two productions have body == [";"] -- one for EmptyStatement and one
+ # for ClassMember. Neither should trigger ASI.
+ #
+ # The only other semicolons that should not trigger ASI are the ones in
+ # `for` statement productions, which happen to be exactly those
+ # semicolons that are not at the end of a production.
+ return (not (isinstance(lhs, grammar.Nt)
+ and lhs.name == 'ForLexicalDeclaration')
+ and len(p.body) > 1
+ and p.body[-1] == ';')
+
+ def apply_asi(self, p, reducer_was_autogenerated):
+ """Return two rules based on p, so that ASI can be applied."""
+ assert isinstance(p.reducer, grammar.CallMethod)
+
+ if reducer_was_autogenerated:
+ # Don't pass the semicolon to the method.
+ reducer = self.expr_call(p.reducer.method,
+ p.reducer.args[:-1],
+ None)
+ else:
+ reducer = p.reducer
+
+ # Except for do-while loops, check at runtime that ASI occurs only at
+ # the end of a line.
+ if (len(p.body) == 7
+ and p.body[0] == 'do'
+ and p.body[2] == 'while'
+ and p.body[3] == '('
+ and p.body[5] == ')'
+ and p.body[6] == ';'):
+ code = "do_while_asi"
+ else:
+ code = "asi"
+
+ return [
+ # The preferred production, with the semicolon in.
+ p.copy_with(body=p.body[:],
+ reducer=reducer),
+ # The fallback production, performing ASI.
+ p.copy_with(body=p.body[:-1] + [grammar.ErrorSymbol(code)],
+ reducer=reducer),
+ ]
+
+ def expand_lexical_rhs(self, rhs):
+ body, reducer, condition = rhs
+ out = []
+ for e in body:
+ if isinstance(e, str):
+ # The terminal symbols of the lexical grammar are characters, so
+ # add each character of this string as a separate element.
+ out += [grammar.Literal(ch) for ch in e]
+ else:
+ out.append(e)
+ return [out, reducer, condition]
+
+ def nt_def(self, nt_type, lhs, eq, rhs_list):
+ has_sole_production = (len(rhs_list) == 1)
+ production_list = []
+ for i, rhs in enumerate(rhs_list):
+ if eq == ':':
+ # Syntactic grammar. A hack is needed for ASI.
+ reducer_was_autogenerated = rhs[1] is None
+ p = self.to_production(lhs, i, rhs, has_sole_production)
+ if self.needs_asi(lhs, p):
+ production_list += self.apply_asi(p, reducer_was_autogenerated)
+ else:
+ production_list.append(p)
+ elif eq == '::':
+ # Lexical grammar. A hack is needed to replace multicharacter
+ # terminals like `!==` into sequences of character terminals.
+ rhs = self.expand_lexical_rhs(rhs)
+ p = self.to_production(lhs, i, rhs, has_sole_production)
+ production_list.append(p)
+ return (lhs.name, eq, grammar.NtDef(lhs.args, production_list, nt_type))
+
+ def nt_def_one_of(self, nt_type, nt_lhs, eq, terminals):
+ return self.nt_def(nt_type, nt_lhs, eq, [([t], None, None) for t in terminals])
+
+ def nt_lhs_no_params(self, name):
+ return grammar.Nt(name, ())
+
+ def nt_lhs_with_params(self, name, params):
+ return grammar.Nt(name, tuple(params))
+
+ def simple_type(self, name):
+ return types.Type(name)
+
+ def lifetime_type(self, name):
+ return types.Lifetime(name)
+
+ def parameterized_type(self, name, args):
+ return types.Type(name, tuple(args))
+
+ def t_list_line(self, terminals):
+ return terminals
+
+ def terminal(self, t):
+ assert t[0] == "`"
+ assert t[-1] == "`"
+ return t[1:-1]
+
+ def terminal_chr(self, chr):
+ raise ValueError("FAILED: %r" % chr)
+
+ def rhs_line(self, ifdef, rhs, reducer, _prodid):
+ return (rhs, reducer, ifdef)
+
+ def rhs_line_prose(self, prose):
+ return ([prose], None, None)
+
+ def empty_rhs(self):
+ return []
+
+ def expr_match_ref(self, token):
+ assert token.startswith('$')
+ return int(token[1:])
+
+ def expr_call(self, method, args, fallible):
+ # NOTE: Currently "AstBuilder" functions are made fallible using the
+ # fallible_methods taken from some Rust code which extract this
+ # information to produce a JSON file.
+ if self.method_trait == "AstBuilder":
+ fallible = None
+ return grammar.CallMethod(method, args or (), types.Type(self.method_trait),
+ fallible is not None)
+
+ def expr_some(self, expr):
+ return grammar.Some(expr)
+
+ def expr_none(self):
+ return None
+
+ def ifdef(self, value, nt):
+ return nt, value
+
+ def optional(self, nt):
+ return grammar.Optional(nt)
+
+ def but_not(self, nt, exclusion):
+ _, exclusion = exclusion
+ return grammar.Exclude(nt, [exclusion])
+ # return ('-', nt, exclusion)
+
+ def but_not_one_of(self, nt, exclusion_list):
+ exclusion_list = [exclusion for _, exclusion in exclusion_list]
+ return grammar.Exclude(nt, exclusion_list)
+ # return ('-', nt, exclusion_list)
+
+ def no_line_terminator_here(self, lt):
+ if lt not in ('LineTerminator', '|LineTerminator|'):
+ raise ValueError("unrecognized directive " + repr("[no " + lt + " here]"))
+ return grammar.NoLineTerminatorHere
+
+ def nonterminal(self, name):
+ if name in self.terminal_names:
+ return name
+ return grammar.Nt(name, ())
+
+ def nonterminal_apply(self, name, args):
+ if name in self.terminal_names:
+ raise ValueError("parameters applied to terminal {!r}".format(name))
+ if len(set(k for k, expr in args)) != len(args):
+ raise ValueError("parameter passed multiple times")
+ return grammar.Nt(name, tuple(args))
+
+ def arg_expr(self, sigil, argname):
+ if sigil == '?':
+ return (argname, grammar.Var(argname))
+ else:
+ return (argname, sigil)
+
+ def sigil_false(self):
+ return False
+
+ def sigil_true(self):
+ return True
+
+ def exclusion_terminal(self, t):
+ return ("t", t)
+
+ def exclusion_nonterminal(self, nt):
+ return ("nt", nt)
+
+ def exclusion_chr_range(self, c1, c2):
+ return ("range", c1, c2)
+
+ def la_eq(self, t):
+ return grammar.LookaheadRule(OrderedFrozenSet([t]), True)
+
+ def la_ne(self, t):
+ return grammar.LookaheadRule(OrderedFrozenSet([t]), False)
+
+ def la_not_in_nonterminal(self, nt):
+ return grammar.LookaheadRule(OrderedFrozenSet([nt]), False)
+
+ def la_not_in_set(self, lookahead_exclusions):
+ if all(len(excl) == 1 for excl in lookahead_exclusions):
+ return grammar.LookaheadRule(
+ OrderedFrozenSet(excl[0] for excl in lookahead_exclusions),
+ False)
+ raise ValueError("unsupported: lookahead > 1 token, {!r}"
+ .format(lookahead_exclusions))
+
+ def chr(self, t):
+ assert t[0] == "<" or t[0] == 'U'
+ if t[0] == "<":
+ assert t[-1] == ">"
+ if t not in ECMASCRIPT_CODE_POINTS:
+ raise ValueError("unrecognized character abbreviation {!r}".format(t))
+ return ECMASCRIPT_CODE_POINTS[t]
+ else:
+ assert t[1] == "+"
+ return grammar.Literal(chr(int(t[2:], base=16)))
+
+
+def finish_grammar(nt_defs, goals, variable_terminals, synthetic_terminals,
+ single_grammar=True, extensions=[]):
+ nt_grammars = {}
+ for nt_name, eq, _ in nt_defs:
+ if nt_name in nt_grammars:
+ raise ValueError(
+ "duplicate definitions for nonterminal {!r}"
+ .format(nt_name))
+ nt_grammars[nt_name] = eq
+
+ # Figure out which grammar we were trying to get (":" for syntactic,
+ # "::" for lexical) based on the goal symbols.
+ goals = list(goals)
+ if len(goals) == 0:
+ raise ValueError("no goal nonterminals specified")
+ if single_grammar:
+ selected_grammars = set(nt_grammars[goal] for goal in goals)
+ assert len(selected_grammars) != 0
+ if len(selected_grammars) > 1:
+ raise ValueError(
+ "all goal nonterminals must be part of the same grammar; "
+ "got {!r} (matching these grammars: {!r})"
+ .format(set(goals), set(selected_grammars)))
+ [selected_grammar] = selected_grammars
+
+ terminal_set = set()
+
+ def hack_production(p):
+ for i, e in enumerate(p.body):
+ if isinstance(e, str) and e[:1] == "`":
+ if len(e) < 3 or e[-1:] != "`":
+ raise ValueError(
+ "Unrecognized grammar symbol: {!r} (in {!r})"
+ .format(e, p))
+ p[i] = token = e[1:-1]
+ terminal_set.add(token)
+
+ nonterminals = {}
+ for nt_name, eq, rhs_list_or_lambda in nt_defs:
+ if single_grammar and eq != selected_grammar:
+ continue
+
+ if isinstance(rhs_list_or_lambda, grammar.NtDef):
+ nonterminals[nt_name] = rhs_list_or_lambda
+ else:
+ rhs_list = rhs_list_or_lambda
+ for p in rhs_list:
+ if not isinstance(p, grammar.Production):
+ raise ValueError(
+ "invalid grammar: ifdef in non-function-call context")
+ hack_production(p)
+ if nt_name in nonterminals:
+ raise ValueError(
+ "unsupported: multiple definitions for nt " + nt_name)
+ nonterminals[nt_name] = rhs_list
+
+ for t in terminal_set:
+ if t in nonterminals:
+ raise ValueError(
+ "grammar contains both a terminal `{}` and nonterminal {}"
+ .format(t, t))
+
+ # Add execution modes to generate the various functions needed to handle
+ # syntax parsing and full parsing execution modes.
+ exec_modes = collections.defaultdict(OrderedSet)
+ noop_parser = types.Type("ParserTrait", (types.Lifetime("alloc"), types.UnitType))
+ token_parser = types.Type("ParserTrait", (
+ types.Lifetime("alloc"), types.Type("StackValue", (types.Lifetime("alloc"),))))
+ ast_builder = types.Type("AstBuilderDelegate", (types.Lifetime("alloc"),))
+
+ # Full parsing takes token as input and build an AST.
+ exec_modes["full_actions"].extend([token_parser, ast_builder])
+
+ # Syntax parsing takes token as input but skip building the AST.
+ # TODO: The syntax parser is commented out for now, as we need something to
+ # be produced when we cannot call the AstBuilder for producing the values.
+
+ # No-op parsing is used for the simulator, which is so far used for
+ # querying whether we can end the incremental input and lookup if a state
+ # can accept some kind of tokens.
+ exec_modes["noop_actions"].add(noop_parser)
+
+ # Extensions are using an equivalent of Rust types to define the kind of
+ # parsers to be used, this map is used to convert these type names to the
+ # various execution modes.
+ full_parser = types.Type("FullParser")
+ syntax_parser = types.Type("SyntaxParser")
+ noop_parser = types.Type("NoopParser")
+ type_to_modes = {
+ noop_parser: ["noop_actions", "full_actions"],
+ syntax_parser: ["full_actions"],
+ full_parser: ["full_actions"],
+ }
+
+ result = grammar.Grammar(
+ nonterminals,
+ goal_nts=goals,
+ variable_terminals=variable_terminals,
+ synthetic_terminals=synthetic_terminals,
+ exec_modes=exec_modes,
+ type_to_modes=type_to_modes)
+ result.patch(extensions)
+ return result
+
+
+def parse_esgrammar(
+ text: str,
+ *,
+ filename: Optional[str] = None,
+ extensions: Iterable[Tuple[os.PathLike, int, str]] = (),
+ goals: Optional[Iterable[str]] = None,
+ terminal_names: Iterable[str] = (),
+ synthetic_terminals: Optional[Dict[str, OrderedSet[str]]] = None,
+ single_grammar: bool = True
+) -> grammar.Grammar:
+ if not text.endswith("\n\n"):
+ # Horrible hack: add a blank line at the end of the document so that
+ # the esgrammar grammar can use newlines as delimiters. :-P
+ text += "\n"
+
+ terminal_names = frozenset(terminal_names)
+ if synthetic_terminals is None:
+ synthetic_terminals = {}
+
+ builder = ESGrammarBuilder(terminal_names)
+ parser = ESGrammarParser(builder=builder, goal="grammar")
+ lexer = ESGrammarLexer(parser, filename=filename)
+ lexer.write(text)
+ nt_defs = lexer.close()
+ grammar_extensions = []
+ for ext_filename, start_lineno, content in extensions:
+ builder.reset()
+ parser = ESGrammarParser(builder=builder, goal="rust_edsl")
+ lexer = ESGrammarLexer(parser, filename=ext_filename)
+ builder.lexer = lexer
+ lexer.start_lineno = start_lineno
+ lexer.write(content)
+ result = lexer.close()
+ grammar_extensions.append(result)
+
+ if goals is None:
+ # Default to the first nonterminal in the input.
+ goals = [nt_defs[0][0]]
+
+ return finish_grammar(
+ nt_defs,
+ goals=goals,
+ variable_terminals=terminal_names - frozenset(synthetic_terminals),
+ synthetic_terminals=synthetic_terminals,
+ single_grammar=single_grammar,
+ extensions=grammar_extensions)
diff --git a/third_party/rust/jsparagus/js_parser/parser.py b/third_party/rust/jsparagus/js_parser/parser.py
new file mode 100644
index 0000000000..f67708a9cc
--- /dev/null
+++ b/third_party/rust/jsparagus/js_parser/parser.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+
+"""parser.py - A JavaScript parser, currently with many bugs.
+
+See README.md for instructions.
+"""
+
+from . import parser_tables
+from .lexer import JSLexer
+
+
+# "type: ignore" because mypy can't see inside js_parser.parser_tables.
+class JSParser(parser_tables.Parser): # type: ignore
+ def __init__(self, goal='Script', builder=None):
+ super().__init__(goal, builder)
+ self._goal = goal
+
+ def clone(self):
+ return JSParser(self._goal, self.methods)
+
+ def on_recover(self, error_code, lexer, stv):
+ """Check that ASI error recovery is really acceptable."""
+ if error_code == 'asi':
+ # ASI is allowed in three places:
+ # - at the end of the source text
+ # - before a close brace `}`
+ # - after a LineTerminator
+ # Hence the three-part if-condition below.
+ #
+ # The other quirks of ASI are implemented by massaging the syntax,
+ # in parse_esgrammar.py.
+ if not self.closed and stv.term != '}' and not lexer.saw_line_terminator():
+ lexer.throw("missing semicolon")
+ else:
+ # ASI is always allowed in this one state.
+ assert error_code == 'do_while_asi'
+
+
+def parse_Script(text):
+ lexer = JSLexer(JSParser('Script'))
+ lexer.write(text)
+ return lexer.close()
diff --git a/third_party/rust/jsparagus/js_parser/slash.esgrammar b/third_party/rust/jsparagus/js_parser/slash.esgrammar
new file mode 100644
index 0000000000..60bad3f660
--- /dev/null
+++ b/third_party/rust/jsparagus/js_parser/slash.esgrammar
@@ -0,0 +1,1683 @@
+
+StringNumericLiteral :::
+ StrWhiteSpace?
+ StrWhiteSpace? StrNumericLiteral StrWhiteSpace?
+
+StrWhiteSpace :::
+ StrWhiteSpaceChar StrWhiteSpace?
+
+StrWhiteSpaceChar :::
+ WhiteSpace
+ LineTerminator
+
+StrNumericLiteral :::
+ StrDecimalLiteral
+ BinaryIntegerLiteral
+ OctalIntegerLiteral
+ HexIntegerLiteral
+
+StrDecimalLiteral :::
+ StrUnsignedDecimalLiteral
+ `+` StrUnsignedDecimalLiteral
+ `-` StrUnsignedDecimalLiteral
+
+StrUnsignedDecimalLiteral :::
+ `Infinity`
+ DecimalDigits `.` DecimalDigits? ExponentPart?
+ `.` DecimalDigits ExponentPart?
+ DecimalDigits ExponentPart?
+
+
+SourceCharacter ::
+ {}
+
+
+InputElementDiv ::
+ WhiteSpace
+ LineTerminator
+ Comment
+ CommonToken
+ DivPunctuator
+ RightBracePunctuator
+
+InputElementRegExp ::
+ WhiteSpace
+ LineTerminator
+ Comment
+ CommonToken
+ RightBracePunctuator
+ RegularExpressionLiteral
+
+InputElementRegExpOrTemplateTail ::
+ WhiteSpace
+ LineTerminator
+ Comment
+ CommonToken
+ RegularExpressionLiteral
+ TemplateSubstitutionTail
+
+InputElementTemplateTail ::
+ WhiteSpace
+ LineTerminator
+ Comment
+ CommonToken
+ DivPunctuator
+ TemplateSubstitutionTail
+
+
+WhiteSpace ::
+ <TAB>
+ <VT>
+ <FF>
+ <SP>
+ <NBSP>
+ <ZWNBSP>
+ {Zs}
+
+
+LineTerminator ::
+ <LF>
+ <CR>
+ <LINE SEPARATOR>
+ <PARAGRAPH SEPARATOR>
+
+LineTerminatorSequence ::
+ <LF>
+ <CR> [lookahead != <LF> ]
+ <LINE SEPARATOR>
+ <PARAGRAPH SEPARATOR>
+ <CR> <LF>
+
+
+Comment ::
+ MultiLineComment
+ SingleLineComment
+
+MultiLineComment ::
+ `/*` MultiLineCommentChars? `*/`
+
+MultiLineCommentChars ::
+ MultiLineNotAsteriskChar MultiLineCommentChars?
+ `*` PostAsteriskCommentChars?
+
+PostAsteriskCommentChars ::
+ MultiLineNotForwardSlashOrAsteriskChar MultiLineCommentChars?
+ `*` PostAsteriskCommentChars?
+
+MultiLineNotAsteriskChar ::
+ SourceCharacter but not `*`
+
+MultiLineNotForwardSlashOrAsteriskChar ::
+ SourceCharacter but not one of `/` or `*`
+
+SingleLineComment ::
+ `//` SingleLineCommentChars?
+
+SingleLineCommentChars ::
+ SingleLineCommentChar SingleLineCommentChars?
+
+SingleLineCommentChar ::
+ SourceCharacter but not LineTerminator
+
+
+CommonToken ::
+ IdentifierName
+ Punctuator
+ NumericLiteral
+ StringLiteral
+ Template
+
+
+IdentifierName ::
+ IdentifierStart
+ IdentifierName IdentifierPart
+
+IdentifierStart ::
+ UnicodeIDStart
+ `$`
+ `_`
+ `\` UnicodeEscapeSequence
+
+IdentifierPart ::
+ UnicodeIDContinue
+ `$`
+ `\` UnicodeEscapeSequence
+ <ZWNJ>
+ <ZWJ>
+
+UnicodeIDStart ::
+ {L}
+ {NI}
+ U+2118
+ U+212E
+ U+309B
+ U+309C
+
+UnicodeIDContinue ::
+ UnicodeIDStart
+ {Mn}
+ {Mc}
+ {Nd}
+ {Pc}
+ U+1369
+ U+1370
+ U+1371
+ U+00B7
+ U+0387
+ U+19DA
+
+
+ReservedWord ::
+ Keyword
+ FutureReservedWord
+ NullLiteral
+ BooleanLiteral
+
+
+Keyword :: one of
+ `await`
+ `break`
+ `case` `catch` `class` `const` `continue`
+ `debugger` `default` `delete` `do`
+ `else` `export` `extends`
+ `finally` `for` `function`
+ `if` `import` `in` `instanceof`
+ `new`
+ `return`
+ `super` `switch`
+ `this` `throw` `try` `typeof`
+ `var` `void`
+ `while` `with`
+ `yield`
+
+
+FutureReservedWord ::
+ `enum`
+
+
+Punctuator :: one of
+ `{` `(` `)` `[` `]`
+ `.` `...` `;` `,`
+ `<` `>` `<=` `>=`
+ `==` `!=` `===` `!==`
+ `+` `-` `*` `%` `**`
+ `++` `--`
+ `<<` `>>` `>>>`
+ `&` `|` `^`
+ `!` `~`
+ `&&` `||`
+ `?` `:`
+ `=` `+=` `-=` `*=` `%=` `**=` `<<=` `>>=` `>>>=` `&=` `|=` `^=`
+ `=>`
+
+DivPunctuator ::
+ `/`
+ `/=`
+
+RightBracePunctuator ::
+ `}`
+
+
+NullLiteral ::
+ `null`
+
+
+BooleanLiteral ::
+ `true`
+ `false`
+
+
+NumericLiteral ::
+ DecimalLiteral
+ BinaryIntegerLiteral
+ OctalIntegerLiteral
+ HexIntegerLiteral
+
+DecimalLiteral ::
+ DecimalIntegerLiteral `.` DecimalDigits? ExponentPart?
+ `.` DecimalDigits ExponentPart?
+ DecimalIntegerLiteral ExponentPart?
+
+DecimalIntegerLiteral ::
+ `0`
+ NonZeroDigit DecimalDigits?
+
+DecimalDigits ::
+ DecimalDigit
+ DecimalDigits DecimalDigit
+
+DecimalDigit :: one of
+ `0` `1` `2` `3` `4` `5` `6` `7` `8` `9`
+
+NonZeroDigit :: one of
+ `1` `2` `3` `4` `5` `6` `7` `8` `9`
+
+ExponentPart ::
+ ExponentIndicator SignedInteger
+
+ExponentIndicator :: one of
+ `e` `E`
+
+SignedInteger ::
+ DecimalDigits
+ `+` DecimalDigits
+ `-` DecimalDigits
+
+BinaryIntegerLiteral ::
+ `0b` BinaryDigits
+ `0B` BinaryDigits
+
+BinaryDigits ::
+ BinaryDigit
+ BinaryDigits BinaryDigit
+
+BinaryDigit :: one of
+ `0` `1`
+
+OctalIntegerLiteral ::
+ `0o` OctalDigits
+ `0O` OctalDigits
+
+OctalDigits ::
+ OctalDigit
+ OctalDigits OctalDigit
+
+OctalDigit :: one of
+ `0` `1` `2` `3` `4` `5` `6` `7`
+
+HexIntegerLiteral ::
+ `0x` HexDigits
+ `0X` HexDigits
+
+HexDigits ::
+ HexDigit
+ HexDigits HexDigit
+
+HexDigit :: one of
+ `0` `1` `2` `3` `4` `5` `6` `7` `8` `9` `a` `b` `c` `d` `e` `f` `A` `B` `C` `D` `E` `F`
+
+
+StringLiteral ::
+ `"` DoubleStringCharacters? `"`
+ `'` SingleStringCharacters? `'`
+
+DoubleStringCharacters ::
+ DoubleStringCharacter DoubleStringCharacters?
+
+SingleStringCharacters ::
+ SingleStringCharacter SingleStringCharacters?
+
+DoubleStringCharacter ::
+ SourceCharacter but not one of `"` or `\` or LineTerminator
+ <LINE SEPARATOR>
+ <PARAGRAPH SEPARATOR>
+ `\` EscapeSequence
+ LineContinuation
+
+SingleStringCharacter ::
+ SourceCharacter but not one of `'` or `\` or LineTerminator
+ <LINE SEPARATOR>
+ <PARAGRAPH SEPARATOR>
+ `\` EscapeSequence
+ LineContinuation
+
+LineContinuation ::
+ `\` LineTerminatorSequence
+
+EscapeSequence ::
+ CharacterEscapeSequence
+ `0` [lookahead <! DecimalDigit]
+ HexEscapeSequence
+ UnicodeEscapeSequence
+
+
+CharacterEscapeSequence ::
+ SingleEscapeCharacter
+ NonEscapeCharacter
+
+SingleEscapeCharacter :: one of
+ `'` `"` `\` `b` `f` `n` `r` `t` `v`
+
+NonEscapeCharacter ::
+ SourceCharacter but not one of EscapeCharacter or LineTerminator
+
+EscapeCharacter ::
+ SingleEscapeCharacter
+ DecimalDigit
+ `x`
+ `u`
+
+HexEscapeSequence ::
+ `x` HexDigit HexDigit
+
+UnicodeEscapeSequence ::
+ `u` Hex4Digits
+ `u{` CodePoint `}`
+
+Hex4Digits ::
+ HexDigit HexDigit HexDigit HexDigit
+
+
+RegularExpressionLiteral ::
+ `/` RegularExpressionBody `/` RegularExpressionFlags
+
+RegularExpressionBody ::
+ RegularExpressionFirstChar RegularExpressionChars
+
+RegularExpressionChars ::
+ [empty]
+ RegularExpressionChars RegularExpressionChar
+
+RegularExpressionFirstChar ::
+ RegularExpressionNonTerminator but not one of `*` or `\` or `/` or `[`
+ RegularExpressionBackslashSequence
+ RegularExpressionClass
+
+RegularExpressionChar ::
+ RegularExpressionNonTerminator but not one of `\` or `/` or `[`
+ RegularExpressionBackslashSequence
+ RegularExpressionClass
+
+RegularExpressionBackslashSequence ::
+ `\` RegularExpressionNonTerminator
+
+RegularExpressionNonTerminator ::
+ SourceCharacter but not LineTerminator
+
+RegularExpressionClass ::
+ `[` RegularExpressionClassChars `]`
+
+RegularExpressionClassChars ::
+ [empty]
+ RegularExpressionClassChars RegularExpressionClassChar
+
+RegularExpressionClassChar ::
+ RegularExpressionNonTerminator but not one of `]` or `\`
+ RegularExpressionBackslashSequence
+
+RegularExpressionFlags ::
+ [empty]
+ RegularExpressionFlags IdentifierPart
+
+
+Template ::
+ NoSubstitutionTemplate
+ TemplateHead
+
+NoSubstitutionTemplate ::
+ ``` TemplateCharacters? ```
+
+TemplateHead ::
+ ``` TemplateCharacters? `${`
+
+TemplateSubstitutionTail ::
+ TemplateMiddle
+ TemplateTail
+
+TemplateMiddle ::
+ `}` TemplateCharacters? `${`
+
+TemplateTail ::
+ `}` TemplateCharacters? ```
+
+TemplateCharacters ::
+ TemplateCharacter TemplateCharacters?
+
+TemplateCharacter ::
+ `$` [lookahead != `{` ]
+ `\` EscapeSequence
+ `\` NotEscapeSequence
+ LineContinuation
+ LineTerminatorSequence
+ SourceCharacter but not one of ``` or `\` or `$` or LineTerminator
+
+NotEscapeSequence ::
+ `0` DecimalDigit
+ DecimalDigit but not `0`
+ `x` [lookahead <! HexDigit]
+ `x` HexDigit [lookahead <! HexDigit]
+ `u` [lookahead <! HexDigit] [lookahead != `{`]
+ `u` HexDigit [lookahead <! HexDigit]
+ `u` HexDigit HexDigit [lookahead <! HexDigit]
+ `u` HexDigit HexDigit HexDigit [lookahead <! HexDigit]
+ `u` `{` [lookahead <! HexDigit]
+ `u` `{` NotCodePoint [lookahead <! HexDigit]
+ `u` `{` CodePoint [lookahead <! HexDigit] [lookahead != `}`]
+
+NotCodePoint ::
+ HexDigits [> but only if MV of |HexDigits| > 0x10FFFF ]
+
+CodePoint ::
+ HexDigits [> but only if MV of |HexDigits| ≤ 0x10FFFF ]
+
+
+IdentifierReference[Yield, Await] :
+ Identifier
+ [~Yield] `yield`
+ [~Await] `await`
+
+BindingIdentifier[Yield, Await] :
+ Identifier
+ `yield`
+ `await`
+
+LabelIdentifier[Yield, Await] :
+ Identifier
+ [~Yield] `yield`
+ [~Await] `await`
+
+Identifier :
+ IdentifierName but not ReservedWord
+
+
+PrimaryExpression[Yield, Await] :
+ `this`
+ IdentifierReference[?Yield, ?Await]
+ Literal
+ ArrayLiteral[?Yield, ?Await]
+ ObjectLiteral[?Yield, ?Await]
+ FunctionExpression
+ ClassExpression[?Yield, ?Await]
+ GeneratorExpression
+ AsyncFunctionExpression
+ AsyncGeneratorExpression
+ RegularExpressionLiteral
+ TemplateLiteral[?Yield, ?Await, ~Tagged]
+ CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] #parencover
+
+CoverParenthesizedExpressionAndArrowParameterList[Yield, Await] :
+ `(` Expression[+In, ?Yield, ?Await] `)`
+ `(` Expression[+In, ?Yield, ?Await] `,` `)`
+ `(` `)`
+ `(` `...` BindingIdentifier[?Yield, ?Await] `)`
+ `(` `...` BindingPattern[?Yield, ?Await] `)`
+ `(` Expression[+In, ?Yield, ?Await] `,` `...` BindingIdentifier[?Yield, ?Await] `)`
+ `(` Expression[+In, ?Yield, ?Await] `,` `...` BindingPattern[?Yield, ?Await] `)`
+
+
+ParenthesizedExpression[Yield, Await] :
+ `(` Expression[+In, ?Yield, ?Await] `)`
+
+
+Literal :
+ NullLiteral
+ BooleanLiteral
+ NumericLiteral
+ StringLiteral
+
+
+ArrayLiteral[Yield, Await] :
+ `[` Elision? `]`
+ `[` ElementList[?Yield, ?Await] `]`
+ `[` ElementList[?Yield, ?Await] `,` Elision? `]`
+
+ElementList[Yield, Await] :
+ Elision? AssignmentExpression[+In, ?Yield, ?Await]
+ Elision? SpreadElement[?Yield, ?Await]
+ ElementList[?Yield, ?Await] `,` Elision? AssignmentExpression[+In, ?Yield, ?Await]
+ ElementList[?Yield, ?Await] `,` Elision? SpreadElement[?Yield, ?Await]
+
+Elision :
+ `,`
+ Elision `,`
+
+SpreadElement[Yield, Await] :
+ `...` AssignmentExpression[+In, ?Yield, ?Await]
+
+
+ObjectLiteral[Yield, Await] :
+ `{` `}`
+ `{` PropertyDefinitionList[?Yield, ?Await] `}`
+ `{` PropertyDefinitionList[?Yield, ?Await] `,` `}`
+
+PropertyDefinitionList[Yield, Await] :
+ PropertyDefinition[?Yield, ?Await]
+ PropertyDefinitionList[?Yield, ?Await] `,` PropertyDefinition[?Yield, ?Await]
+
+PropertyDefinition[Yield, Await] :
+ IdentifierReference[?Yield, ?Await]
+ CoverInitializedName[?Yield, ?Await]
+ PropertyName[?Yield, ?Await] `:` AssignmentExpression[+In, ?Yield, ?Await]
+ MethodDefinition[?Yield, ?Await]
+ `...` AssignmentExpression[+In, ?Yield, ?Await]
+
+PropertyName[Yield, Await] :
+ LiteralPropertyName
+ ComputedPropertyName[?Yield, ?Await]
+
+LiteralPropertyName :
+ IdentifierName
+ StringLiteral
+ NumericLiteral
+
+ComputedPropertyName[Yield, Await] :
+ `[` AssignmentExpression[+In, ?Yield, ?Await] `]`
+
+CoverInitializedName[Yield, Await] :
+ IdentifierReference[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]
+
+Initializer[In, Yield, Await] :
+ `=` AssignmentExpression[?In, ?Yield, ?Await]
+
+
+TemplateLiteral[Yield, Await, Tagged] :
+ NoSubstitutionTemplate
+ SubstitutionTemplate[?Yield, ?Await, ?Tagged]
+
+SubstitutionTemplate[Yield, Await, Tagged] :
+ TemplateHead Expression[+In, ?Yield, ?Await] TemplateSpans[?Yield, ?Await, ?Tagged]
+
+TemplateSpans[Yield, Await, Tagged] :
+ TemplateTail
+ TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateTail
+
+TemplateMiddleList[Yield, Await, Tagged] :
+ TemplateMiddle Expression[+In, ?Yield, ?Await]
+ TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateMiddle Expression[+In, ?Yield, ?Await]
+
+
+MemberExpression[Yield, Await] :
+ PrimaryExpression[?Yield, ?Await]
+ MemberExpression[?Yield, ?Await] `[` Expression[+In, ?Yield, ?Await] `]`
+ MemberExpression[?Yield, ?Await] `.` IdentifierName
+ MemberExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged]
+ SuperProperty[?Yield, ?Await]
+ MetaProperty
+ `new` MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]
+
+SuperProperty[Yield, Await] :
+ `super` `[` Expression[+In, ?Yield, ?Await] `]`
+ `super` `.` IdentifierName
+
+MetaProperty :
+ NewTarget
+
+NewTarget :
+ `new` `.` `target`
+
+NewExpression[Yield, Await] :
+ MemberExpression[?Yield, ?Await]
+ `new` NewExpression[?Yield, ?Await]
+
+CallExpression[Yield, Await] :
+ CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] #callcover
+ SuperCall[?Yield, ?Await]
+ ImportCall[?Yield, ?Await]
+ CallExpression[?Yield, ?Await] Arguments[?Yield, ?Await]
+ CallExpression[?Yield, ?Await] `[` Expression[+In, ?Yield, ?Await] `]`
+ CallExpression[?Yield, ?Await] `.` IdentifierName
+ CallExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged]
+
+SuperCall[Yield, Await] :
+ `super` Arguments[?Yield, ?Await]
+
+ImportCall[Yield, Await] :
+ `import` `(` AssignmentExpression[+In, ?Yield, ?Await] `)`
+
+Arguments[Yield, Await] :
+ `(` `)`
+ `(` ArgumentList[?Yield, ?Await] `)`
+ `(` ArgumentList[?Yield, ?Await] `,` `)`
+
+ArgumentList[Yield, Await] :
+ AssignmentExpression[+In, ?Yield, ?Await]
+ `...` AssignmentExpression[+In, ?Yield, ?Await]
+ ArgumentList[?Yield, ?Await] `,` AssignmentExpression[+In, ?Yield, ?Await]
+ ArgumentList[?Yield, ?Await] `,` `...` AssignmentExpression[+In, ?Yield, ?Await]
+
+LeftHandSideExpression[Yield, Await] :
+ NewExpression[?Yield, ?Await]
+ CallExpression[?Yield, ?Await]
+
+
+CallMemberExpression[Yield, Await] :
+ MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]
+
+
+UpdateExpression[Yield, Await] :
+ LeftHandSideExpression[?Yield, ?Await]
+ LeftHandSideExpression[?Yield, ?Await] `++`
+ LeftHandSideExpression[?Yield, ?Await] `--`
+ `++` UnaryExpression[?Yield, ?Await]
+ `--` UnaryExpression[?Yield, ?Await]
+
+
+UnaryExpression[Yield, Await] :
+ UpdateExpression[?Yield, ?Await]
+ `delete` UnaryExpression[?Yield, ?Await]
+ `void` UnaryExpression[?Yield, ?Await]
+ `typeof` UnaryExpression[?Yield, ?Await]
+ `+` UnaryExpression[?Yield, ?Await]
+ `-` UnaryExpression[?Yield, ?Await]
+ `~` UnaryExpression[?Yield, ?Await]
+ `!` UnaryExpression[?Yield, ?Await]
+ [+Await] AwaitExpression[?Yield]
+
+
+ExponentiationExpression[Yield, Await] :
+ UnaryExpression[?Yield, ?Await]
+ UpdateExpression[?Yield, ?Await] `**` ExponentiationExpression[?Yield, ?Await]
+
+
+MultiplicativeExpression[Yield, Await] :
+ ExponentiationExpression[?Yield, ?Await]
+ MultiplicativeExpression[?Yield, ?Await] MultiplicativeOperator ExponentiationExpression[?Yield, ?Await]
+
+MultiplicativeOperator : one of
+ `*` `/` `%`
+
+
+AdditiveExpression[Yield, Await] :
+ MultiplicativeExpression[?Yield, ?Await]
+ AdditiveExpression[?Yield, ?Await] `+` MultiplicativeExpression[?Yield, ?Await]
+ AdditiveExpression[?Yield, ?Await] `-` MultiplicativeExpression[?Yield, ?Await]
+
+
+ShiftExpression[Yield, Await] :
+ AdditiveExpression[?Yield, ?Await]
+ ShiftExpression[?Yield, ?Await] `<<` AdditiveExpression[?Yield, ?Await]
+ ShiftExpression[?Yield, ?Await] `>>` AdditiveExpression[?Yield, ?Await]
+ ShiftExpression[?Yield, ?Await] `>>>` AdditiveExpression[?Yield, ?Await]
+
+
+RelationalExpression[In, Yield, Await] :
+ ShiftExpression[?Yield, ?Await]
+ RelationalExpression[?In, ?Yield, ?Await] `<` ShiftExpression[?Yield, ?Await]
+ RelationalExpression[?In, ?Yield, ?Await] `>` ShiftExpression[?Yield, ?Await]
+ RelationalExpression[?In, ?Yield, ?Await] `<=` ShiftExpression[?Yield, ?Await]
+ RelationalExpression[?In, ?Yield, ?Await] `>=` ShiftExpression[?Yield, ?Await]
+ RelationalExpression[?In, ?Yield, ?Await] `instanceof` ShiftExpression[?Yield, ?Await]
+ [+In] RelationalExpression[+In, ?Yield, ?Await] `in` ShiftExpression[?Yield, ?Await]
+
+
+EqualityExpression[In, Yield, Await] :
+ RelationalExpression[?In, ?Yield, ?Await]
+ EqualityExpression[?In, ?Yield, ?Await] `==` RelationalExpression[?In, ?Yield, ?Await]
+ EqualityExpression[?In, ?Yield, ?Await] `!=` RelationalExpression[?In, ?Yield, ?Await]
+ EqualityExpression[?In, ?Yield, ?Await] `===` RelationalExpression[?In, ?Yield, ?Await]
+ EqualityExpression[?In, ?Yield, ?Await] `!==` RelationalExpression[?In, ?Yield, ?Await]
+
+
+BitwiseANDExpression[In, Yield, Await] :
+ EqualityExpression[?In, ?Yield, ?Await]
+ BitwiseANDExpression[?In, ?Yield, ?Await] `&` EqualityExpression[?In, ?Yield, ?Await]
+
+BitwiseXORExpression[In, Yield, Await] :
+ BitwiseANDExpression[?In, ?Yield, ?Await]
+ BitwiseXORExpression[?In, ?Yield, ?Await] `^` BitwiseANDExpression[?In, ?Yield, ?Await]
+
+BitwiseORExpression[In, Yield, Await] :
+ BitwiseXORExpression[?In, ?Yield, ?Await]
+ BitwiseORExpression[?In, ?Yield, ?Await] `|` BitwiseXORExpression[?In, ?Yield, ?Await]
+
+
+LogicalANDExpression[In, Yield, Await] :
+ BitwiseORExpression[?In, ?Yield, ?Await]
+ LogicalANDExpression[?In, ?Yield, ?Await] `&&` BitwiseORExpression[?In, ?Yield, ?Await]
+
+LogicalORExpression[In, Yield, Await] :
+ LogicalANDExpression[?In, ?Yield, ?Await]
+ LogicalORExpression[?In, ?Yield, ?Await] `||` LogicalANDExpression[?In, ?Yield, ?Await]
+
+
+ConditionalExpression[In, Yield, Await] :
+ LogicalORExpression[?In, ?Yield, ?Await]
+ LogicalORExpression[?In, ?Yield, ?Await] `?` AssignmentExpression[+In, ?Yield, ?Await] `:` AssignmentExpression[?In, ?Yield, ?Await]
+
+
+AssignmentExpression[In, Yield, Await] :
+ ConditionalExpression[?In, ?Yield, ?Await]
+ [+Yield] YieldExpression[?In, ?Await]
+ ArrowFunction[?In, ?Yield, ?Await]
+ AsyncArrowFunction[?In, ?Yield, ?Await]
+ LeftHandSideExpression[?Yield, ?Await] `=` AssignmentExpression[?In, ?Yield, ?Await] #assignment
+ LeftHandSideExpression[?Yield, ?Await] AssignmentOperator AssignmentExpression[?In, ?Yield, ?Await]
+
+AssignmentOperator : one of
+ `*=` `/=` `%=` `+=` `-=` `<<=` `>>=` `>>>=` `&=` `^=` `|=` `**=`
+
+
+AssignmentPattern[Yield, Await] :
+ ObjectAssignmentPattern[?Yield, ?Await]
+ ArrayAssignmentPattern[?Yield, ?Await]
+
+ObjectAssignmentPattern[Yield, Await] :
+ `{` `}`
+ `{` AssignmentRestProperty[?Yield, ?Await] `}`
+ `{` AssignmentPropertyList[?Yield, ?Await] `}`
+ `{` AssignmentPropertyList[?Yield, ?Await] `,` AssignmentRestProperty[?Yield, ?Await]? `}`
+
+ArrayAssignmentPattern[Yield, Await] :
+ `[` Elision? AssignmentRestElement[?Yield, ?Await]? `]`
+ `[` AssignmentElementList[?Yield, ?Await] `]`
+ `[` AssignmentElementList[?Yield, ?Await] `,` Elision? AssignmentRestElement[?Yield, ?Await]? `]`
+
+AssignmentRestProperty[Yield, Await] :
+ `...` DestructuringAssignmentTarget[?Yield, ?Await]
+
+AssignmentPropertyList[Yield, Await] :
+ AssignmentProperty[?Yield, ?Await]
+ AssignmentPropertyList[?Yield, ?Await] `,` AssignmentProperty[?Yield, ?Await]
+
+AssignmentElementList[Yield, Await] :
+ AssignmentElisionElement[?Yield, ?Await]
+ AssignmentElementList[?Yield, ?Await] `,` AssignmentElisionElement[?Yield, ?Await]
+
+AssignmentElisionElement[Yield, Await] :
+ Elision? AssignmentElement[?Yield, ?Await]
+
+AssignmentProperty[Yield, Await] :
+ IdentifierReference[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]?
+ PropertyName[?Yield, ?Await] `:` AssignmentElement[?Yield, ?Await]
+
+AssignmentElement[Yield, Await] :
+ DestructuringAssignmentTarget[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]?
+
+AssignmentRestElement[Yield, Await] :
+ `...` DestructuringAssignmentTarget[?Yield, ?Await]
+
+DestructuringAssignmentTarget[Yield, Await] :
+ LeftHandSideExpression[?Yield, ?Await]
+
+
+Expression[In, Yield, Await] :
+ AssignmentExpression[?In, ?Yield, ?Await]
+ Expression[?In, ?Yield, ?Await] `,` AssignmentExpression[?In, ?Yield, ?Await]
+
+
+Statement[Yield, Await, Return] :
+ BlockStatement[?Yield, ?Await, ?Return]
+ VariableStatement[?Yield, ?Await]
+ EmptyStatement
+ ExpressionStatement[?Yield, ?Await]
+ IfStatement[?Yield, ?Await, ?Return]
+ BreakableStatement[?Yield, ?Await, ?Return]
+ ContinueStatement[?Yield, ?Await]
+ BreakStatement[?Yield, ?Await]
+ [+Return] ReturnStatement[?Yield, ?Await]
+ WithStatement[?Yield, ?Await, ?Return]
+ LabelledStatement[?Yield, ?Await, ?Return]
+ ThrowStatement[?Yield, ?Await]
+ TryStatement[?Yield, ?Await, ?Return]
+ DebuggerStatement
+
+Declaration[Yield, Await] :
+ HoistableDeclaration[?Yield, ?Await, ~Default]
+ ClassDeclaration[?Yield, ?Await, ~Default]
+ LexicalDeclaration[+In, ?Yield, ?Await]
+
+HoistableDeclaration[Yield, Await, Default] :
+ FunctionDeclaration[?Yield, ?Await, ?Default]
+ GeneratorDeclaration[?Yield, ?Await, ?Default]
+ AsyncFunctionDeclaration[?Yield, ?Await, ?Default]
+ AsyncGeneratorDeclaration[?Yield, ?Await, ?Default]
+
+BreakableStatement[Yield, Await, Return] :
+ IterationStatement[?Yield, ?Await, ?Return]
+ SwitchStatement[?Yield, ?Await, ?Return]
+
+
+BlockStatement[Yield, Await, Return] :
+ Block[?Yield, ?Await, ?Return]
+
+Block[Yield, Await, Return] :
+ `{` StatementList[?Yield, ?Await, ?Return]? `}`
+
+StatementList[Yield, Await, Return] :
+ StatementListItem[?Yield, ?Await, ?Return]
+ StatementList[?Yield, ?Await, ?Return] StatementListItem[?Yield, ?Await, ?Return]
+
+StatementListItem[Yield, Await, Return] :
+ Statement[?Yield, ?Await, ?Return]
+ Declaration[?Yield, ?Await]
+
+
+LexicalDeclaration[In, Yield, Await] :
+ LetOrConst BindingList[?In, ?Yield, ?Await] `;`
+
+LetOrConst :
+ `let`
+ `const`
+
+BindingList[In, Yield, Await] :
+ LexicalBinding[?In, ?Yield, ?Await]
+ BindingList[?In, ?Yield, ?Await] `,` LexicalBinding[?In, ?Yield, ?Await]
+
+LexicalBinding[In, Yield, Await] :
+ BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]?
+ BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]
+
+
+VariableStatement[Yield, Await] :
+ `var` VariableDeclarationList[+In, ?Yield, ?Await] `;`
+
+VariableDeclarationList[In, Yield, Await] :
+ VariableDeclaration[?In, ?Yield, ?Await]
+ VariableDeclarationList[?In, ?Yield, ?Await] `,` VariableDeclaration[?In, ?Yield, ?Await]
+
+VariableDeclaration[In, Yield, Await] :
+ BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]?
+ BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]
+
+
+BindingPattern[Yield, Await] :
+ ObjectBindingPattern[?Yield, ?Await]
+ ArrayBindingPattern[?Yield, ?Await]
+
+ObjectBindingPattern[Yield, Await] :
+ `{` `}`
+ `{` BindingRestProperty[?Yield, ?Await] `}`
+ `{` BindingPropertyList[?Yield, ?Await] `}`
+ `{` BindingPropertyList[?Yield, ?Await] `,` BindingRestProperty[?Yield, ?Await]? `}`
+
+ArrayBindingPattern[Yield, Await] :
+ `[` Elision? BindingRestElement[?Yield, ?Await]? `]`
+ `[` BindingElementList[?Yield, ?Await] `]`
+ `[` BindingElementList[?Yield, ?Await] `,` Elision? BindingRestElement[?Yield, ?Await]? `]`
+
+BindingRestProperty[Yield, Await] :
+ `...` BindingIdentifier[?Yield, ?Await]
+
+BindingPropertyList[Yield, Await] :
+ BindingProperty[?Yield, ?Await]
+ BindingPropertyList[?Yield, ?Await] `,` BindingProperty[?Yield, ?Await]
+
+BindingElementList[Yield, Await] :
+ BindingElisionElement[?Yield, ?Await]
+ BindingElementList[?Yield, ?Await] `,` BindingElisionElement[?Yield, ?Await]
+
+BindingElisionElement[Yield, Await] :
+ Elision? BindingElement[?Yield, ?Await]
+
+BindingProperty[Yield, Await] :
+ SingleNameBinding[?Yield, ?Await]
+ PropertyName[?Yield, ?Await] `:` BindingElement[?Yield, ?Await]
+
+BindingElement[Yield, Await] :
+ SingleNameBinding[?Yield, ?Await]
+ BindingPattern[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]?
+
+SingleNameBinding[Yield, Await] :
+ BindingIdentifier[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]?
+
+BindingRestElement[Yield, Await] :
+ `...` BindingIdentifier[?Yield, ?Await]
+ `...` BindingPattern[?Yield, ?Await]
+
+
+EmptyStatement :
+ `;`
+
+
+ExpressionStatement[Yield, Await] :
+ [lookahead <! {`{`, `function`, `async`, `class`, `let`}] Expression[+In, ?Yield, ?Await] `;`
+
+
+IfStatement[Yield, Await, Return] :
+ `if` `(` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return] `else` Statement[?Yield, ?Await, ?Return]
+ `if` `(` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+
+
+IterationStatement[Yield, Await, Return] :
+ `do` Statement[?Yield, ?Await, ?Return] `while` `(` Expression[+In, ?Yield, ?Await] `)` `;`
+ `while` `(` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` [lookahead != `let`] Expression[~In, ?Yield, ?Await]? `;` Expression[+In, ?Yield, ?Await]? `;` Expression[+In, ?Yield, ?Await]? `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` `var` VariableDeclarationList[~In, ?Yield, ?Await] `;` Expression[+In, ?Yield, ?Await]? `;` Expression[+In, ?Yield, ?Await]? `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` ForLexicalDeclaration[~In, ?Yield, ?Await] Expression[+In, ?Yield, ?Await]? `;` Expression[+In, ?Yield, ?Await]? `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` [lookahead != `let`] LeftHandSideExpression[?Yield, ?Await] `in` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` `var` ForBinding[?Yield, ?Await] `in` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` ForDeclaration[?Yield, ?Await] `in` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` [lookahead <! {`async`, `let`} ] LeftHandSideExpression[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` `var` ForBinding[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ `for` `(` ForDeclaration[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ [+Await] `for` `await` `(` [lookahead <! {`async`, `let`} ] LeftHandSideExpression[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ [+Await] `for` `await` `(` `var` ForBinding[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+ [+Await] `for` `await` `(` ForDeclaration[?Yield, ?Await] `of` AssignmentExpression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+
+ForDeclaration[Yield, Await] :
+ LetOrConst ForBinding[?Yield, ?Await]
+
+ForBinding[Yield, Await] :
+ BindingIdentifier[?Yield, ?Await]
+ BindingPattern[?Yield, ?Await]
+
+
+ContinueStatement[Yield, Await] :
+ `continue` `;`
+ `continue` LabelIdentifier[?Yield, ?Await] `;`
+
+
+BreakStatement[Yield, Await] :
+ `break` `;`
+ `break` LabelIdentifier[?Yield, ?Await] `;`
+
+
+ReturnStatement[Yield, Await] :
+ `return` `;`
+ `return` Expression[+In, ?Yield, ?Await] `;`
+
+
+WithStatement[Yield, Await, Return] :
+ `with` `(` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+
+
+SwitchStatement[Yield, Await, Return] :
+ `switch` `(` Expression[+In, ?Yield, ?Await] `)` CaseBlock[?Yield, ?Await, ?Return]
+
+CaseBlock[Yield, Await, Return] :
+ `{` CaseClauses[?Yield, ?Await, ?Return]? `}`
+ `{` CaseClauses[?Yield, ?Await, ?Return]? DefaultClause[?Yield, ?Await, ?Return] CaseClauses[?Yield, ?Await, ?Return]? `}`
+
+CaseClauses[Yield, Await, Return] :
+ CaseClause[?Yield, ?Await, ?Return]
+ CaseClauses[?Yield, ?Await, ?Return] CaseClause[?Yield, ?Await, ?Return]
+
+CaseClause[Yield, Await, Return] :
+ `case` Expression[+In, ?Yield, ?Await] `:` StatementList[?Yield, ?Await, ?Return]?
+
+DefaultClause[Yield, Await, Return] :
+ `default` `:` StatementList[?Yield, ?Await, ?Return]?
+
+
+LabelledStatement[Yield, Await, Return] :
+ LabelIdentifier[?Yield, ?Await] `:` LabelledItem[?Yield, ?Await, ?Return]
+
+LabelledItem[Yield, Await, Return] :
+ Statement[?Yield, ?Await, ?Return]
+ FunctionDeclaration[?Yield, ?Await, ~Default]
+
+
+ThrowStatement[Yield, Await] :
+ `throw` Expression[+In, ?Yield, ?Await] `;`
+
+
+TryStatement[Yield, Await, Return] :
+ `try` Block[?Yield, ?Await, ?Return] Catch[?Yield, ?Await, ?Return]
+ `try` Block[?Yield, ?Await, ?Return] Finally[?Yield, ?Await, ?Return]
+ `try` Block[?Yield, ?Await, ?Return] Catch[?Yield, ?Await, ?Return] Finally[?Yield, ?Await, ?Return]
+
+Catch[Yield, Await, Return] :
+ `catch` `(` CatchParameter[?Yield, ?Await] `)` Block[?Yield, ?Await, ?Return]
+ `catch` Block[?Yield, ?Await, ?Return]
+
+Finally[Yield, Await, Return] :
+ `finally` Block[?Yield, ?Await, ?Return]
+
+CatchParameter[Yield, Await] :
+ BindingIdentifier[?Yield, ?Await]
+ BindingPattern[?Yield, ?Await]
+
+
+DebuggerStatement :
+ `debugger` `;`
+
+
+FunctionDeclaration[Yield, Await, Default] :
+ `function` BindingIdentifier[?Yield, ?Await] `(` FormalParameters[~Yield, ~Await] `)` `{` FunctionBody[~Yield, ~Await] `}`
+ [+Default] `function` `(` FormalParameters[~Yield, ~Await] `)` `{` FunctionBody[~Yield, ~Await] `}`
+
+FunctionExpression :
+ `function` BindingIdentifier[~Yield, ~Await]? `(` FormalParameters[~Yield, ~Await] `)` `{` FunctionBody[~Yield, ~Await] `}`
+
+UniqueFormalParameters[Yield, Await] :
+ FormalParameters[?Yield, ?Await]
+
+FormalParameters[Yield, Await] :
+ [empty]
+ FunctionRestParameter[?Yield, ?Await]
+ FormalParameterList[?Yield, ?Await]
+ FormalParameterList[?Yield, ?Await] `,`
+ FormalParameterList[?Yield, ?Await] `,` FunctionRestParameter[?Yield, ?Await]
+
+FormalParameterList[Yield, Await] :
+ FormalParameter[?Yield, ?Await]
+ FormalParameterList[?Yield, ?Await] `,` FormalParameter[?Yield, ?Await]
+
+FunctionRestParameter[Yield, Await] :
+ BindingRestElement[?Yield, ?Await]
+
+FormalParameter[Yield, Await] :
+ BindingElement[?Yield, ?Await]
+
+FunctionBody[Yield, Await] :
+ FunctionStatementList[?Yield, ?Await]
+
+FunctionStatementList[Yield, Await] :
+ StatementList[?Yield, ?Await, +Return]?
+
+
+ArrowFunction[In, Yield, Await] :
+ ArrowParameters[?Yield, ?Await] `=>` ConciseBody[?In]
+
+ArrowParameters[Yield, Await] :
+ BindingIdentifier[?Yield, ?Await]
+ CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] #parencover
+
+ConciseBody[In] :
+ [lookahead != `{` ] AssignmentExpression[?In, ~Yield, ~Await]
+ `{` FunctionBody[~Yield, ~Await] `}`
+
+
+ArrowFormalParameters[Yield, Await] :
+ `(` UniqueFormalParameters[?Yield, ?Await] `)`
+
+
+MethodDefinition[Yield, Await] :
+ PropertyName[?Yield, ?Await] `(` UniqueFormalParameters[~Yield, ~Await] `)` `{` FunctionBody[~Yield, ~Await] `}`
+ GeneratorMethod[?Yield, ?Await]
+ AsyncMethod[?Yield, ?Await]
+ AsyncGeneratorMethod[?Yield, ?Await]
+ `get` PropertyName[?Yield, ?Await] `(` `)` `{` FunctionBody[~Yield, ~Await] `}`
+ `set` PropertyName[?Yield, ?Await] `(` PropertySetParameterList `)` `{` FunctionBody[~Yield, ~Await] `}`
+
+PropertySetParameterList :
+ FormalParameter[~Yield, ~Await]
+
+
+GeneratorMethod[Yield, Await] :
+ `*` PropertyName[?Yield, ?Await] `(` UniqueFormalParameters[+Yield, ~Await] `)` `{` GeneratorBody `}`
+
+GeneratorDeclaration[Yield, Await, Default] :
+ `function` `*` BindingIdentifier[?Yield, ?Await] `(` FormalParameters[+Yield, ~Await] `)` `{` GeneratorBody `}`
+ [+Default] `function` `*` `(` FormalParameters[+Yield, ~Await] `)` `{` GeneratorBody `}`
+
+GeneratorExpression :
+ `function` `*` BindingIdentifier[+Yield, ~Await]? `(` FormalParameters[+Yield, ~Await] `)` `{` GeneratorBody `}`
+
+GeneratorBody :
+ FunctionBody[+Yield, ~Await]
+
+YieldExpression[In, Await] :
+ `yield`
+ `yield` AssignmentExpression[?In, +Yield, ?Await]
+ `yield` `*` AssignmentExpression[?In, +Yield, ?Await]
+
+
+AsyncGeneratorMethod[Yield, Await] :
+ `async` `*` PropertyName[?Yield, ?Await] `(` UniqueFormalParameters[+Yield, +Await] `)` `{` AsyncGeneratorBody `}`
+
+AsyncGeneratorDeclaration[Yield, Await, Default] :
+ `async` `function` `*` BindingIdentifier[?Yield, ?Await] `(` FormalParameters[+Yield, +Await] `)` `{` AsyncGeneratorBody `}`
+ [+Default] `async` `function` `*` `(` FormalParameters[+Yield, +Await] `)` `{` AsyncGeneratorBody `}`
+
+AsyncGeneratorExpression :
+ `async` `function` `*` BindingIdentifier[+Yield, +Await]? `(` FormalParameters[+Yield, +Await] `)` `{` AsyncGeneratorBody `}`
+
+AsyncGeneratorBody :
+ FunctionBody[+Yield, +Await]
+
+
+ClassDeclaration[Yield, Await, Default] :
+ `class` BindingIdentifier[?Yield, ?Await] ClassTail[?Yield, ?Await]
+ [+Default] `class` ClassTail[?Yield, ?Await]
+
+ClassExpression[Yield, Await] :
+ `class` BindingIdentifier[?Yield, ?Await]? ClassTail[?Yield, ?Await]
+
+ClassTail[Yield, Await] :
+ ClassHeritage[?Yield, ?Await]? `{` ClassBody[?Yield, ?Await]? `}`
+
+ClassHeritage[Yield, Await] :
+ `extends` LeftHandSideExpression[?Yield, ?Await]
+
+ClassBody[Yield, Await] :
+ ClassElementList[?Yield, ?Await]
+
+ClassElementList[Yield, Await] :
+ ClassElement[?Yield, ?Await]
+ ClassElementList[?Yield, ?Await] ClassElement[?Yield, ?Await]
+
+ClassElement[Yield, Await] :
+ MethodDefinition[?Yield, ?Await]
+ `static` MethodDefinition[?Yield, ?Await]
+ `;`
+
+
+AsyncFunctionDeclaration[Yield, Await, Default] :
+ `async` `function` BindingIdentifier[?Yield, ?Await] `(` FormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
+ [+Default] `async` `function` `(` FormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
+
+AsyncFunctionExpression :
+ `async` `function` `(` FormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
+ `async` `function` BindingIdentifier[~Yield, +Await] `(` FormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
+
+AsyncMethod[Yield, Await] :
+ `async` PropertyName[?Yield, ?Await] `(` UniqueFormalParameters[~Yield, +Await] `)` `{` AsyncFunctionBody `}`
+
+AsyncFunctionBody :
+ FunctionBody[~Yield, +Await]
+
+AwaitExpression[Yield] :
+ `await` UnaryExpression[?Yield, +Await]
+
+
+AsyncArrowFunction[In, Yield, Await] :
+ `async` AsyncArrowBindingIdentifier[?Yield] `=>` AsyncConciseBody[?In]
+ CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] `=>` AsyncConciseBody[?In] #callcover
+
+AsyncConciseBody[In] :
+ [lookahead != `{`] AssignmentExpression[?In, ~Yield, +Await]
+ `{` AsyncFunctionBody `}`
+
+AsyncArrowBindingIdentifier[Yield] :
+ BindingIdentifier[?Yield, +Await]
+
+CoverCallExpressionAndAsyncArrowHead[Yield, Await] :
+ MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]
+
+
+AsyncArrowHead :
+ `async` ArrowFormalParameters[~Yield, +Await]
+
+
+Script :
+ ScriptBody?
+
+ScriptBody :
+ StatementList[~Yield, ~Await, ~Return]
+
+
+Module :
+ ModuleBody?
+
+ModuleBody :
+ ModuleItemList
+
+ModuleItemList :
+ ModuleItem
+ ModuleItemList ModuleItem
+
+ModuleItem :
+ ImportDeclaration
+ ExportDeclaration
+ StatementListItem[~Yield, ~Await, ~Return]
+
+
+ImportDeclaration :
+ `import` ImportClause FromClause `;`
+ `import` ModuleSpecifier `;`
+
+ImportClause :
+ ImportedDefaultBinding
+ NameSpaceImport
+ NamedImports
+ ImportedDefaultBinding `,` NameSpaceImport
+ ImportedDefaultBinding `,` NamedImports
+
+ImportedDefaultBinding :
+ ImportedBinding
+
+NameSpaceImport :
+ `*` `as` ImportedBinding
+
+NamedImports :
+ `{` `}`
+ `{` ImportsList `}`
+ `{` ImportsList `,` `}`
+
+FromClause :
+ `from` ModuleSpecifier
+
+ImportsList :
+ ImportSpecifier
+ ImportsList `,` ImportSpecifier
+
+ImportSpecifier :
+ ImportedBinding
+ IdentifierName `as` ImportedBinding
+
+ModuleSpecifier :
+ StringLiteral
+
+ImportedBinding :
+ BindingIdentifier[~Yield, ~Await]
+
+
+ExportDeclaration :
+ `export` `*` FromClause `;`
+ `export` ExportClause FromClause `;`
+ `export` ExportClause `;`
+ `export` VariableStatement[~Yield, ~Await]
+ `export` Declaration[~Yield, ~Await]
+ `export` `default` HoistableDeclaration[~Yield, ~Await, +Default]
+ `export` `default` ClassDeclaration[~Yield, ~Await, +Default]
+ `export` `default` [lookahead <! {`function`, `async`, `class`}] AssignmentExpression[+In, ~Yield, ~Await] `;`
+
+ExportClause :
+ `{` `}`
+ `{` ExportsList `}`
+ `{` ExportsList `,` `}`
+
+ExportsList :
+ ExportSpecifier
+ ExportsList `,` ExportSpecifier
+
+ExportSpecifier :
+ IdentifierName
+ IdentifierName `as` IdentifierName
+
+
+uri :::
+ uriCharacters?
+
+uriCharacters :::
+ uriCharacter uriCharacters?
+
+uriCharacter :::
+ uriReserved
+ uriUnescaped
+ uriEscaped
+
+uriReserved ::: one of
+ `;` `/` `?` `:` `@` `&` `=` `+` `$` `,`
+
+uriUnescaped :::
+ uriAlpha
+ DecimalDigit
+ uriMark
+
+uriEscaped :::
+ `%` HexDigit HexDigit
+
+uriAlpha ::: one of
+ `a` `b` `c` `d` `e` `f` `g` `h` `i` `j` `k` `l` `m` `n` `o` `p` `q` `r` `s` `t` `u` `v` `w` `x` `y` `z`
+ `A` `B` `C` `D` `E` `F` `G` `H` `I` `J` `K` `L` `M` `N` `O` `P` `Q` `R` `S` `T` `U` `V` `W` `X` `Y` `Z`
+
+uriMark ::: one of
+ `-` `_` `.` `!` `~` `*` `'` `(` `)`
+
+
+NativeFunction :
+ `function` PropertyName[~Yield, ~Await]? `(` FormalParameters[~Yield, ~Await] `)` `{` `[` `native` `code` `]` `}`
+
+
+Pattern[U, N] ::
+ Disjunction[?U, ?N]
+
+Disjunction[U, N] ::
+ Alternative[?U, ?N]
+ Alternative[?U, ?N] `|` Disjunction[?U, ?N]
+
+Alternative[U, N] ::
+ [empty]
+ Alternative[?U, ?N] Term[?U, ?N]
+
+Term[U, N] ::
+ Assertion[?U, ?N]
+ Atom[?U, ?N]
+ Atom[?U, ?N] Quantifier
+
+Assertion[U, N] ::
+ `^`
+ `$`
+ `\` `b`
+ `\` `B`
+ `(` `?` `=` Disjunction[?U, ?N] `)`
+ `(` `?` `!` Disjunction[?U, ?N] `)`
+ `(` `?` `<=` Disjunction[?U, ?N] `)`
+ `(` `?` `<!` Disjunction[?U, ?N] `)`
+
+Quantifier ::
+ QuantifierPrefix
+ QuantifierPrefix `?`
+
+QuantifierPrefix ::
+ `*`
+ `+`
+ `?`
+ `{` DecimalDigits `}`
+ `{` DecimalDigits `,` `}`
+ `{` DecimalDigits `,` DecimalDigits `}`
+
+Atom[U, N] ::
+ PatternCharacter
+ `.`
+ `\` AtomEscape[?U, ?N]
+ CharacterClass[?U]
+ `(` GroupSpecifier[?U] Disjunction[?U, ?N] `)`
+ `(` `?` `:` Disjunction[?U, ?N] `)`
+
+SyntaxCharacter :: one of
+ `^` `$` `\` `.` `*` `+` `?` `(` `)` `[` `]` `{` `}` `|`
+
+PatternCharacter ::
+ SourceCharacter but not SyntaxCharacter
+
+AtomEscape[U, N] ::
+ DecimalEscape
+ CharacterClassEscape[?U]
+ CharacterEscape[?U]
+ [+N] `k` GroupName[?U]
+
+CharacterEscape[U] ::
+ ControlEscape
+ `c` ControlLetter
+ `0` [lookahead <! DecimalDigit]
+ HexEscapeSequence
+ RegExpUnicodeEscapeSequence[?U]
+ IdentityEscape[?U]
+
+ControlEscape :: one of
+ `f` `n` `r` `t` `v`
+
+ControlLetter :: one of
+ `a` `b` `c` `d` `e` `f` `g` `h` `i` `j` `k` `l` `m` `n` `o` `p` `q` `r` `s` `t` `u` `v` `w` `x` `y` `z`
+ `A` `B` `C` `D` `E` `F` `G` `H` `I` `J` `K` `L` `M` `N` `O` `P` `Q` `R` `S` `T` `U` `V` `W` `X` `Y` `Z`
+
+GroupSpecifier[U] ::
+ [empty]
+ `?` GroupName[?U]
+
+GroupName[U] ::
+ `<` RegExpIdentifierName[?U] `>`
+
+RegExpIdentifierName[U] ::
+ RegExpIdentifierStart[?U]
+ RegExpIdentifierName[?U] RegExpIdentifierPart[?U]
+
+RegExpIdentifierStart[U] ::
+ UnicodeIDStart
+ `$`
+ `_`
+ `\` RegExpUnicodeEscapeSequence[?U]
+
+RegExpIdentifierPart[U] ::
+ UnicodeIDContinue
+ `$`
+ `\` RegExpUnicodeEscapeSequence[?U]
+ <ZWNJ>
+ <ZWJ>
+
+RegExpUnicodeEscapeSequence[U] ::
+ [+U] `u` LeadSurrogate `\u` TrailSurrogate
+ [+U] `u` LeadSurrogate
+ [+U] `u` TrailSurrogate
+ [+U] `u` NonSurrogate
+ [~U] `u` Hex4Digits
+ [+U] `u{` CodePoint `}`
+
+
+LeadSurrogate ::
+ Hex4Digits [> but only if the SV of |Hex4Digits| is in the inclusive range 0xD800 to 0xDBFF]
+
+TrailSurrogate ::
+ Hex4Digits [> but only if the SV of |Hex4Digits| is in the inclusive range 0xDC00 to 0xDFFF]
+
+NonSurrogate ::
+ Hex4Digits [> but only if the SV of |Hex4Digits| is not in the inclusive range 0xD800 to 0xDFFF]
+
+IdentityEscape[U] ::
+ [+U] SyntaxCharacter
+ [+U] `/`
+ [~U] SourceCharacter but not UnicodeIDContinue
+
+DecimalEscape ::
+ NonZeroDigit DecimalDigits? [lookahead <! DecimalDigit]
+
+CharacterClassEscape[U] ::
+ `d`
+ `D`
+ `s`
+ `S`
+ `w`
+ `W`
+ [+U] `p{` UnicodePropertyValueExpression `}`
+ [+U] `P{` UnicodePropertyValueExpression `}`
+
+UnicodePropertyValueExpression ::
+ UnicodePropertyName `=` UnicodePropertyValue
+ LoneUnicodePropertyNameOrValue
+
+UnicodePropertyName ::
+ UnicodePropertyNameCharacters
+
+UnicodePropertyNameCharacters ::
+ UnicodePropertyNameCharacter UnicodePropertyNameCharacters?
+
+UnicodePropertyValue ::
+ UnicodePropertyValueCharacters
+
+LoneUnicodePropertyNameOrValue ::
+ UnicodePropertyValueCharacters
+
+UnicodePropertyValueCharacters ::
+ UnicodePropertyValueCharacter UnicodePropertyValueCharacters?
+
+UnicodePropertyValueCharacter ::
+ UnicodePropertyNameCharacter
+ `0`
+ `1`
+ `2`
+ `3`
+ `4`
+ `5`
+ `6`
+ `7`
+ `8`
+ `9`
+
+UnicodePropertyNameCharacter ::
+ ControlLetter
+ `_`
+
+CharacterClass[U] ::
+ `[` [lookahead != `^`] ClassRanges[?U] `]`
+ `[` `^` ClassRanges[?U] `]`
+
+ClassRanges[U] ::
+ [empty]
+ NonemptyClassRanges[?U]
+
+NonemptyClassRanges[U] ::
+ ClassAtom[?U]
+ ClassAtom[?U] NonemptyClassRangesNoDash[?U]
+ ClassAtom[?U] `-` ClassAtom[?U] ClassRanges[?U]
+
+NonemptyClassRangesNoDash[U] ::
+ ClassAtom[?U]
+ ClassAtomNoDash[?U] NonemptyClassRangesNoDash[?U]
+ ClassAtomNoDash[?U] `-` ClassAtom[?U] ClassRanges[?U]
+
+ClassAtom[U] ::
+ `-`
+ ClassAtomNoDash[?U]
+
+ClassAtomNoDash[U] ::
+ SourceCharacter but not one of `\` or `]` or `-`
+ `\` ClassEscape[?U]
+
+ClassEscape[U] ::
+ `b`
+ [+U] `-`
+ CharacterClassEscape[?U]
+ CharacterEscape[?U]
+
+
+NumericLiteral ::
+ DecimalLiteral
+ BinaryIntegerLiteral
+ OctalIntegerLiteral
+ HexIntegerLiteral
+ LegacyOctalIntegerLiteral
+
+LegacyOctalIntegerLiteral ::
+ `0` OctalDigit
+ LegacyOctalIntegerLiteral OctalDigit
+
+DecimalIntegerLiteral ::
+ `0`
+ NonZeroDigit DecimalDigits?
+ NonOctalDecimalIntegerLiteral
+
+NonOctalDecimalIntegerLiteral ::
+ `0` NonOctalDigit
+ LegacyOctalLikeDecimalIntegerLiteral NonOctalDigit
+ NonOctalDecimalIntegerLiteral DecimalDigit
+
+LegacyOctalLikeDecimalIntegerLiteral ::
+ `0` OctalDigit
+ LegacyOctalLikeDecimalIntegerLiteral OctalDigit
+
+NonOctalDigit :: one of
+ `8` `9`
+
+
+EscapeSequence ::
+ CharacterEscapeSequence
+ LegacyOctalEscapeSequence
+ HexEscapeSequence
+ UnicodeEscapeSequence
+
+LegacyOctalEscapeSequence ::
+ OctalDigit [lookahead <! OctalDigit]
+ ZeroToThree OctalDigit [lookahead <! OctalDigit]
+ FourToSeven OctalDigit
+ ZeroToThree OctalDigit OctalDigit
+
+ZeroToThree :: one of
+ `0` `1` `2` `3`
+
+FourToSeven :: one of
+ `4` `5` `6` `7`
+
+
+Comment ::
+ MultiLineComment
+ SingleLineComment
+ SingleLineHTMLOpenComment
+ SingleLineHTMLCloseComment
+ SingleLineDelimitedComment
+
+MultiLineComment ::
+ `/*` FirstCommentLine? LineTerminator MultiLineCommentChars? `*/` HTMLCloseComment?
+
+FirstCommentLine ::
+ SingleLineDelimitedCommentChars
+
+SingleLineHTMLOpenComment ::
+ `<!--` SingleLineCommentChars?
+
+SingleLineHTMLCloseComment ::
+ LineTerminatorSequence HTMLCloseComment
+
+SingleLineDelimitedComment ::
+ `/*` SingleLineDelimitedCommentChars? `*/`
+
+HTMLCloseComment ::
+ WhiteSpaceSequence? SingleLineDelimitedCommentSequence? `-->` SingleLineCommentChars?
+
+SingleLineDelimitedCommentChars ::
+ SingleLineNotAsteriskChar SingleLineDelimitedCommentChars?
+ `*` SingleLinePostAsteriskCommentChars?
+
+SingleLineNotAsteriskChar ::
+ SourceCharacter but not one of `*` or LineTerminator
+
+SingleLinePostAsteriskCommentChars ::
+ SingleLineNotForwardSlashOrAsteriskChar SingleLineDelimitedCommentChars?
+ `*` SingleLinePostAsteriskCommentChars?
+
+SingleLineNotForwardSlashOrAsteriskChar ::
+ SourceCharacter but not one of `/` or `*` or LineTerminator
+
+WhiteSpaceSequence ::
+ WhiteSpace WhiteSpaceSequence?
+
+SingleLineDelimitedCommentSequence ::
+ SingleLineDelimitedComment WhiteSpaceSequence? SingleLineDelimitedCommentSequence?
+
+
+Term[U, N] ::
+ [+U] Assertion[+U, ?N]
+ [+U] Atom[+U, ?N]
+ [+U] Atom[+U, ?N] Quantifier
+ [~U] QuantifiableAssertion[?N] Quantifier
+ [~U] Assertion[~U, ?N]
+ [~U] ExtendedAtom[?N] Quantifier
+ [~U] ExtendedAtom[?N]
+
+Assertion[U, N] ::
+ `^`
+ `$`
+ `\` `b`
+ `\` `B`
+ [+U] `(` `?` `=` Disjunction[+U, ?N] `)`
+ [+U] `(` `?` `!` Disjunction[+U, ?N] `)`
+ [~U] QuantifiableAssertion[?N]
+ `(` `?` `<=` Disjunction[?U, ?N] `)`
+ `(` `?` `<!` Disjunction[?U, ?N] `)`
+
+QuantifiableAssertion[N] ::
+ `(` `?` `=` Disjunction[~U, ?N] `)`
+ `(` `?` `!` Disjunction[~U, ?N] `)`
+
+ExtendedAtom[N] ::
+ `.`
+ `\` AtomEscape[~U, ?N]
+ `\` [lookahead == `c`]
+ CharacterClass[~U]
+ `(` Disjunction[~U, ?N] `)`
+ `(` `?` `:` Disjunction[~U, ?N] `)`
+ InvalidBracedQuantifier
+ ExtendedPatternCharacter
+
+InvalidBracedQuantifier ::
+ `{` DecimalDigits `}`
+ `{` DecimalDigits `,` `}`
+ `{` DecimalDigits `,` DecimalDigits `}`
+
+ExtendedPatternCharacter ::
+ SourceCharacter but not one of `^` `$` `\` `.` `*` `+` `?` `(` `)` `[` `|`
+
+AtomEscape[U, N] ::
+ [+U] DecimalEscape
+ [~U] DecimalEscape [> but only if the CapturingGroupNumber of |DecimalEscape| is <= _NcapturingParens_]
+ CharacterClassEscape[?U]
+ CharacterEscape[~U, ?N]
+ [+N] `k` GroupName[?U]
+
+CharacterEscape[U, N] ::
+ ControlEscape
+ `c` ControlLetter
+ `0` [lookahead <! DecimalDigit]
+ HexEscapeSequence
+ RegExpUnicodeEscapeSequence[?U]
+ [~U] LegacyOctalEscapeSequence
+ IdentityEscape[?U, ?N]
+
+IdentityEscape[U, N] ::
+ [+U] SyntaxCharacter
+ [+U] `/`
+ [~U] SourceCharacterIdentityEscape[?N]
+
+SourceCharacterIdentityEscape[N] ::
+ [~N] SourceCharacter but not `c`
+ [+N] SourceCharacter but not one of `c` or `k`
+
+ClassAtomNoDash[U] ::
+ SourceCharacter but not one of `\` or `]` or `-`
+ `\` ClassEscape[?U, ~N]
+ `\` [lookahead == `c`]
+
+ClassEscape[U, N] ::
+ `b`
+ [+U] `-`
+ [~U] `c` ClassControlLetter
+ CharacterClassEscape[?U]
+ CharacterEscape[?U, ?N]
+
+ClassControlLetter ::
+ DecimalDigit
+ `_`
+
+
+IfStatement[Yield, Await, Return] :
+ `if` `(` Expression[+In, ?Yield, ?Await] `)` FunctionDeclaration[?Yield, ?Await, ~Default] `else` Statement[?Yield, ?Await, ?Return]
+ `if` `(` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return] `else` FunctionDeclaration[?Yield, ?Await, ~Default]
+ `if` `(` Expression[+In, ?Yield, ?Await] `)` FunctionDeclaration[?Yield, ?Await, ~Default] `else` FunctionDeclaration[?Yield, ?Await, ~Default]
+ `if` `(` Expression[+In, ?Yield, ?Await] `)` FunctionDeclaration[?Yield, ?Await, ~Default]
+
+
+IterationStatement[Yield, Await, Return] :
+ `for` `(` `var` BindingIdentifier[?Yield, ?Await] Initializer[~In, ?Yield, ?Await] `in` Expression[+In, ?Yield, ?Await] `)` Statement[?Yield, ?Await, ?Return]
+
diff --git a/third_party/rust/jsparagus/js_parser/try_it.py b/third_party/rust/jsparagus/js_parser/try_it.py
new file mode 100755
index 0000000000..d8cb89457a
--- /dev/null
+++ b/third_party/rust/jsparagus/js_parser/try_it.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+
+"""js.py - Repl-like toy to explore parsing of lines of JS.
+
+See README.md for instructions.
+"""
+
+import argparse
+import traceback
+from .lexer import JSLexer
+from .parser import JSParser
+from jsparagus.lexer import SyntaxError
+
+
+def interactive_input(lexer, prompt="js> "):
+ while True:
+ line = input(prompt)
+ lexer.write(line + "\n")
+ if lexer.can_close():
+ return lexer.close()
+ prompt = "..> "
+
+
+def rpl():
+ """Read-print loop."""
+ while True:
+ parser = JSLexer(JSParser(), filename="<stdin>")
+ try:
+ result = interactive_input(parser)
+ except EOFError:
+ print()
+ break
+ except SyntaxError:
+ traceback.print_exc(limit=0)
+ continue
+ print(result)
+
+
+def main():
+ parser = argparse.ArgumentParser(description="Try out the JS parser.")
+ parser.add_argument('input_file', metavar='FILE', nargs='?',
+ help=".js file to parse")
+ options = parser.parse_args()
+
+ if options.input_file is not None:
+ with open(options.input_file) as f:
+ source = f.readlines()
+ lexer = JSLexer(JSParser())
+ for line in source:
+ print(line.rstrip())
+ lexer.write(line)
+ ast = lexer.close()
+ print(ast)
+ else:
+ rpl()
+
+
+if __name__ == '__main__':
+ main()