[][src]Constant tree_sitter_javascript::GRAMMAR

pub const GRAMMAR: &'static str = "const PREC = {\n  COMMENT: 1, // Prefer comments over regexes\n  STRING: 2,  // In a string, prefer string characters over comments\n\n  COMMA: -1,\n  OBJECT: -1,\n  DECLARATION: 1,\n  ASSIGN: 0,\n  TERNARY: 1,\n  OR: 2,\n  AND: 3,\n  REL: 4,\n  PLUS: 5,\n  TIMES: 6,\n  EXP: 7,\n  TYPEOF: 8,\n  DELETE: 8,\n  VOID: 8,\n  NOT: 9,\n  NEG: 10,\n  INC: 11,\n  CALL: 12,\n  NEW: 13,\n  MEMBER: 14\n};\n\nmodule.exports = grammar({\n  name: \'javascript\',\n\n  externals: $ => [\n    $._automatic_semicolon,\n    $._template_chars\n  ],\n\n  extras: $ => [\n    $.comment,\n    /[\\s\\uFEFF\\u2060\\u200B\\u00A0]/\n  ],\n\n  supertypes: $ => [\n    $._statement,\n    $._declaration,\n    $._expression,\n    $._destructuring_pattern,\n  ],\n\n  inline: $ => [\n    $._call_signature,\n    $._primary_expression,\n    $._statement,\n    $._expressions,\n    $._semicolon,\n    $._formal_parameter,\n    $._destructuring_pattern,\n    $._reserved_identifier,\n    $._jsx_attribute,\n    $._jsx_element_name,\n    $._jsx_child,\n    $._jsx_element,\n    $._jsx_attribute_name,\n    $._jsx_attribute_value,\n    $._jsx_identifier,\n    $._lhs_expression,\n  ],\n\n  conflicts: $ => [\n    [$._expression, $._property_name],\n    [$._expression, $._property_name, $.arrow_function],\n    [$._expression, $.arrow_function],\n    [$._expression, $.method_definition],\n    [$._expression, $.formal_parameters],\n    [$._expression, $.rest_parameter],\n    [$.labeled_statement, $._property_name],\n    [$.assignment_pattern, $.assignment_expression],\n    [$.computed_property_name, $.array],\n    [$._for_header, $._expression],\n  ],\n\n  word: $ => $.identifier,\n\n  rules: {\n    program: $ => seq(\n      optional($.hash_bang_line),\n      repeat($._statement)\n    ),\n\n    hash_bang_line: $ => /#!.*/,\n\n    //\n    // Export declarations\n    //\n\n    export_statement: $ => choice(\n      seq(\n        \'export\',\n        choice(\n          seq(\'*\', $._from_clause, $._semicolon),\n          seq($.export_clause, $._from_clause, $._semicolon),\n          seq($.export_clause, $._semicolon)\n        )\n      ),\n      seq(\n        repeat(field(\'decorator\', $.decorator)),\n        \'export\',\n        choice(\n          field(\'declaration\', $._declaration),\n          seq(\n            \'default\',\n            field(\'value\', $._expression),\n            $._semicolon\n          )\n        )\n      ),\n    ),\n\n    export_clause: $ => seq(\n      \'{\',\n      commaSep(alias($._import_export_specifier, $.export_specifier)),\n      optional(\',\'),\n      \'}\'\n    ),\n\n    _import_export_specifier: $ => seq(\n      field(\'name\', $.identifier),\n      optional(seq(\n        \'as\',\n        field(\'alias\', $.identifier)\n      ))\n    ),\n\n    _declaration: $ => choice(\n      $.function_declaration,\n      $.generator_function_declaration,\n      $.class_declaration,\n      $.lexical_declaration,\n      $.variable_declaration\n    ),\n\n    //\n    // Import declarations\n    //\n\n    import: $ => token(\'import\'),\n\n    import_statement: $ => prec(1, seq(\n      \'import\',\n      choice(\n        seq($.import_clause, $._from_clause),\n        field(\'source\', $.string)\n      ),\n      $._semicolon\n    )),\n\n    import_clause: $ => choice(\n      $.namespace_import,\n      $.named_imports,\n      seq(\n        $.identifier,\n        optional(seq(\n          \',\',\n          choice(\n            $.namespace_import,\n            $.named_imports\n          )\n        ))\n      )\n    ),\n\n    _from_clause: $ => seq(\n      \"from\", field(\'source\', $.string)\n    ),\n\n    namespace_import: $ => seq(\n      \"*\", \"as\", $.identifier\n    ),\n\n    named_imports: $ => seq(\n      \'{\',\n      commaSep(alias($._import_export_specifier, $.import_specifier)),\n      optional(\',\'),\n      \'}\'\n    ),\n\n    //\n    // Statements\n    //\n\n    _statement: $ => choice(\n      $.export_statement,\n      $.import_statement,\n      $.debugger_statement,\n      $.expression_statement,\n      $._declaration,\n      $.statement_block,\n\n      $.if_statement,\n      $.switch_statement,\n      $.for_statement,\n      $.for_in_statement,\n      $.while_statement,\n      $.do_statement,\n      $.try_statement,\n      $.with_statement,\n\n      $.break_statement,\n      $.continue_statement,\n      $.return_statement,\n      $.throw_statement,\n      $.empty_statement,\n      $.labeled_statement\n    ),\n\n    expression_statement: $ => seq(\n      $._expressions,\n      $._semicolon\n    ),\n\n    variable_declaration: $ => seq(\n      \'var\',\n      commaSep1($.variable_declarator),\n      $._semicolon\n    ),\n\n    lexical_declaration: $ => seq(\n      choice(\'let\', \'const\'),\n      commaSep1($.variable_declarator),\n      $._semicolon\n    ),\n\n    variable_declarator: $ => seq(\n      field(\'name\', choice($.identifier, $._destructuring_pattern)),\n      optional($._initializer)\n    ),\n\n    statement_block: $ => prec.right(seq(\n      \'{\',\n      repeat($._statement),\n      \'}\',\n      optional($._automatic_semicolon)\n    )),\n\n    if_statement: $ => prec.right(seq(\n      \'if\',\n      field(\'condition\', $.parenthesized_expression),\n      field(\'consequence\', $._statement),\n      optional(seq(\n        \'else\',\n        field(\'alternative\', $._statement)\n      ))\n    )),\n\n    switch_statement: $ => seq(\n      \'switch\',\n      field(\'value\', $.parenthesized_expression),\n      field(\'body\', $.switch_body)\n    ),\n\n    for_statement: $ => seq(\n      \'for\',\n      \'(\',\n      field(\'initializer\', choice(\n        $.lexical_declaration,\n        $.variable_declaration,\n        $.expression_statement,\n        $.empty_statement\n      )),\n      field(\'condition\', choice(\n        $.expression_statement,\n        $.empty_statement\n      )),\n      field(\'increment\', optional($._expressions)),\n      \')\',\n      field(\'body\', $._statement)\n    ),\n\n    for_in_statement: $ => seq(\n      \'for\',\n      optional(\'await\'),\n      $._for_header,\n      field(\'body\', $._statement)\n    ),\n\n    _for_header: $ => seq(\n      \'(\',\n      optional(choice(\'var\', \'let\', \'const\')),\n      field(\'left\', choice($.parenthesized_expression, $._lhs_expression)),\n      choice(\'in\', \'of\'),\n      field(\'right\', $._expressions),\n      \')\',\n    ),\n\n    while_statement: $ => seq(\n      \'while\',\n      field(\'condition\', $.parenthesized_expression),\n      field(\'body\', $._statement)\n    ),\n\n    do_statement: $ => seq(\n      \'do\',\n      field(\'body\', $._statement),\n      \'while\',\n      field(\'condition\', $.parenthesized_expression),\n      $._semicolon\n    ),\n\n    try_statement: $ => seq(\n      \'try\',\n      field(\'body\', $.statement_block),\n      optional(field(\'handler\', $.catch_clause)),\n      optional(field(\'finalizer\', $.finally_clause))\n    ),\n\n    with_statement: $ => seq(\n      \'with\',\n      field(\'object\', $.parenthesized_expression),\n      field(\'body\', $._statement)\n    ),\n\n    break_statement: $ => seq(\n      \'break\',\n      field(\'label\', optional(alias($.identifier, $.statement_identifier))),\n      $._semicolon\n    ),\n\n    continue_statement: $ => seq(\n      \'continue\',\n      field(\'label\', optional(alias($.identifier, $.statement_identifier))),\n      $._semicolon\n    ),\n\n    debugger_statement: $ => seq(\n      \'debugger\',\n      $._semicolon\n    ),\n\n    return_statement: $ => seq(\n      \'return\',\n      optional($._expressions),\n      $._semicolon\n    ),\n\n    throw_statement: $ => seq(\n      \'throw\',\n      $._expressions,\n      $._semicolon\n    ),\n\n    empty_statement: $ => \';\',\n\n    labeled_statement: $ => prec.dynamic(-1, seq(\n      field(\'label\', alias(choice($.identifier, $._reserved_identifier), $.statement_identifier)),\n      \':\',\n      $._statement\n    )),\n\n    //\n    // Statement components\n    //\n\n    switch_body: $ => seq(\n      \'{\',\n      repeat(choice($.switch_case, $.switch_default)),\n      \'}\'\n    ),\n\n    switch_case: $ => seq(\n      \'case\',\n      field(\'value\', $._expressions),\n      \':\',\n      repeat($._statement)\n    ),\n\n    switch_default: $ => seq(\n      \'default\',\n      \':\',\n      repeat($._statement)\n    ),\n\n    catch_clause: $ => seq(\n      \'catch\',\n      optional(seq(\'(\', field(\'parameter\', choice($.identifier, $._destructuring_pattern)), \')\')),\n      field(\'body\', $.statement_block)\n    ),\n\n    finally_clause: $ => seq(\n      \'finally\',\n      field(\'body\', $.statement_block)\n    ),\n\n    parenthesized_expression: $ => seq(\n      \'(\',\n      $._expressions,\n      \')\'\n    ),\n\n    //\n    // Expressions\n    //\n    _expressions: $ => choice(\n      $._expression,\n      $.sequence_expression\n    ),\n\n    _expression: $ => choice(\n      $._primary_expression,\n      $._jsx_element,\n      $.jsx_fragment,\n      $.assignment_expression,\n      $.augmented_assignment_expression,\n      $.await_expression,\n      $.unary_expression,\n      $.binary_expression,\n      $.ternary_expression,\n      $.update_expression,\n      $.new_expression,\n      $.yield_expression,\n    ),\n\n    _primary_expression: $ => choice(\n      $.this,\n      $.super,\n      $.identifier,\n      alias($._reserved_identifier, $.identifier),\n      $.number,\n      $.string,\n      $.template_string,\n      $.regex,\n      $.true,\n      $.false,\n      $.null,\n      $.undefined,\n      $.import,\n      $.object,\n      $.array,\n      $.function,\n      $.arrow_function,\n      $.generator_function,\n      $.class,\n      $.parenthesized_expression,\n      $.subscript_expression,\n      $.member_expression,\n      $.meta_property,\n      $.call_expression,\n    ),\n\n    yield_expression: $ => prec.right(seq(\n      \'yield\',\n      choice(\n        seq(\'*\', $._expression),\n        optional($._expression)\n      ))),\n\n    object: $ => prec(PREC.OBJECT, seq(\n      \'{\',\n      commaSep(optional(choice(\n        $.pair,\n        $.spread_element,\n        $.method_definition,\n        $.assignment_pattern,\n        alias(\n          choice($.identifier, $._reserved_identifier),\n          $.shorthand_property_identifier\n        )\n      ))),\n      \'}\'\n    )),\n\n    assignment_pattern: $ => seq(\n      field(\'left\', choice(\n        alias(choice($._reserved_identifier, $.identifier), $.shorthand_property_identifier),\n        $._destructuring_pattern\n      )),\n      \'=\',\n      field(\'right\', $._expression)\n    ),\n\n    array: $ => seq(\n      \'[\',\n      commaSep(optional(choice(\n        $._expression,\n        $.spread_element\n      ))),\n      \']\'\n    ),\n\n    _jsx_element: $ => choice($.jsx_element, $.jsx_self_closing_element),\n\n    jsx_element: $ => seq(\n      field(\'open_tag\', $.jsx_opening_element),\n      repeat($._jsx_child),\n      field(\'close_tag\', $.jsx_closing_element)\n    ),\n\n    jsx_fragment: $ => seq(\'<\', \'>\', repeat($._jsx_child), \'<\', \'/\', \'>\'),\n\n    jsx_text: $ => /[^{}<>]+/,\n\n    jsx_expression: $ => seq(\n      \'{\',\n      optional(choice(\n        $._expression,\n        $.sequence_expression,\n        $.spread_element\n      )),\n      \'}\'\n    ),\n\n    _jsx_child: $ => choice(\n      $.jsx_text,\n      $._jsx_element,\n      $.jsx_fragment,\n      $.jsx_expression\n    ),\n\n    jsx_opening_element: $ => prec.dynamic(-1, seq(\n      \'<\',\n      field(\'name\', $._jsx_element_name),\n      repeat(field(\'attribute\', $._jsx_attribute)),\n      \'>\'\n    )),\n\n    jsx_identifier: $ => /[a-zA-Z_$][a-zA-Z\\d_$]*-[a-zA-Z\\d_$\\-]*/,\n\n    _jsx_identifier: $ => choice(\n      alias($.jsx_identifier, $.identifier),\n      $.identifier\n    ),\n\n    nested_identifier: $ => prec(PREC.MEMBER, seq(\n      choice($.identifier, $.nested_identifier),\n      \'.\',\n      $.identifier\n    )),\n\n    jsx_namespace_name: $ => seq($._jsx_identifier, \':\', $._jsx_identifier),\n\n    _jsx_element_name: $ => choice(\n      $._jsx_identifier,\n      $.nested_identifier,\n      $.jsx_namespace_name,\n    ),\n\n    jsx_closing_element: $ => seq(\n      \'<\',\n      \'/\',\n      field(\'name\', $._jsx_element_name),\n      \'>\'\n    ),\n\n    jsx_self_closing_element: $ => seq(\n      \'<\',\n      field(\'name\', $._jsx_element_name),\n      repeat(field(\'attribute\', $._jsx_attribute)),\n      \'/\',\n      \'>\'\n    ),\n\n    _jsx_attribute: $ => choice($.jsx_attribute, $.jsx_expression),\n\n    _jsx_attribute_name: $ => choice(alias($._jsx_identifier, $.property_identifier), $.jsx_namespace_name),\n\n    jsx_attribute: $ => seq(\n      $._jsx_attribute_name,\n      optional(seq(\n        \'=\',\n        $._jsx_attribute_value\n      ))\n    ),\n\n    _jsx_attribute_value: $ => choice(\n      $.string,\n      $.jsx_expression,\n      $._jsx_element,\n      $.jsx_fragment\n    ),\n\n    class: $ => seq(\n      repeat(field(\'decorator\', $.decorator)),\n      \'class\',\n      field(\'name\', optional($.identifier)),\n      optional($.class_heritage),\n      field(\'body\', $.class_body)\n    ),\n\n    class_declaration: $ => prec(PREC.DECLARATION, seq(\n      repeat(field(\'decorator\', $.decorator)),\n      \'class\',\n      field(\'name\', $.identifier),\n      optional($.class_heritage),\n      field(\'body\', $.class_body),\n      optional($._automatic_semicolon)\n    )),\n\n    class_heritage: $ => seq(\'extends\', $._expression),\n\n    function: $ => seq(\n      optional(\'async\'),\n      \'function\',\n      field(\'name\', optional($.identifier)),\n      $._call_signature,\n      field(\'body\', $.statement_block)\n    ),\n\n    function_declaration: $ => prec.right(PREC.DECLARATION, seq(\n      optional(\'async\'),\n      \'function\',\n      field(\'name\', $.identifier),\n      $._call_signature,\n      field(\'body\', $.statement_block),\n      optional($._automatic_semicolon)\n    )),\n\n    generator_function: $ => seq(\n      optional(\'async\'),\n      \'function\',\n      \'*\',\n      field(\'name\', optional($.identifier)),\n      $._call_signature,\n      field(\'body\', $.statement_block)\n    ),\n\n    generator_function_declaration: $ => prec.right(PREC.DECLARATION, seq(\n      optional(\'async\'),\n      \'function\',\n      \'*\',\n      field(\'name\', $.identifier),\n      $._call_signature,\n      field(\'body\', $.statement_block),\n      optional($._automatic_semicolon)\n    )),\n\n    arrow_function: $ => seq(\n      optional(\'async\'),\n      choice(\n        field(\'parameter\', choice(\n          alias($._reserved_identifier, $.identifier),\n          $.identifier,\n        )),\n        $._call_signature\n      ),\n      \'=>\',\n      field(\'body\', choice(\n        $._expression,\n        $.statement_block\n      ))\n    ),\n\n    // Override\n    _call_signature: $ => seq(\n      field(\'parameters\', $.formal_parameters)\n    ),\n\n    call_expression: $ => choice(\n      prec(PREC.CALL, seq(\n        field(\'function\', $._expression),\n        field(\'arguments\', choice($.arguments, $.template_string))\n      )),\n      prec(PREC.MEMBER, seq(\n        field(\'function\', $._primary_expression),\n        \'?.\',\n        field(\'arguments\', $.arguments)\n      ))\n    ),\n\n    new_expression: $ => prec.right(PREC.NEW, seq(\n      \'new\',\n      field(\'constructor\', $._primary_expression),\n      field(\'arguments\', optional(prec.dynamic(1, $.arguments)))\n    )),\n\n    await_expression: $ => seq(\n      \'await\',\n      $._expression\n    ),\n\n    member_expression: $ => prec(PREC.MEMBER, seq(\n      field(\'object\', choice($._expression, $._primary_expression)),\n      choice(\'.\', \'?.\'),\n      field(\'property\', alias($.identifier, $.property_identifier))\n    )),\n\n    subscript_expression: $ => prec.right(PREC.MEMBER, seq(\n      field(\'object\', choice($._expression, $._primary_expression)),\n      optional(\'?.\'),\n      \'[\', field(\'index\', $._expressions), \']\'\n    )),\n\n    _lhs_expression: $ => choice(\n      $.member_expression,\n      $.subscript_expression,\n      $.identifier,\n      alias($._reserved_identifier, $.identifier),\n      $._destructuring_pattern\n    ),\n\n    assignment_expression: $ => prec.right(PREC.ASSIGN, seq(\n      field(\'left\', choice($.parenthesized_expression, $._lhs_expression)),\n      \'=\',\n      field(\'right\', $._expression)\n    )),\n\n    augmented_assignment_expression: $ => prec.right(PREC.ASSIGN, seq(\n      field(\'left\', choice(\n        $.member_expression,\n        $.subscript_expression,\n        alias($._reserved_identifier, $.identifier),\n        $.identifier,\n        $.parenthesized_expression,\n      )),\n      choice(\'+=\', \'-=\', \'*=\', \'/=\', \'%=\', \'^=\', \'&=\', \'|=\', \'>>=\', \'>>>=\',\n             \'<<=\', \'**=\', \'&&=\', \'||=\', \'??=\'),\n      field(\'right\', $._expression)\n    )),\n\n    _initializer: $ => seq(\n      \'=\',\n      field(\'value\', $._expression)\n    ),\n\n    _destructuring_pattern: $ => choice(\n      alias($.object, $.object_pattern),\n      alias($.array, $.array_pattern)\n    ),\n\n    spread_element: $ => seq(\'...\', $._expression),\n\n    ternary_expression: $ => prec.right(PREC.TERNARY, seq(\n      field(\'condition\', $._expression),\n      \'?\',\n      field(\'consequence\', $._expression),\n      \':\',\n      field(\'alternative\', $._expression)\n    )),\n\n    binary_expression: $ => choice(\n      ...[\n        [\'&&\', PREC.AND],\n        [\'||\', PREC.OR],\n        [\'>>\', PREC.TIMES],\n        [\'>>>\', PREC.TIMES],\n        [\'<<\', PREC.TIMES],\n        [\'&\', PREC.AND],\n        [\'^\', PREC.OR],\n        [\'|\', PREC.OR],\n        [\'+\', PREC.PLUS],\n        [\'-\', PREC.PLUS],\n        [\'*\', PREC.TIMES],\n        [\'/\', PREC.TIMES],\n        [\'%\', PREC.TIMES],\n        [\'**\', PREC.EXP],\n        [\'<\', PREC.REL],\n        [\'<=\', PREC.REL],\n        [\'==\', PREC.REL],\n        [\'===\', PREC.REL],\n        [\'!=\', PREC.REL],\n        [\'!==\', PREC.REL],\n        [\'>=\', PREC.REL],\n        [\'>\', PREC.REL],\n        [\'??\', PREC.TERNARY],\n        [\'instanceof\', PREC.REL],\n        [\'in\', PREC.REL],\n      ].map(([operator, precedence]) =>\n        prec.left(precedence, seq(\n          field(\'left\', $._expression),\n          field(\'operator\', operator),\n          field(\'right\', $._expression)\n        ))\n      )\n    ),\n\n    unary_expression: $ => choice(...[\n      [\'!\', PREC.NOT],\n      [\'~\', PREC.NOT],\n      [\'-\', PREC.NEG],\n      [\'+\', PREC.NEG],\n      [\'typeof\', PREC.TYPEOF],\n      [\'void\', PREC.VOID],\n      [\'delete\', PREC.DELETE],\n    ].map(([operator, precedence]) =>\n      prec.left(precedence, seq(\n        field(\'operator\', operator),\n        field(\'argument\', $._expression)\n      ))\n    )),\n\n    update_expression: $ => prec.left(PREC.INC, choice(\n      seq(\n        field(\'argument\', $._expression),\n        field(\'operator\', choice(\'++\', \'--\'))\n      ),\n      seq(\n        field(\'operator\', choice(\'++\', \'--\')),\n        field(\'argument\', $._expression)\n      ),\n    )),\n\n    sequence_expression: $ => prec(PREC.COMMA, seq(\n      field(\'left\', $._expression),\n      \',\',\n      field(\'right\', choice($.sequence_expression, $._expression))\n    )),\n\n    //\n    // Primitives\n    //\n\n    string: $ => choice(\n      seq(\n        \'\"\',\n        repeat(choice(\n          token.immediate(prec(PREC.STRING, /[^\"\\\\\\n]+|\\\\\\r?\\n/)),\n          $.escape_sequence\n        )),\n        \'\"\'\n      ),\n      seq(\n        \"\'\",\n        repeat(choice(\n          token.immediate(prec(PREC.STRING, /[^\'\\\\\\n]+|\\\\\\r?\\n/)),\n          $.escape_sequence\n        )),\n        \"\'\"\n      )\n    ),\n\n    escape_sequence: $ => token.immediate(seq(\n      \'\\\\\',\n      choice(\n        /[^xu0-7]/,\n        /[0-7]{1,3}/,\n        /x[0-9a-fA-F]{2}/,\n        /u[0-9a-fA-F]{4}/,\n        /u{[0-9a-fA-F]+}/\n      )\n    )),\n\n    // http://stackoverflow.com/questions/13014947/regex-to-match-a-c-style-multiline-comment/36328890#36328890\n    comment: $ => token(prec(PREC.COMMENT, choice(\n      seq(\'//\', /.*/),\n      seq(\n        \'/*\',\n        /[^*]*\\*+([^/*][^*]*\\*+)*/,\n        \'/\'\n      )\n    ))),\n\n    template_string: $ => seq(\n      \'`\',\n      repeat(choice(\n        $._template_chars,\n        $.escape_sequence,\n        $.template_substitution\n      )),\n      \'`\'\n    ),\n\n    template_substitution: $ => seq(\n      \'${\',\n      $._expressions,\n      \'}\'\n    ),\n\n    regex: $ => seq(\n      \'/\',\n      field(\'pattern\', $.regex_pattern),\n      token.immediate(\'/\'),\n      optional(field(\'flags\', $.regex_flags))\n    ),\n\n    regex_pattern: $ => token.immediate(\n      repeat1(choice(\n        seq(\n          \'[\',\n          repeat(choice(\n            seq(\'\\\\\', /./), // escaped character\n            /[^\\]\\n\\\\]/       // any character besides \']\' or \'\\n\'\n          )),\n          \']\'\n        ),              // square-bracket-delimited character class\n        seq(\'\\\\\', /./), // escaped character\n        /[^/\\\\\\[\\n]/    // any character besides \'[\', \'\\\', \'/\', \'\\n\'\n      ))\n    ),\n\n    regex_flags: $ => token.immediate(/[a-z]+/),\n\n    number: $ => {\n      const hex_literal = seq(\n        choice(\'0x\', \'0X\'),\n        /[\\da-fA-F](_?[\\da-fA-F])*/\n      )\n\n      const decimal_digits = /\\d(_?\\d)*/\n      const signed_integer = seq(optional(choice(\'-\', \'+\')), decimal_digits)\n      const exponent_part = seq(choice(\'e\', \'E\'), signed_integer)\n\n      const binary_literal = seq(choice(\'0b\', \'0B\'), /[0-1](_?[0-1])*/)\n\n      const octal_literal = seq(choice(\'0o\', \'0O\'), /[0-7](_?[0-7])*/)\n\n      const bigint_literal = seq(choice(hex_literal, binary_literal, octal_literal, decimal_digits), \'n\')\n\n      const decimal_integer_literal = choice(\n        \'0\',\n        seq(optional(\'0\'), /[1-9]/, optional(seq(optional(\'_\'), decimal_digits)))\n      )\n\n      const decimal_literal = choice(\n        seq(decimal_integer_literal, \'.\', optional(decimal_digits), optional(exponent_part)),\n        seq(\'.\', decimal_digits, optional(exponent_part)),\n        seq(decimal_integer_literal, exponent_part),\n        seq(decimal_digits),\n      )\n\n      return token(choice(\n        hex_literal,\n        decimal_literal,\n        binary_literal,\n        octal_literal,\n        bigint_literal,\n      ))\n    },\n\n    identifier: $ => {\n      const alpha = /[^\\x00-\\x1F\\s0-9:;`\"\'@#.,|^&<=>+\\-*/\\\\%?!~()\\[\\]{}\\uFEFF\\u2060\\u200B\\u00A0]|\\\\u[0-9a-fA-F]{4}|\\\\u\\{[0-9a-fA-F]+\\}/\n      const alphanumeric = /[^\\x00-\\x1F\\s:;`\"\'@#.,|^&<=>+\\-*/\\\\%?!~()\\[\\]{}\\uFEFF\\u2060\\u200B\\u00A0]|\\\\u[0-9a-fA-F]{4}|\\\\u\\{[0-9a-fA-F]+\\}/\n      return token(seq(alpha, repeat(alphanumeric)))\n    },\n\n    meta_property: $ => seq(\'new\', \'.\', \'target\'),\n\n    this: $ => \'this\',\n    super: $ => \'super\',\n    true: $ => \'true\',\n    false: $ => \'false\',\n    null: $ => \'null\',\n    undefined: $ => \'undefined\',\n\n    //\n    // Expression components\n    //\n\n    arguments: $ => prec(PREC.CALL, seq(\n      \'(\',\n      commaSep(optional(choice($._expression, $.spread_element))),\n      \')\'\n    )),\n\n    decorator: $ => seq(\n      \'@\',\n      choice(\n        $.identifier,\n        alias($.decorator_member_expression, $.member_expression),\n        alias($.decorator_call_expression, $.call_expression)\n      )\n    ),\n\n    decorator_member_expression: $ => prec(PREC.MEMBER, seq(\n      field(\'object\', choice(\n        $.identifier,\n        alias($.decorator_member_expression, $.member_expression)\n      )),\n      \'.\',\n      field(\'property\', alias($.identifier, $.property_identifier))\n    )),\n\n    decorator_call_expression: $ => prec(PREC.CALL, seq(\n      field(\'function\', choice(\n        $.identifier,\n        alias($.decorator_member_expression, $.member_expression)\n      )),\n      field(\'arguments\', $.arguments)\n    )),\n\n    class_body: $ => seq(\n      \'{\',\n      repeat(choice(\n        seq(field(\'member\', $.method_definition), optional(\';\')),\n        seq(field(\'member\', $.public_field_definition), $._semicolon)\n      )),\n      \'}\'\n    ),\n\n    public_field_definition: $ => seq(\n      optional(\'static\'),\n      field(\'property\', $._property_name),\n      optional($._initializer)\n    ),\n\n    formal_parameters: $ => seq(\n      \'(\',\n      optional(seq(\n        commaSep1($._formal_parameter),\n        optional(\',\')\n      )),\n      \')\'\n    ),\n\n    _formal_parameter: $ => choice(\n      $.identifier,\n      alias($._reserved_identifier, $.identifier),\n      $._destructuring_pattern,\n      $.assignment_pattern,\n      $.rest_parameter\n    ),\n\n    rest_parameter: $ => seq(\n      \'...\',\n      choice(\n        $.identifier,\n        $._destructuring_pattern,\n      )\n    ),\n\n    method_definition: $ => seq(\n      repeat(field(\'decorator\', $.decorator)),\n      optional(\'static\'),\n      optional(\'async\'),\n      optional(choice(\'get\', \'set\', \'*\')),\n      field(\'name\', $._property_name),\n      field(\'parameters\', $.formal_parameters),\n      field(\'body\', $.statement_block)\n    ),\n\n    pair: $ => seq(\n      field(\'key\', $._property_name),\n      \':\',\n      field(\'value\', $._expression)\n    ),\n\n    _property_name: $ => choice(\n      alias(choice(\n        $.identifier,\n        $._reserved_identifier\n      ), $.property_identifier),\n      $.string,\n      $.number,\n      $.computed_property_name\n    ),\n\n    computed_property_name: $ => seq(\n      \'[\',\n      $._expression,\n      \']\'\n    ),\n\n    _reserved_identifier: $ => choice(\n      \'get\',\n      \'set\',\n      \'async\',\n      \'static\',\n    ),\n\n    _semicolon: $ => choice($._automatic_semicolon, \';\')\n  }\n});\n\nfunction commaSep1(rule) {\n  return seq(rule, repeat(seq(\',\', rule)));\n}\n\nfunction commaSep(rule) {\n  return optional(commaSep1(rule));\n}\n";

The source of the JavaScript tree-sitter grammar description.