[−][src]Constant tree_sitter_go::GRAMMAR
pub const GRAMMAR: &'static str = "const\n PREC = {\n primary: 7,\n unary: 6,\n multiplicative: 5,\n additive: 4,\n comparative: 3,\n and: 2,\n or: 1,\n composite_literal: -1,\n },\n\n multiplicative_operators = [\'*\', \'/\', \'%\', \'<<\', \'>>\', \'&\', \'&^\'],\n additive_operators = [\'+\', \'-\', \'|\', \'^\'],\n comparative_operators = [\'==\', \'!=\', \'<\', \'<=\', \'>\', \'>=\'],\n assignment_operators = multiplicative_operators.concat(additive_operators).map(operator => operator + \'=\').concat(\'=\'),\n\n unicodeLetter = /[a-zA-Z\u{3b1}-\u{3c9}\u{391}-\u{3a9}\u{b5}]/,\n unicodeDigit = /[0-9]/,\n unicodeChar = /./,\n unicodeValue = unicodeChar,\n letter = choice(unicodeLetter, \'_\'),\n\n newline = \'\\n\',\n terminator = choice(newline, \';\'),\n\n hexDigit = /[0-9a-fA-F]/,\n octalDigit = /[0-7]/,\n decimalDigit = /[0-9]/,\n binaryDigit = /[01]/,\n\n hexDigits = seq(hexDigit, repeat(seq(optional(\'_\'), hexDigit))),\n octalDigits = seq(octalDigit, repeat(seq(optional(\'_\'), octalDigit))),\n decimalDigits = seq(decimalDigit, repeat(seq(optional(\'_\'), decimalDigit))),\n binaryDigits = seq(binaryDigit, repeat(seq(optional(\'_\'), binaryDigit))),\n\n hexLiteral = seq(\'0\', choice(\'x\', \'X\'), optional(\'_\'), hexDigits),\n octalLiteral = seq(\'0\', optional(choice(\'o\', \'O\')), optional(\'_\'), octalDigits),\n decimalLiteral = choice(\'0\', seq(/[1-9]/, optional(seq(optional(\'_\'), decimalDigits)))),\n binaryLiteral = seq(\'0\', choice(\'b\', \'B\'), optional(\'_\'), binaryDigits),\n\n intLiteral = choice(binaryLiteral, decimalLiteral, octalLiteral, hexLiteral),\n\n decimalExponent = seq(choice(\'e\', \'E\'), optional(choice(\'+\', \'-\')), decimalDigits),\n decimalFloatLiteral = choice(\n seq(decimalDigits, \'.\', optional(decimalDigits), optional(decimalExponent)),\n seq(decimalDigits, decimalExponent),\n seq(\'.\', decimalDigits, optional(decimalExponent)),\n ),\n\n hexExponent = seq(choice(\'p\', \'P\'), optional(choice(\'+\', \'-\')), decimalDigits),\n hexMantissa = choice(\n seq(optional(\'_\'), hexDigits, \'.\', optional(hexDigits)),\n seq(optional(\'_\'), hexDigits),\n seq(\'.\', hexDigits),\n ),\n hexFloatLiteral = seq(\'0\', choice(\'x\', \'X\'), hexMantissa, hexExponent),\n\n floatLiteral = choice(decimalFloatLiteral, hexFloatLiteral),\n\n imaginaryLiteral = seq(choice(decimalDigits, intLiteral, floatLiteral), \'i\')\n\nmodule.exports = grammar({\n name: \'go\',\n\n extras: $ => [\n $.comment,\n /\\s/\n ],\n\n inline: $ => [\n $._type,\n $._type_identifier,\n $._field_identifier,\n $._package_identifier,\n $._top_level_declaration,\n $._string_literal,\n ],\n\n word: $ => $.identifier,\n\n conflicts: $ => [\n [$._simple_type, $._expression],\n [$.qualified_type, $._expression],\n [$.func_literal, $.function_type],\n [$.function_type],\n [$.parameter_declaration, $._simple_type],\n ],\n\n supertypes: $ => [\n $._expression,\n $._type,\n $._simple_type,\n $._statement,\n $._simple_statement,\n ],\n\n rules: {\n source_file: $ => repeat(choice(\n seq($._statement, terminator),\n seq($._top_level_declaration, optional(terminator)),\n )),\n\n _top_level_declaration: $ => choice(\n $.package_clause,\n $.function_declaration,\n $.method_declaration,\n $.import_declaration\n ),\n\n package_clause: $ => seq(\n \'package\',\n $._package_identifier\n ),\n\n import_declaration: $ => seq(\n \'import\',\n choice(\n $.import_spec,\n $.import_spec_list\n )\n ),\n\n import_spec: $ => seq(\n optional(field(\'name\', choice(\n $.dot,\n $.blank_identifier,\n $._package_identifier\n ))),\n field(\'path\', $._string_literal)\n ),\n dot: $ => \'.\',\n blank_identifier: $ => \'_\',\n\n import_spec_list: $ => seq(\n \'(\',\n repeat(seq(\n $.import_spec,\n terminator\n )),\n \')\'\n ),\n\n _declaration: $ => choice(\n $.const_declaration,\n $.type_declaration,\n $.var_declaration\n ),\n\n const_declaration: $ => seq(\n \'const\',\n choice(\n $.const_spec,\n seq(\n \'(\',\n repeat(seq($.const_spec, terminator)),\n \')\'\n )\n )\n ),\n\n const_spec: $ => prec.left(seq(\n field(\'name\', commaSep1($.identifier)),\n optional(seq(\n optional(field(\'type\', $._type)),\n \'=\',\n field(\'value\', $.expression_list)\n ))\n )),\n\n var_declaration: $ => seq(\n \'var\',\n choice(\n $.var_spec,\n seq(\n \'(\',\n repeat(seq($.var_spec, terminator)),\n \')\'\n )\n )\n ),\n\n var_spec: $ => seq(\n field(\'name\', commaSep1($.identifier)),\n choice(\n seq(\n field(\'type\', $._type),\n optional(seq(\'=\', field(\'value\', $.expression_list)))\n ),\n seq(\'=\', field(\'value\', $.expression_list))\n )\n ),\n\n function_declaration: $ => prec.right(1, seq(\n \'func\',\n field(\'name\', $.identifier),\n field(\'parameters\', $.parameter_list),\n field(\'result\', optional(choice($.parameter_list, $._simple_type))),\n field(\'body\', optional($.block))\n )),\n\n method_declaration: $ => prec.right(1, seq(\n \'func\',\n field(\'receiver\', $.parameter_list),\n field(\'name\', $._field_identifier),\n field(\'parameters\', $.parameter_list),\n field(\'result\', optional(choice($.parameter_list, $._simple_type))),\n field(\'body\', optional($.block))\n )),\n\n parameter_list: $ => seq(\n \'(\',\n optional(seq(\n commaSep(choice($.parameter_declaration, $.variadic_parameter_declaration)),\n optional(\',\')\n )),\n \')\'\n ),\n\n parameter_declaration: $ => seq(\n field(\'name\', commaSep($.identifier)),\n field(\'type\', $._type)\n ),\n\n variadic_parameter_declaration: $ => seq(\n field(\'name\', optional($.identifier)),\n \'...\',\n field(\'type\', $._type)\n ),\n\n type_alias: $ => seq(\n field(\'name\', $._type_identifier),\n \'=\',\n field(\'type\', $._type)\n ),\n\n type_declaration: $ => seq(\n \'type\',\n choice(\n $.type_spec,\n $.type_alias,\n seq(\n \'(\',\n repeat(seq(choice($.type_spec, $.type_alias), terminator)),\n \')\'\n )\n )\n ),\n\n type_spec: $ => seq(\n field(\'name\', $._type_identifier),\n field(\'type\', $._type)\n ),\n\n field_name_list: $ => commaSep1($._field_identifier),\n\n expression_list: $ => commaSep1($._expression),\n\n _type: $ => choice(\n $._simple_type,\n $.parenthesized_type\n ),\n\n parenthesized_type: $ => seq(\'(\', $._type, \')\'),\n\n _simple_type: $ => choice(\n prec.dynamic(-1, $._type_identifier),\n $.qualified_type,\n $.pointer_type,\n $.struct_type,\n $.interface_type,\n $.array_type,\n $.slice_type,\n $.map_type,\n $.channel_type,\n $.function_type\n ),\n\n pointer_type: $ => prec(PREC.unary, seq(\'*\', $._type)),\n\n array_type: $ => seq(\n \'[\',\n field(\'length\', $._expression),\n \']\',\n field(\'element\', $._type)\n ),\n\n implicit_length_array_type: $ => seq(\n \'[\',\n \'...\',\n \']\',\n field(\'element\', $._type)\n ),\n\n slice_type: $ => seq(\n \'[\',\n \']\',\n field(\'element\', $._type)\n ),\n\n struct_type: $ => seq(\n \'struct\',\n $.field_declaration_list\n ),\n\n field_declaration_list: $ => seq(\n \'{\',\n optional(seq(\n $.field_declaration,\n repeat(seq(terminator, $.field_declaration)),\n optional(terminator)\n )),\n \'}\'\n ),\n\n field_declaration: $ => seq(\n choice(\n seq(\n field(\'name\', commaSep1($._field_identifier)),\n field(\'type\', $._type)\n ),\n seq(\n optional(\'*\'),\n field(\'type\', choice(\n $._type_identifier,\n $.qualified_type\n ))\n )\n ),\n field(\'tag\', optional($._string_literal))\n ),\n\n interface_type: $ => seq(\n \'interface\',\n $.method_spec_list\n ),\n\n method_spec_list: $ => seq(\n \'{\',\n optional(seq(\n choice($._type_identifier, $.qualified_type, $.method_spec),\n repeat(seq(terminator, choice($._type_identifier, $.qualified_type, $.method_spec))),\n optional(terminator)\n )),\n \'}\'\n ),\n\n method_spec: $ => seq(\n field(\'name\', $._field_identifier),\n field(\'parameters\', $.parameter_list),\n field(\'result\', optional(choice($.parameter_list, $._simple_type)))\n ),\n\n map_type: $ => seq(\n \'map\',\n \'[\',\n field(\'key\', $._type),\n \']\',\n field(\'value\', $._type)\n ),\n\n channel_type: $ => choice(\n seq(\'chan\', field(\'value\', $._type)),\n seq(\'chan\', \'<-\', field(\'value\', $._type)),\n prec(PREC.unary, seq(\'<-\', \'chan\', field(\'value\', $._type)))\n ),\n\n function_type: $ => seq(\n \'func\',\n field(\'parameters\', $.parameter_list),\n field(\'result\', optional(choice($.parameter_list, $._simple_type)))\n ),\n\n block: $ => seq(\n \'{\',\n optional($._statement_list),\n \'}\'\n ),\n\n _statement_list: $ => choice(\n seq(\n $._statement,\n repeat(seq(terminator, $._statement)),\n optional(seq(\n terminator,\n optional(alias($.empty_labeled_statement, $.labeled_statement))\n ))\n ),\n alias($.empty_labeled_statement, $.labeled_statement)\n ),\n\n _statement: $ => choice(\n $._declaration,\n $._simple_statement,\n $.return_statement,\n $.go_statement,\n $.defer_statement,\n $.if_statement,\n $.for_statement,\n $.expression_switch_statement,\n $.type_switch_statement,\n $.select_statement,\n $.labeled_statement,\n $.fallthrough_statement,\n $.break_statement,\n $.continue_statement,\n $.goto_statement,\n $.block,\n $.empty_statement\n ),\n\n empty_statement: $ => \';\',\n\n _simple_statement: $ => choice(\n $._expression,\n $.send_statement,\n $.inc_statement,\n $.dec_statement,\n $.assignment_statement,\n $.short_var_declaration\n ),\n\n send_statement: $ => seq(\n field(\'channel\', $._expression),\n \'<-\',\n field(\'value\', $._expression)\n ),\n\n receive_statement: $ => seq(\n optional(seq(\n field(\'left\', $.expression_list),\n choice(\'=\', \':=\')\n )),\n field(\'right\', $._expression)\n ),\n\n inc_statement: $ => seq(\n $._expression,\n \'++\'\n ),\n\n dec_statement: $ => seq(\n $._expression,\n \'--\'\n ),\n\n assignment_statement: $ => seq(\n field(\'left\', $.expression_list),\n field(\'operator\', choice(...assignment_operators)),\n field(\'right\', $.expression_list)\n ),\n\n short_var_declaration: $ => seq(\n // TODO: this should really only allow identifier lists, but that causes\n // conflicts between identifiers as expressions vs identifiers here.\n field(\'left\', $.expression_list),\n \':=\',\n field(\'right\', $.expression_list)\n ),\n\n labeled_statement: $ => seq(\n field(\'label\', alias($.identifier, $.label_name)),\n \':\',\n $._statement\n ),\n\n empty_labeled_statement: $ => seq(\n field(\'label\', alias($.identifier, $.label_name)),\n \':\'\n ),\n\n // This is a hack to prevent `fallthrough_statement` from being parsed as\n // a single token. For consistency with `break_statement` etc it should\n // be parsed as a parent node that *contains* a `fallthrough` token.\n fallthrough_statement: $ => prec.left(\'fallthrough\'),\n\n break_statement: $ => seq(\'break\', optional(alias($.identifier, $.label_name))),\n\n continue_statement: $ => seq(\'continue\', optional(alias($.identifier, $.label_name))),\n\n goto_statement: $ => seq(\'goto\', alias($.identifier, $.label_name)),\n\n return_statement: $ => seq(\'return\', optional($.expression_list)),\n\n go_statement: $ => seq(\'go\', $._expression),\n\n defer_statement: $ => seq(\'defer\', $._expression),\n\n if_statement: $ => seq(\n \'if\',\n optional(seq(\n field(\'initializer\', $._simple_statement),\n \';\'\n )),\n field(\'condition\', $._expression),\n field(\'consequence\', $.block),\n optional(seq(\n \'else\',\n field(\'alternative\', choice($.block, $.if_statement))\n ))\n ),\n\n for_statement: $ => seq(\n \'for\',\n optional(choice($._expression, $.for_clause, $.range_clause)),\n field(\'body\', $.block)\n ),\n\n for_clause: $ => seq(\n field(\'initializer\', optional($._simple_statement)),\n \';\',\n field(\'condition\', optional($._expression)),\n \';\',\n field(\'update\', optional($._simple_statement))\n ),\n\n range_clause: $ => seq(\n optional(seq(\n field(\'left\', $.expression_list),\n choice(\'=\', \':=\')\n )),\n \'range\',\n field(\'right\', $._expression)\n ),\n\n expression_switch_statement: $ => seq(\n \'switch\',\n optional(seq(\n field(\'initializer\', $._simple_statement),\n \';\'\n )),\n field(\'value\', optional($._expression)),\n \'{\',\n repeat(choice($.expression_case, $.default_case)),\n \'}\'\n ),\n\n expression_case: $ => seq(\n \'case\',\n field(\'value\', $.expression_list),\n \':\',\n optional($._statement_list)\n ),\n\n default_case: $ => seq(\n \'default\',\n \':\',\n optional($._statement_list)\n ),\n\n type_switch_statement: $ => seq(\n \'switch\',\n $._type_switch_header,\n \'{\',\n repeat(choice($.type_case, $.default_case)),\n \'}\'\n ),\n\n _type_switch_header: $ => seq(\n optional(seq(\n field(\'initializer\', $._simple_statement),\n \';\'\n )),\n optional(seq(field(\'alias\', $.expression_list), \':=\')),\n field(\'value\', $._expression),\n \'.\',\n \'(\',\n \'type\',\n \')\'\n ),\n\n type_case: $ => seq(\n \'case\',\n field(\'type\', commaSep1($._type)),\n \':\',\n optional($._statement_list)\n ),\n\n select_statement: $ => seq(\n \'select\',\n \'{\',\n repeat(choice($.communication_case, $.default_case)),\n \'}\'\n ),\n\n communication_case: $ => seq(\n \'case\',\n field(\'communication\', choice($.send_statement, $.receive_statement)),\n \':\',\n optional($._statement_list)\n ),\n\n _expression: $ => choice(\n $.unary_expression,\n $.binary_expression,\n $.selector_expression,\n $.index_expression,\n $.slice_expression,\n $.call_expression,\n $.type_assertion_expression,\n $.type_conversion_expression,\n $.identifier,\n alias(choice(\'new\', \'make\'), $.identifier),\n $.composite_literal,\n $.func_literal,\n $._string_literal,\n $.int_literal,\n $.float_literal,\n $.imaginary_literal,\n $.rune_literal,\n $.nil,\n $.true,\n $.false,\n $.parenthesized_expression\n ),\n\n parenthesized_expression: $ => seq(\n \'(\',\n $._expression,\n \')\'\n ),\n\n call_expression: $ => prec(PREC.primary, choice(\n seq(\n field(\'function\', alias(choice(\'new\', \'make\'), $.identifier)),\n field(\'arguments\', alias($.special_argument_list, $.argument_list))\n ),\n seq(\n field(\'function\', $._expression),\n field(\'arguments\', $.argument_list)\n )\n )),\n\n variadic_argument: $ => prec.right(seq(\n $._expression,\n \'...\'\n )),\n\n special_argument_list: $ => seq(\n \'(\',\n $._type,\n repeat(seq(\',\', $._expression)),\n optional(\',\'),\n \')\'\n ),\n\n argument_list: $ => seq(\n \'(\',\n optional(seq(\n choice($._expression, $.variadic_argument),\n repeat(seq(\',\', choice($._expression, $.variadic_argument))),\n optional(\',\')\n )),\n \')\'\n ),\n\n selector_expression: $ => prec(PREC.primary, seq(\n field(\'operand\', $._expression),\n \'.\',\n field(\'field\', $._field_identifier)\n )),\n\n index_expression: $ => prec(PREC.primary, seq(\n field(\'operand\', $._expression),\n \'[\',\n field(\'index\', $._expression),\n \']\'\n )),\n\n slice_expression: $ => prec(PREC.primary, seq(\n field(\'operand\', $._expression),\n \'[\',\n choice(\n seq(\n field(\'start\', optional($._expression)),\n \':\',\n field(\'end\', optional($._expression))\n ),\n seq(\n field(\'start\', optional($._expression)),\n \':\',\n field(\'end\', $._expression),\n \':\',\n field(\'capacity\', $._expression)\n )\n ),\n \']\'\n )),\n\n type_assertion_expression: $ => prec(PREC.primary, seq(\n field(\'operand\', $._expression),\n \'.\',\n \'(\',\n field(\'type\', $._type),\n \')\'\n )),\n\n type_conversion_expression: $ => prec.dynamic(-1, seq(\n field(\'type\', $._type),\n \'(\',\n field(\'operand\', $._expression),\n optional(\',\'),\n \')\'\n )),\n\n composite_literal: $ => prec(PREC.composite_literal, seq(\n field(\'type\', choice(\n $.map_type,\n $.slice_type,\n $.array_type,\n $.implicit_length_array_type,\n $.struct_type,\n $._type_identifier,\n $.qualified_type\n )),\n field(\'body\', $.literal_value)\n )),\n\n literal_value: $ => seq(\n \'{\',\n optional(seq(\n choice($.element, $.keyed_element),\n repeat(seq(\',\', choice($.element, $.keyed_element))),\n optional(\',\')\n )),\n \'}\'\n ),\n\n keyed_element: $ => seq(\n choice(\n seq($._expression, \':\'),\n seq($.literal_value, \':\'),\n prec(1, seq($._field_identifier, \':\'))\n ),\n choice(\n $._expression,\n $.literal_value\n )\n ),\n\n element: $ => choice(\n $._expression,\n $.literal_value\n ),\n\n func_literal: $ => seq(\n \'func\',\n field(\'parameters\', $.parameter_list),\n field(\'result\', optional(choice($.parameter_list, $._simple_type))),\n field(\'body\', $.block)\n ),\n\n unary_expression: $ => prec(PREC.unary, seq(\n field(\'operator\', choice(\'+\', \'-\', \'!\', \'^\', \'*\', \'&\', \'<-\')),\n field(\'operand\', $._expression)\n )),\n\n binary_expression: $ => {\n const table = [\n [PREC.multiplicative, choice(...multiplicative_operators)],\n [PREC.additive, choice(...additive_operators)],\n [PREC.comparative, choice(...comparative_operators)],\n [PREC.and, \'&&\'],\n [PREC.or, \'||\'],\n ];\n\n return choice(...table.map(([precedence, operator]) =>\n prec.left(precedence, seq(\n field(\'left\', $._expression),\n field(\'operator\', operator),\n field(\'right\', $._expression)\n ))\n ));\n },\n\n qualified_type: $ => seq(\n field(\'package\', $._package_identifier),\n \'.\',\n field(\'name\', $._type_identifier)\n ),\n\n identifier: $ => token(seq(\n letter,\n repeat(choice(letter, unicodeDigit))\n )),\n\n _type_identifier: $ => alias($.identifier, $.type_identifier),\n _field_identifier: $ => alias($.identifier, $.field_identifier),\n _package_identifier: $ => alias($.identifier, $.package_identifier),\n\n _string_literal: $ => choice(\n $.raw_string_literal,\n $.interpreted_string_literal\n ),\n\n raw_string_literal: $ => token(seq(\n \'`\',\n repeat(/[^`]/),\n \'`\'\n )),\n\n interpreted_string_literal: $ => seq(\n \'\"\',\n repeat(choice(\n token.immediate(prec(1, /[^\"\\n\\\\]+/)),\n $.escape_sequence\n )),\n \'\"\'\n ),\n\n escape_sequence: $ => token.immediate(seq(\n \'\\\\\',\n choice(\n /[^xuU]/,\n /\\d{2,3}/,\n /x[0-9a-fA-F]{2,}/,\n /u[0-9a-fA-F]{4}/,\n /U[0-9a-fA-F]{8}/\n )\n )),\n\n int_literal: $ => token(intLiteral),\n\n float_literal: $ => token(floatLiteral),\n\n imaginary_literal: $ => token(imaginaryLiteral),\n\n rune_literal: $ => token(seq(\n \"\'\",\n choice(\n /[^\'\\\\]/,\n seq(\n \'\\\\\',\n choice(\n seq(\'x\', hexDigit, hexDigit),\n seq(octalDigit, octalDigit, octalDigit),\n seq(\'u\', hexDigit, hexDigit, hexDigit, hexDigit),\n seq(\'U\', hexDigit, hexDigit, hexDigit, hexDigit, hexDigit, hexDigit, hexDigit, hexDigit),\n seq(choice(\'a\', \'b\', \'f\', \'n\', \'r\', \'t\', \'v\', \'\\\\\', \"\'\", \'\"\'))\n )\n )\n ),\n \"\'\"\n )),\n\n nil: $ => \'nil\',\n true: $ => \'true\',\n false: $ => \'false\',\n\n // http://stackoverflow.com/questions/13014947/regex-to-match-a-c-style-multiline-comment/36328890#36328890\n comment: $ => token(choice(\n seq(\'//\', /.*/),\n seq(\n \'/*\',\n /[^*]*\\*+([^/*][^*]*\\*+)*/,\n \'/\'\n )\n ))\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 Go tree-sitter grammar description.