Constant tree_sitter_cpp::GRAMMAR
source · pub const GRAMMAR: &str = "/**\n * @file C++ grammar for tree-sitter\n * @author Max Brunsfeld\n * @license MIT\n */\n\n/* eslint-disable arrow-parens */\n/* eslint-disable camelcase */\n/* eslint-disable-next-line spaced-comment */\n/// <reference types=\"tree-sitter-cli/dsl\" />\n// @ts-check\n\nconst C = require(\'tree-sitter-c/grammar\');\n\nconst PREC = Object.assign(C.PREC, {\n LAMBDA: 18,\n NEW: C.PREC.CALL + 1,\n STRUCTURED_BINDING: -1,\n THREE_WAY: C.PREC.RELATIONAL + 1,\n});\n\nconst FOLD_OPERATORS = [\n \'+\', \'-\', \'*\', \'/\', \'%\',\n \'^\', \'&\', \'|\',\n \'=\', \'<\', \'>\',\n \'<<\', \'>>\',\n \'+=\', \'-=\', \'*=\', \'/=\', \'%=\', \'^=\', \'&=\', \'|=\',\n \'>>=\', \'<<=\',\n \'==\', \'!=\', \'<=\', \'>=\',\n \'&&\', \'||\',\n \',\',\n \'.*\', \'->*\',\n \'or\', \'and\', \'bitor\', \'xor\', \'bitand\', \'not_eq\',\n];\n\nconst ASSIGNMENT_OPERATORS = [\n \'=\',\n \'*=\',\n \'/=\',\n \'%=\',\n \'+=\',\n \'-=\',\n \'<<=\',\n \'>>=\',\n \'&=\',\n \'^=\',\n \'|=\',\n \'and_eq\',\n \'or_eq\',\n \'xor_eq\',\n];\n\nmodule.exports = grammar(C, {\n name: \'cpp\',\n\n externals: $ => [\n $.raw_string_delimiter,\n $.raw_string_content,\n ],\n\n conflicts: $ => [\n // C\n [$._type_specifier, $._declarator],\n [$._type_specifier, $._expression_not_binary],\n [$.sized_type_specifier],\n [$.attributed_statement],\n [$._declaration_modifiers, $.attributed_statement],\n\n // C++\n [$.template_function, $.template_type],\n [$.template_function, $.template_type, $._expression_not_binary],\n [$.template_function, $.template_type, $.qualified_identifier],\n [$.template_method, $.field_expression],\n [$.template_type, $.qualified_type_identifier],\n [$.qualified_type_identifier, $.qualified_identifier],\n [$.comma_expression, $.initializer_list],\n [$._expression_not_binary, $._declarator],\n [$._expression_not_binary, $.structured_binding_declarator],\n [$._expression_not_binary, $._declarator, $._type_specifier],\n [$.parameter_list, $.argument_list],\n [$._type_specifier, $.call_expression],\n [$._declaration_specifiers, $._constructor_specifiers],\n [$._binary_fold_operator, $._fold_operator],\n [$._function_declarator_seq],\n [$._type_specifier, $.sized_type_specifier],\n [$.initializer_pair, $.comma_expression],\n [$.expression_statement, $._for_statement_body],\n [$.init_statement, $._for_statement_body],\n ],\n\n inline: ($, original) => original.concat([\n $._namespace_identifier,\n ]),\n\n precedences: $ => [\n [$.argument_list, $.type_qualifier],\n [$._expression_not_binary, $._class_name],\n ],\n\n rules: {\n _top_level_item: ($, original) => choice(\n ...original.members.filter((member) => member.content?.name != \'_old_style_function_definition\'),\n $.namespace_definition,\n $.concept_definition,\n $.namespace_alias_definition,\n $.using_declaration,\n $.alias_declaration,\n $.static_assert_declaration,\n $.template_declaration,\n $.template_instantiation,\n alias($.constructor_or_destructor_definition, $.function_definition),\n alias($.operator_cast_definition, $.function_definition),\n alias($.operator_cast_declaration, $.declaration),\n ),\n\n _block_item: ($, original) => choice(\n ...original.members.filter((member) => member.content?.name != \'_old_style_function_definition\'),\n $.namespace_definition,\n $.concept_definition,\n $.namespace_alias_definition,\n $.using_declaration,\n $.alias_declaration,\n $.static_assert_declaration,\n $.template_declaration,\n $.template_instantiation,\n alias($.constructor_or_destructor_definition, $.function_definition),\n alias($.operator_cast_definition, $.function_definition),\n alias($.operator_cast_declaration, $.declaration),\n ),\n\n // Types\n\n placeholder_type_specifier: $ => prec(1, seq(\n field(\'constraint\', optional($._type_specifier)),\n choice($.auto, alias($.decltype_auto, $.decltype)),\n )),\n\n auto: _ => \'auto\',\n decltype_auto: $ => seq(\n \'decltype\',\n \'(\',\n $.auto,\n \')\',\n ),\n decltype: $ => seq(\n \'decltype\',\n \'(\',\n $._expression,\n \')\',\n ),\n\n _type_specifier: $ => choice(\n $.struct_specifier,\n $.union_specifier,\n $.enum_specifier,\n $.class_specifier,\n $.sized_type_specifier,\n $.primitive_type,\n $.template_type,\n $.dependent_type,\n $.placeholder_type_specifier,\n $.decltype,\n prec.right(choice(\n alias($.qualified_type_identifier, $.qualified_identifier),\n $._type_identifier,\n )),\n ),\n\n type_qualifier: (_, original) => choice(\n original,\n \'mutable\',\n \'constinit\',\n \'consteval\',\n ),\n\n type_descriptor: (_, original) => prec.right(original),\n\n // When used in a trailing return type, these specifiers can now occur immediately before\n // a compound statement. This introduces a shift/reduce conflict that needs to be resolved\n // with an associativity.\n _class_declaration: $ => seq(\n repeat(choice($.attribute_specifier, $.alignas_specifier)),\n optional($.ms_declspec_modifier),\n repeat($.attribute_declaration),\n $._class_declaration_item,\n ),\n _class_declaration_item: $ => prec.right(seq(\n choice(\n field(\'name\', $._class_name),\n seq(\n optional(field(\'name\', $._class_name)),\n optional($.virtual_specifier),\n optional($.base_class_clause),\n field(\'body\', $.field_declaration_list),\n ),\n ),\n optional($.attribute_specifier),\n )),\n\n class_specifier: $ => seq(\n \'class\',\n $._class_declaration,\n ),\n\n union_specifier: $ => seq(\n \'union\',\n $._class_declaration,\n ),\n\n struct_specifier: $ => seq(\n \'struct\',\n $._class_declaration,\n ),\n\n _class_name: $ => prec.right(choice(\n $._type_identifier,\n $.template_type,\n alias($.qualified_type_identifier, $.qualified_identifier),\n )),\n\n function_definition: ($, original) => ({\n ...original,\n members: original.members.map(\n (e) => e.name !== \'body\' ?\n e :\n field(\'body\', choice(e.content, $.try_statement))),\n }),\n\n declaration: $ => seq(\n $._declaration_specifiers,\n commaSep1(field(\'declarator\', choice(\n seq(\n // C uses _declaration_declarator here for some nice macro parsing in function declarators,\n // but this causes a world of pain for C++ so we\'ll just stick to the normal _declarator here.\n $._declarator,\n optional($.gnu_asm_expression),\n ),\n $.init_declarator,\n ))),\n \';\',\n ),\n\n virtual_specifier: _ => choice(\n \'final\', // the only legal value here for classes\n \'override\', // legal for functions in addition to final, plus permutations.\n ),\n\n virtual: _ => choice(\'virtual\'),\n\n alignas_specifier: $ => seq(\n \'alignas\',\n \'(\',\n choice($._expression, $.primitive_type),\n \')\',\n ),\n\n _declaration_modifiers: ($, original) => choice(\n original,\n $.virtual,\n $.alignas_specifier,\n ),\n\n explicit_function_specifier: $ => choice(\n \'explicit\',\n prec(PREC.CALL, seq(\n \'explicit\',\n \'(\',\n $._expression,\n \')\',\n )),\n ),\n\n base_class_clause: $ => seq(\n \':\',\n commaSep1(seq(\n repeat($.attribute_declaration),\n optional(choice(\n $.access_specifier,\n seq($.access_specifier, $.virtual),\n seq($.virtual, $.access_specifier),\n )),\n $._class_name,\n optional(\'...\'),\n )),\n ),\n\n enum_specifier: $ => prec.right(seq(\n \'enum\',\n optional(choice(\'class\', \'struct\')),\n choice(\n seq(\n field(\'name\', $._class_name),\n optional($._enum_base_clause),\n optional(field(\'body\', $.enumerator_list)),\n ),\n field(\'body\', $.enumerator_list),\n ),\n optional($.attribute_specifier),\n )),\n\n _enum_base_clause: $ => prec.left(seq(\n \':\',\n field(\'base\', choice(\n alias($.qualified_type_identifier, $.qualified_identifier),\n $._type_identifier,\n $.primitive_type,\n $.sized_type_specifier,\n )),\n )),\n\n // The `auto` storage class is removed in C++0x in order to allow for the `auto` type.\n storage_class_specifier: (_, original) => choice(\n ...original.members.filter((member) => member.value !== \'auto\'),\n \'thread_local\',\n ),\n\n dependent_type: $ => prec.dynamic(-1, prec.right(seq(\n \'typename\',\n $._type_specifier,\n ))),\n\n // Declarations\n\n template_declaration: $ => seq(\n \'template\',\n field(\'parameters\', $.template_parameter_list),\n optional($.requires_clause),\n choice(\n $._empty_declaration,\n $.alias_declaration,\n $.declaration,\n $.template_declaration,\n $.function_definition,\n $.concept_definition,\n $.friend_declaration,\n alias($.constructor_or_destructor_declaration, $.declaration),\n alias($.constructor_or_destructor_definition, $.function_definition),\n alias($.operator_cast_declaration, $.declaration),\n alias($.operator_cast_definition, $.function_definition),\n ),\n ),\n\n template_instantiation: $ => seq(\n \'template\',\n optional($._declaration_specifiers),\n field(\'declarator\', $._declarator),\n \';\',\n ),\n\n template_parameter_list: $ => seq(\n \'<\',\n commaSep(choice(\n $.parameter_declaration,\n $.optional_parameter_declaration,\n $.type_parameter_declaration,\n $.variadic_parameter_declaration,\n $.variadic_type_parameter_declaration,\n $.optional_type_parameter_declaration,\n $.template_template_parameter_declaration,\n )),\n alias(token(prec(1, \'>\')), \'>\'),\n ),\n\n type_parameter_declaration: $ => prec(1, seq(\n choice(\'typename\', \'class\'),\n optional($._type_identifier),\n )),\n\n variadic_type_parameter_declaration: $ => prec(1, seq(\n choice(\'typename\', \'class\'),\n \'...\',\n optional($._type_identifier),\n )),\n\n optional_type_parameter_declaration: $ => seq(\n choice(\'typename\', \'class\'),\n optional(field(\'name\', $._type_identifier)),\n \'=\',\n field(\'default_type\', $._type_specifier),\n ),\n\n template_template_parameter_declaration: $ => seq(\n \'template\',\n field(\'parameters\', $.template_parameter_list),\n choice(\n $.type_parameter_declaration,\n $.variadic_type_parameter_declaration,\n $.optional_type_parameter_declaration,\n ),\n ),\n\n parameter_list: $ => seq(\n \'(\',\n commaSep(choice(\n $.parameter_declaration,\n $.optional_parameter_declaration,\n $.variadic_parameter_declaration,\n \'...\',\n )),\n \')\',\n ),\n\n optional_parameter_declaration: $ => seq(\n $._declaration_specifiers,\n field(\'declarator\', optional(choice($._declarator, $.abstract_reference_declarator))),\n \'=\',\n field(\'default_value\', $._expression),\n ),\n\n variadic_parameter_declaration: $ => seq(\n $._declaration_specifiers,\n field(\'declarator\', choice(\n $.variadic_declarator,\n alias($.variadic_reference_declarator, $.reference_declarator),\n )),\n ),\n\n variadic_declarator: $ => seq(\n \'...\',\n optional($.identifier),\n ),\n\n variadic_reference_declarator: $ => seq(\n choice(\'&&\', \'&\'),\n $.variadic_declarator,\n ),\n\n init_declarator: ($, original) => choice(\n original,\n seq(\n field(\'declarator\', $._declarator),\n field(\'value\', choice(\n $.argument_list,\n $.initializer_list,\n )),\n ),\n ),\n\n operator_cast: $ => prec.right(1, seq(\n \'operator\',\n $._declaration_specifiers,\n field(\'declarator\', $._abstract_declarator),\n )),\n\n // Avoid ambiguity between compound statement and initializer list in a construct like:\n // A b {};\n compound_statement: (_, original) => prec(-1, original),\n\n field_initializer_list: $ => seq(\n \':\',\n commaSep1($.field_initializer),\n ),\n\n field_initializer: $ => prec(1, seq(\n choice(\n $._field_identifier,\n $.template_method,\n alias($.qualified_field_identifier, $.qualified_identifier),\n ),\n choice($.initializer_list, $.argument_list),\n optional(\'...\'),\n )),\n\n _field_declaration_list_item: ($, original) => choice(\n original,\n $.template_declaration,\n alias($.inline_method_definition, $.function_definition),\n alias($.constructor_or_destructor_definition, $.function_definition),\n alias($.constructor_or_destructor_declaration, $.declaration),\n alias($.operator_cast_definition, $.function_definition),\n alias($.operator_cast_declaration, $.declaration),\n $.friend_declaration,\n seq($.access_specifier, \':\'),\n $.alias_declaration,\n $.using_declaration,\n $.type_definition,\n $.static_assert_declaration,\n ),\n\n field_declaration: $ => seq(\n $._declaration_specifiers,\n commaSep(seq(\n field(\'declarator\', $._field_declarator),\n optional(choice(\n $.bitfield_clause,\n field(\'default_value\', $.initializer_list),\n seq(\'=\', field(\'default_value\', choice($._expression, $.initializer_list))),\n )),\n )),\n optional($.attribute_specifier),\n \';\',\n ),\n\n inline_method_definition: $ => seq(\n $._declaration_specifiers,\n field(\'declarator\', $._field_declarator),\n choice(\n field(\'body\', choice($.compound_statement, $.try_statement)),\n $.default_method_clause,\n $.delete_method_clause,\n ),\n ),\n\n _constructor_specifiers: $ => choice(\n $._declaration_modifiers,\n $.explicit_function_specifier,\n ),\n\n operator_cast_definition: $ => seq(\n repeat($._constructor_specifiers),\n field(\'declarator\', choice(\n $.operator_cast,\n alias($.qualified_operator_cast_identifier, $.qualified_identifier),\n )),\n field(\'body\', choice($.compound_statement, $.try_statement)),\n ),\n\n operator_cast_declaration: $ => prec(1, seq(\n repeat($._constructor_specifiers),\n field(\'declarator\', choice(\n $.operator_cast,\n alias($.qualified_operator_cast_identifier, $.qualified_identifier),\n )),\n optional(seq(\'=\', field(\'default_value\', $._expression))),\n \';\',\n )),\n\n constructor_try_statement: $ => seq(\n \'try\',\n optional($.field_initializer_list),\n field(\'body\', $.compound_statement),\n repeat1($.catch_clause),\n ),\n\n constructor_or_destructor_definition: $ => seq(\n repeat($._constructor_specifiers),\n field(\'declarator\', $.function_declarator),\n choice(\n seq(\n optional($.field_initializer_list),\n field(\'body\', $.compound_statement),\n ),\n alias($.constructor_try_statement, $.try_statement),\n $.default_method_clause,\n $.delete_method_clause,\n ),\n ),\n\n constructor_or_destructor_declaration: $ => seq(\n repeat($._constructor_specifiers),\n field(\'declarator\', $.function_declarator),\n \';\',\n ),\n\n default_method_clause: _ => seq(\'=\', \'default\', \';\'),\n delete_method_clause: _ => seq(\'=\', \'delete\', \';\'),\n\n friend_declaration: $ => seq(\n \'friend\',\n choice(\n $.declaration,\n $.function_definition,\n seq(\n optional(choice(\n \'class\',\n \'struct\',\n \'union\',\n )),\n $._class_name, \';\',\n ),\n ),\n ),\n\n access_specifier: _ => choice(\n \'public\',\n \'private\',\n \'protected\',\n ),\n\n _declarator: ($, original) => choice(\n original,\n $.reference_declarator,\n $.qualified_identifier,\n $.template_function,\n $.operator_name,\n $.destructor_name,\n $.structured_binding_declarator,\n ),\n\n _field_declarator: ($, original) => choice(\n original,\n alias($.reference_field_declarator, $.reference_declarator),\n $.template_method,\n $.operator_name,\n ),\n\n _abstract_declarator: ($, original) => choice(\n original,\n $.abstract_reference_declarator,\n ),\n\n reference_declarator: $ => prec.dynamic(1, prec.right(seq(choice(\'&\', \'&&\'), $._declarator))),\n reference_field_declarator: $ => prec.dynamic(1, prec.right(seq(choice(\'&\', \'&&\'), $._field_declarator))),\n abstract_reference_declarator: $ => prec.right(seq(choice(\'&\', \'&&\'), optional($._abstract_declarator))),\n\n structured_binding_declarator: $ => prec.dynamic(PREC.STRUCTURED_BINDING, seq(\n \'[\', commaSep1($.identifier), \']\',\n )),\n\n ref_qualifier: _ => choice(\'&\', \'&&\'),\n\n _function_declarator_seq: $ => seq(\n field(\'parameters\', $.parameter_list),\n optional($._function_attributes_start),\n optional($.ref_qualifier),\n optional($._function_exception_specification),\n optional($._function_attributes_end),\n optional($.trailing_return_type),\n optional($._function_postfix),\n ),\n\n _function_attributes_start: $ => prec(1, choice(\n seq(repeat1($.attribute_specifier), repeat($.type_qualifier)),\n seq(repeat($.attribute_specifier), repeat1($.type_qualifier)),\n )),\n\n _function_exception_specification: $ => choice(\n $.noexcept,\n $.throw_specifier,\n ),\n\n _function_attributes_end: $ => prec.right(seq(\n optional($.gnu_asm_expression),\n choice(\n seq(repeat1($.attribute_specifier), repeat($.attribute_declaration)),\n seq(repeat($.attribute_specifier), repeat1($.attribute_declaration)),\n ),\n )),\n\n _function_postfix: $ => prec.right(choice(\n repeat1($.virtual_specifier),\n $.requires_clause,\n )),\n\n function_declarator: $ => prec.dynamic(1, seq(\n field(\'declarator\', $._declarator),\n $._function_declarator_seq,\n )),\n\n function_field_declarator: $ => prec.dynamic(1, seq(\n field(\'declarator\', $._field_declarator),\n $._function_declarator_seq,\n )),\n\n abstract_function_declarator: $ => seq(\n field(\'declarator\', optional($._abstract_declarator)),\n $._function_declarator_seq,\n ),\n\n trailing_return_type: $ => seq(\'->\', $.type_descriptor),\n\n noexcept: $ => prec.right(seq(\n \'noexcept\',\n optional(\n seq(\n \'(\',\n optional($._expression),\n \')\',\n ),\n ),\n )),\n\n throw_specifier: $ => seq(\n \'throw\',\n seq(\n \'(\',\n commaSep($.type_descriptor),\n \')\',\n ),\n ),\n\n template_type: $ => seq(\n field(\'name\', $._type_identifier),\n field(\'arguments\', $.template_argument_list),\n ),\n\n template_method: $ => seq(\n field(\'name\', choice($._field_identifier, $.operator_name)),\n field(\'arguments\', $.template_argument_list),\n ),\n\n template_function: $ => seq(\n field(\'name\', $.identifier),\n field(\'arguments\', $.template_argument_list),\n ),\n\n template_argument_list: $ => seq(\n \'<\',\n commaSep(choice(\n prec.dynamic(3, $.type_descriptor),\n prec.dynamic(2, alias($.type_parameter_pack_expansion, $.parameter_pack_expansion)),\n prec.dynamic(1, $._expression),\n )),\n alias(token(prec(1, \'>\')), \'>\'),\n ),\n\n namespace_definition: $ => seq(\n optional(\'inline\'),\n \'namespace\',\n field(\'name\', optional(\n choice(\n $._namespace_identifier,\n $.nested_namespace_specifier,\n ))),\n field(\'body\', $.declaration_list),\n ),\n\n namespace_alias_definition: $ => seq(\n \'namespace\',\n field(\'name\', $._namespace_identifier),\n \'=\',\n choice(\n $._namespace_identifier,\n $.nested_namespace_specifier,\n ),\n \';\',\n ),\n\n _namespace_specifier: $ => seq(\n optional(\'inline\'),\n $._namespace_identifier,\n ),\n\n nested_namespace_specifier: $ => prec(1, seq(\n optional($._namespace_specifier),\n \'::\',\n choice(\n $.nested_namespace_specifier,\n $._namespace_specifier,\n ),\n )),\n\n using_declaration: $ => seq(\n \'using\',\n optional(choice(\'namespace\', \'enum\')),\n choice(\n $.identifier,\n $.qualified_identifier,\n ),\n \';\',\n ),\n\n alias_declaration: $ => seq(\n \'using\',\n field(\'name\', $._type_identifier),\n repeat($.attribute_declaration),\n \'=\',\n field(\'type\', $.type_descriptor),\n \';\',\n ),\n\n static_assert_declaration: $ => seq(\n \'static_assert\',\n \'(\',\n field(\'condition\', $._expression),\n optional(seq(\n \',\',\n field(\'message\', choice(\n $.string_literal,\n $.raw_string_literal,\n $.concatenated_string,\n )),\n )),\n \')\',\n \';\',\n ),\n\n concept_definition: $ => seq(\n \'concept\',\n field(\'name\', $.identifier),\n \'=\',\n $._expression,\n \';\',\n ),\n\n // Statements\n\n _top_level_statement: ($, original) => choice(\n original,\n $.co_return_statement,\n $.co_yield_statement,\n $.for_range_loop,\n $.try_statement,\n $.throw_statement,\n ),\n\n _non_case_statement: ($, original) => choice(\n original,\n $.co_return_statement,\n $.co_yield_statement,\n $.for_range_loop,\n $.try_statement,\n $.throw_statement,\n ),\n\n switch_statement: $ => seq(\n \'switch\',\n field(\'condition\', $.condition_clause),\n field(\'body\', $.compound_statement),\n ),\n\n while_statement: $ => seq(\n \'while\',\n field(\'condition\', $.condition_clause),\n field(\'body\', $._statement),\n ),\n\n if_statement: $ => prec.right(seq(\n \'if\',\n optional(\'constexpr\'),\n field(\'condition\', $.condition_clause),\n field(\'consequence\', $._statement),\n optional(field(\'alternative\', $.else_clause)),\n )),\n\n // Using prec(1) instead of prec.dynamic(1) causes issues with the\n // range loop\'s declaration specifiers if `int` is passed in, it\'ll\n // always prefer the standard for loop and give us a parse error.\n _for_statement_body: ($, original) => prec.dynamic(1, original),\n for_range_loop: $ => seq(\n \'for\',\n \'(\',\n $._for_range_loop_body,\n \')\',\n field(\'body\', $._statement),\n ),\n _for_range_loop_body: $ => seq(\n field(\'initializer\', optional($.init_statement)),\n $._declaration_specifiers,\n field(\'declarator\', $._declarator),\n \':\',\n field(\'right\', choice(\n $._expression,\n $.initializer_list,\n )),\n ),\n\n init_statement: $ => choice(\n $.alias_declaration,\n $.type_definition,\n $.declaration,\n $.expression_statement,\n ),\n\n condition_clause: $ => seq(\n \'(\',\n field(\'initializer\', optional($.init_statement)),\n field(\'value\', choice(\n $._expression,\n $.comma_expression,\n alias($.condition_declaration, $.declaration),\n )),\n \')\',\n ),\n\n condition_declaration: $ => seq(\n $._declaration_specifiers,\n field(\'declarator\', $._declarator),\n choice(\n seq(\n \'=\',\n field(\'value\', $._expression),\n ),\n field(\'value\', $.initializer_list),\n ),\n ),\n\n return_statement: ($, original) => seq(\n choice(\n original,\n seq(\'return\', $.initializer_list, \';\'),\n ),\n ),\n\n co_return_statement: $ => seq(\n \'co_return\',\n optional($._expression),\n \';\',\n ),\n\n co_yield_statement: $ => seq(\n \'co_yield\',\n $._expression,\n \';\',\n ),\n\n throw_statement: $ => seq(\n \'throw\',\n optional($._expression),\n \';\',\n ),\n\n try_statement: $ => seq(\n \'try\',\n field(\'body\', $.compound_statement),\n repeat1($.catch_clause),\n ),\n\n catch_clause: $ => seq(\n \'catch\',\n field(\'parameters\', $.parameter_list),\n field(\'body\', $.compound_statement),\n ),\n\n // Expressions\n\n _expression_not_binary: ($, original) => choice(\n original,\n $.co_await_expression,\n $.requires_expression,\n $.requires_clause,\n $.template_function,\n $.qualified_identifier,\n $.new_expression,\n $.delete_expression,\n $.lambda_expression,\n $.parameter_pack_expansion,\n $.this,\n $.raw_string_literal,\n $.user_defined_literal,\n $.fold_expression,\n ),\n\n raw_string_literal: $ => seq(\n choice(\'R\"\', \'LR\"\', \'uR\"\', \'UR\"\', \'u8R\"\'),\n choice(\n seq(\n field(\'delimiter\', $.raw_string_delimiter),\n \'(\',\n $.raw_string_content,\n \')\',\n $.raw_string_delimiter,\n ),\n seq(\n \'(\',\n $.raw_string_content,\n \')\',\n )),\n \'\"\',\n ),\n\n subscript_expression: $ => prec(PREC.SUBSCRIPT, seq(\n field(\'argument\', $._expression),\n field(\'indices\', $.subscript_argument_list),\n )),\n\n subscript_argument_list: $ => seq(\n \'[\',\n commaSep(choice($._expression, $.initializer_list)),\n \']\',\n ),\n\n call_expression: ($, original) => choice(original, seq(\n field(\'function\', $.primitive_type),\n field(\'arguments\', $.argument_list),\n )),\n\n co_await_expression: $ => prec.left(PREC.UNARY, seq(\n field(\'operator\', \'co_await\'),\n field(\'argument\', $._expression),\n )),\n\n new_expression: $ => prec.right(PREC.NEW, seq(\n optional(\'::\'),\n \'new\',\n field(\'placement\', optional($.argument_list)),\n field(\'type\', $._type_specifier),\n field(\'declarator\', optional($.new_declarator)),\n field(\'arguments\', optional(choice(\n $.argument_list,\n $.initializer_list,\n ))),\n )),\n\n new_declarator: $ => prec.right(seq(\n \'[\',\n field(\'length\', $._expression),\n \']\',\n optional($.new_declarator),\n )),\n\n delete_expression: $ => seq(\n optional(\'::\'),\n \'delete\',\n optional(seq(\'[\', \']\')),\n $._expression,\n ),\n\n field_expression: $ => prec.right(seq(\n prec(PREC.FIELD, seq(\n field(\'argument\', $._expression),\n field(\'operator\', choice(\'.\', \'.*\', \'->\')),\n )),\n field(\'field\', choice(\n $._field_identifier,\n alias($.qualified_field_identifier, $.qualified_identifier),\n $.destructor_name,\n $.template_method,\n alias($.dependent_field_identifier, $.dependent_name),\n )),\n )),\n\n type_requirement: $ => seq(\'typename\', $._class_name),\n\n compound_requirement: $ => seq(\n \'{\', $._expression, \'}\',\n optional(\'noexcept\'),\n optional($.trailing_return_type),\n \';\',\n ),\n\n _requirement: $ => choice(\n alias($.expression_statement, $.simple_requirement),\n $.type_requirement,\n $.compound_requirement,\n ),\n\n requirement_seq: $ => seq(\'{\', repeat($._requirement), \'}\'),\n\n constraint_conjunction: $ => prec.left(PREC.LOGICAL_AND, seq(\n field(\'left\', $._requirement_clause_constraint),\n field(\'operator\', choice(\'&&\', \'and\')),\n field(\'right\', $._requirement_clause_constraint)),\n ),\n\n constraint_disjunction: $ => prec.left(PREC.LOGICAL_OR, seq(\n field(\'left\', $._requirement_clause_constraint),\n field(\'operator\', choice(\'||\', \'or\')),\n field(\'right\', $._requirement_clause_constraint)),\n ),\n\n _requirement_clause_constraint: $ => choice(\n // Primary expressions\"\n $.true,\n $.false,\n $._class_name,\n $.fold_expression,\n $.lambda_expression,\n $.requires_expression,\n\n // Parenthesized expressions\n seq(\'(\', $._expression, \')\'),\n\n // conjunction or disjunction of the above\n $.constraint_conjunction,\n $.constraint_disjunction,\n ),\n\n requires_clause: $ => seq(\n \'requires\',\n field(\'constraint\', $._requirement_clause_constraint),\n ),\n\n requires_parameter_list: $ => seq(\n \'(\',\n commaSep(choice(\n $.parameter_declaration,\n $.optional_parameter_declaration,\n $.variadic_parameter_declaration,\n )),\n \')\',\n ),\n\n requires_expression: $ => seq(\n \'requires\',\n field(\'parameters\', optional(alias($.requires_parameter_list, $.parameter_list))),\n field(\'requirements\', $.requirement_seq),\n ),\n\n lambda_expression: $ => seq(\n field(\'captures\', $.lambda_capture_specifier),\n optional(seq(\n field(\'template_parameters\', $.template_parameter_list),\n optional(field(\'constraint\', $.requires_clause)),\n )),\n optional(field(\'declarator\', $.abstract_function_declarator)),\n field(\'body\', $.compound_statement),\n ),\n\n lambda_capture_specifier: $ => prec(PREC.LAMBDA, seq(\n \'[\',\n choice(\n $.lambda_default_capture,\n commaSep($._expression),\n seq(\n $.lambda_default_capture,\n \',\', commaSep1($._expression),\n ),\n ),\n \']\',\n )),\n\n lambda_default_capture: _ => choice(\'=\', \'&\'),\n\n _fold_operator: _ => choice(...FOLD_OPERATORS),\n _binary_fold_operator: _ => choice(...FOLD_OPERATORS.map((operator) => seq(field(\'operator\', operator), \'...\', operator))),\n\n _unary_left_fold: $ => seq(\n field(\'left\', \'...\'),\n field(\'operator\', $._fold_operator),\n field(\'right\', $._expression),\n ),\n _unary_right_fold: $ => seq(\n field(\'left\', $._expression),\n field(\'operator\', $._fold_operator),\n field(\'right\', \'...\'),\n ),\n _binary_fold: $ => seq(\n field(\'left\', $._expression),\n $._binary_fold_operator,\n field(\'right\', $._expression),\n ),\n\n fold_expression: $ => seq(\n \'(\',\n choice(\n $._unary_right_fold,\n $._unary_left_fold,\n $._binary_fold,\n ),\n \')\',\n ),\n\n parameter_pack_expansion: $ => prec(-1, seq(\n field(\'pattern\', $._expression),\n \'...\',\n )),\n\n type_parameter_pack_expansion: $ => seq(\n field(\'pattern\', $.type_descriptor),\n \'...\',\n ),\n\n sizeof_expression: ($, original) => prec.right(PREC.SIZEOF, choice(\n original,\n seq(\n \'sizeof\', \'...\',\n \'(\',\n field(\'value\', $.identifier),\n \')\',\n ),\n )),\n\n unary_expression: ($, original) => choice(\n original,\n prec.left(PREC.UNARY, seq(\n field(\'operator\', choice(\'not\', \'compl\')),\n field(\'argument\', $._expression),\n )),\n ),\n\n binary_expression: ($, original) => {\n const table = [\n [\'<=>\', PREC.THREE_WAY],\n [\'or\', PREC.LOGICAL_OR],\n [\'and\', PREC.LOGICAL_AND],\n [\'bitor\', PREC.INCLUSIVE_OR],\n [\'xor\', PREC.EXCLUSIVE_OR],\n [\'bitand\', PREC.BITWISE_AND],\n [\'not_eq\', PREC.EQUAL],\n ];\n\n return choice(\n ...original.members,\n ...table.map(([operator, precedence]) => {\n return prec.left(precedence, seq(\n field(\'left\', $._expression),\n // @ts-ignore\n field(\'operator\', operator),\n field(\'right\', $._expression),\n ));\n }));\n },\n\n // The compound_statement is added to parse macros taking statements as arguments, e.g. MYFORLOOP(1, 10, i, { foo(i); bar(i); })\n argument_list: $ => seq(\n \'(\',\n commaSep(choice(seq(optional(\'__extension__\'), $._expression), $.initializer_list, $.compound_statement)),\n \')\',\n ),\n\n destructor_name: $ => prec(1, seq(\'~\', $.identifier)),\n\n compound_literal_expression: ($, original) => choice(\n original,\n seq(\n field(\'type\', choice($._class_name, $.primitive_type)),\n field(\'value\', $.initializer_list),\n ),\n ),\n\n dependent_identifier: $ => seq(\'template\', $.template_function),\n dependent_field_identifier: $ => seq(\'template\', $.template_method),\n dependent_type_identifier: $ => seq(\'template\', $.template_type),\n\n _scope_resolution: $ => prec(1, seq(\n field(\'scope\', optional(choice(\n $._namespace_identifier,\n $.template_type,\n $.decltype,\n alias($.dependent_type_identifier, $.dependent_name),\n ))),\n \'::\',\n )),\n\n qualified_field_identifier: $ => prec.right(seq(\n $._scope_resolution,\n field(\'name\', choice(\n alias($.dependent_field_identifier, $.dependent_name),\n alias($.qualified_field_identifier, $.qualified_identifier),\n $.template_method,\n $._field_identifier,\n )),\n )),\n\n qualified_identifier: $ => seq(\n $._scope_resolution,\n field(\'name\', choice(\n alias($.dependent_identifier, $.dependent_name),\n $.qualified_identifier,\n $.template_function,\n seq(optional(\'template\'), $.identifier),\n $.operator_name,\n $.destructor_name,\n $.pointer_type_declarator,\n )),\n ),\n\n qualified_type_identifier: $ => seq(\n $._scope_resolution,\n field(\'name\', choice(\n alias($.dependent_type_identifier, $.dependent_name),\n alias($.qualified_type_identifier, $.qualified_identifier),\n $.template_type,\n $._type_identifier,\n )),\n ),\n\n qualified_operator_cast_identifier: $ => seq(\n $._scope_resolution,\n field(\'name\', choice(\n alias($.qualified_operator_cast_identifier, $.qualified_identifier),\n $.operator_cast,\n )),\n ),\n\n _assignment_left_expression: ($, original) => choice(\n original,\n $.qualified_identifier,\n $.user_defined_literal,\n ),\n\n assignment_expression: $ => prec.right(PREC.ASSIGNMENT, seq(\n field(\'left\', $._assignment_left_expression),\n field(\'operator\', choice(...ASSIGNMENT_OPERATORS)),\n field(\'right\', choice($._expression, $.initializer_list)),\n )),\n\n _assignment_expression_lhs: $ => seq(\n field(\'left\', $._expression),\n field(\'operator\', choice(...ASSIGNMENT_OPERATORS)),\n field(\'right\', choice($._expression, $.initializer_list)),\n ),\n\n // This prevents an ambiguity between fold expressions\n // and assignment expressions within parentheses.\n parenthesized_expression: ($, original) => choice(\n original,\n seq(\'(\', alias($._assignment_expression_lhs, $.assignment_expression), \')\'),\n ),\n\n operator_name: $ => prec(1, seq(\n \'operator\',\n choice(\n \'co_await\',\n \'+\', \'-\', \'*\', \'/\', \'%\',\n \'^\', \'&\', \'|\', \'~\',\n \'!\', \'=\', \'<\', \'>\',\n \'+=\', \'-=\', \'*=\', \'/=\', \'%=\', \'^=\', \'&=\', \'|=\',\n \'<<\', \'>>\', \'>>=\', \'<<=\',\n \'==\', \'!=\', \'<=\', \'>=\',\n \'<=>\',\n \'&&\', \'||\',\n \'++\', \'--\',\n \',\',\n \'->*\',\n \'->\',\n \'()\', \'[]\',\n \'xor\', \'bitand\', \'bitor\', \'compl\',\n \'not\', \'xor_eq\', \'and_eq\', \'or_eq\', \'not_eq\',\n \'and\', \'or\',\n seq(choice(\'new\', \'delete\'), optional(\'[]\')),\n seq(\'\"\"\', $.identifier),\n ),\n )),\n\n this: _ => \'this\',\n\n concatenated_string: $ => prec.right(seq(\n choice($.identifier, $.string_literal, $.raw_string_literal),\n choice($.string_literal, $.raw_string_literal),\n repeat(choice($.identifier, $.string_literal, $.raw_string_literal)),\n )),\n\n number_literal: $ => {\n const sign = /[-\\+]/;\n const separator = \'\\\'\';\n const binary = /[01]/;\n const binaryDigits = seq(repeat1(binary), repeat(seq(separator, repeat1(binary))));\n const decimal = /[0-9]/;\n const firstDecimal = /[1-9]/;\n const intDecimalDigits = seq(firstDecimal, repeat(decimal), repeat(seq(separator, repeat1(decimal))));\n const floatDecimalDigits = seq(repeat1(decimal), repeat(seq(separator, repeat1(decimal))));\n const hex = /[0-9a-fA-F]/;\n const hexDigits = seq(repeat1(hex), repeat(seq(separator, repeat1(hex))));\n const octal = /[0-7]/;\n const octalDigits = seq(\'0\', repeat(octal), repeat(seq(separator, repeat1(octal))));\n const hexExponent = seq(/[pP]/, optional(sign), floatDecimalDigits);\n const decimalExponent = seq(/[eE]/, optional(sign), floatDecimalDigits);\n const intSuffix = /(ll|LL)[uU]?|[uU](ll|LL)?|[uU][lL]?|[uU][zZ]?|[lL][uU]?|[zZ][uU]?/;\n const floatSuffix = /([fF](16|32|64|128)?)|[lL]|(bf16|BF16)/;\n\n return token(seq(\n optional(sign),\n choice(\n seq(\n choice(\n seq(choice(\'0b\', \'0B\'), binaryDigits),\n intDecimalDigits,\n seq(choice(\'0x\', \'0X\'), hexDigits),\n octalDigits,\n ),\n optional(intSuffix),\n ),\n seq(\n choice(\n seq(floatDecimalDigits, decimalExponent),\n seq(floatDecimalDigits, \'.\', optional(floatDecimalDigits), optional(decimalExponent)),\n seq(\'.\', floatDecimalDigits, optional(decimalExponent)),\n seq(\n choice(\'0x\', \'0X\'),\n choice(\n hexDigits,\n seq(hexDigits, \'.\', optional(hexDigits)),\n seq(\'.\', hexDigits)),\n hexExponent,\n ),\n ),\n optional(floatSuffix),\n ),\n ),\n ));\n },\n\n literal_suffix: _ => token.immediate(/[a-zA-Z_]\\w*/),\n\n user_defined_literal: $ => seq(\n choice(\n $.number_literal,\n $.char_literal,\n $.string_literal,\n $.raw_string_literal,\n $.concatenated_string,\n ),\n $.literal_suffix,\n ),\n\n _namespace_identifier: $ => alias($.identifier, $.namespace_identifier),\n },\n});\n\n/**\n * Creates a rule to optionally match one or more of the rules separated by a comma\n *\n * @param {Rule} rule\n *\n * @return {ChoiceRule}\n *\n */\nfunction commaSep(rule) {\n return optional(commaSep1(rule));\n}\n\n/**\n * Creates a rule to match one or more of the rules separated by a comma\n *\n * @param {Rule} rule\n *\n * @return {SeqRule}\n *\n */\nfunction commaSep1(rule) {\n return seq(rule, repeat(seq(\',\', rule)));\n}\n";
Expand description
The source of the Cpp tree-sitter grammar description.