[−][src]Constant tree_sitter_python::GRAMMAR
pub const GRAMMAR: &'static str = "const PREC = {\n // this resolves a conflict between the usage of \':\' in a lambda vs in a\n // typed parameter. In the case of a lambda, we don\'t allow typed parameters.\n lambda: -2,\n typed_parameter: -1,\n conditional: -1,\n\n parenthesized_expression: 1,\n parenthesized_list_splat: 1,\n not: 1,\n compare: 2,\n or: 10,\n and: 11,\n bitwise_or: 12,\n bitwise_and: 13,\n xor: 14,\n shift: 15,\n plus: 16,\n times: 17,\n unary: 18,\n power: 19,\n call: 20,\n}\n\nmodule.exports = grammar({\n name: \'python\',\n\n extras: $ => [\n $.comment,\n /[\\s\\f\\uFEFF\\u2060\\u200B]|\\\\\\r?\\n/\n ],\n\n conflicts: $ => [\n [$.primary_expression, $.pattern],\n [$.primary_expression, $.list_splat_pattern],\n [$.tuple, $.tuple_pattern],\n [$.list, $.list_pattern],\n ],\n\n supertypes: $ => [\n $._simple_statement,\n $._compound_statement,\n $.expression,\n $.primary_expression,\n $.pattern,\n $.parameter,\n ],\n\n externals: $ => [\n $._newline,\n $._indent,\n $._dedent,\n $._string_start,\n $._string_content,\n $._string_end,\n ],\n\n inline: $ => [\n $._simple_statement,\n $._compound_statement,\n $._suite,\n $.keyword_identifier,\n ],\n\n word: $ => $.identifier,\n\n rules: {\n module: $ => repeat($._statement),\n\n _statement: $ => choice(\n $._simple_statements,\n $._compound_statement\n ),\n\n // Simple statements\n\n _simple_statements: $ => seq(\n $._simple_statement,\n optional(repeat(seq(\n $._semicolon,\n $._simple_statement\n ))),\n optional($._semicolon),\n $._newline\n ),\n\n _simple_statement: $ => choice(\n $.future_import_statement,\n $.import_statement,\n $.import_from_statement,\n $.print_statement,\n $.assert_statement,\n $.expression_statement,\n $.return_statement,\n $.delete_statement,\n $.raise_statement,\n $.pass_statement,\n $.break_statement,\n $.continue_statement,\n $.global_statement,\n $.nonlocal_statement,\n $.exec_statement\n ),\n\n import_statement: $ => seq(\n \'import\',\n $._import_list\n ),\n\n import_prefix: $ => repeat1(\'.\'),\n\n relative_import: $ => seq(\n $.import_prefix,\n optional($.dotted_name)\n ),\n\n future_import_statement: $ => seq(\n \'from\',\n \'__future__\',\n \'import\',\n choice(\n $._import_list,\n seq(\'(\', $._import_list, \')\'),\n )\n ),\n\n import_from_statement: $ => seq(\n \'from\',\n field(\'module_name\', choice(\n $.relative_import,\n $.dotted_name\n )),\n \'import\',\n choice(\n $.wildcard_import,\n $._import_list,\n seq(\'(\', $._import_list, \')\')\n )\n ),\n\n _import_list: $ => seq(\n commaSep1(field(\'name\', choice(\n $.dotted_name,\n $.aliased_import\n ))),\n optional(\',\')\n ),\n\n aliased_import: $ => seq(\n field(\'name\', $.dotted_name),\n \'as\',\n field(\'alias\', $.identifier)\n ),\n\n wildcard_import: $ => \'*\',\n\n print_statement: $ => choice(\n prec(1, seq(\n \'print\',\n $.chevron,\n repeat(seq(\',\', field(\'argument\', $.expression))),\n optional(\',\'))\n ),\n prec(-1, seq(\n \'print\',\n commaSep1(field(\'argument\', $.expression)),\n optional(\',\'))\n )\n ),\n\n chevron: $ => seq(\n \'>>\',\n $.expression\n ),\n\n assert_statement: $ => seq(\n \'assert\',\n commaSep1($.expression)\n ),\n\n expression_statement: $ => choice(\n $.expression,\n seq(commaSep1($.expression), optional(\',\')),\n $.assignment,\n $.augmented_assignment,\n $.yield\n ),\n\n named_expression: $ => seq(\n field(\'name\', $.identifier),\n \':=\',\n field(\'value\', $.expression)\n ),\n\n return_statement: $ => seq(\n \'return\',\n optional($.expression_list)\n ),\n\n delete_statement: $ => seq(\n \'del\',\n $.expression_list\n ),\n\n raise_statement: $ => seq(\n \'raise\',\n optional($.expression_list),\n optional(seq(\'from\', field(\'cause\', $.expression)))\n ),\n\n pass_statement: $ => prec.left(\'pass\'),\n break_statement: $ => prec.left(\'break\'),\n continue_statement: $ => prec.left(\'continue\'),\n\n // Compound statements\n\n _compound_statement: $ => choice(\n $.if_statement,\n $.for_statement,\n $.while_statement,\n $.try_statement,\n $.with_statement,\n $.function_definition,\n $.class_definition,\n $.decorated_definition\n ),\n\n if_statement: $ => seq(\n \'if\',\n field(\'condition\', $.expression),\n \':\',\n field(\'consequence\', $._suite),\n repeat(field(\'alternative\', $.elif_clause)),\n optional(field(\'alternative\', $.else_clause))\n ),\n\n elif_clause: $ => seq(\n \'elif\',\n field(\'condition\', $.expression),\n \':\',\n field(\'consequence\', $._suite)\n ),\n\n else_clause: $ => seq(\n \'else\',\n \':\',\n field(\'body\', $._suite)\n ),\n\n for_statement: $ => seq(\n optional(\'async\'),\n \'for\',\n field(\'left\', $.left_hand_side),\n \'in\',\n field(\'right\', $.expression_list),\n \':\',\n field(\'body\', $._suite),\n field(\'alternative\', optional($.else_clause))\n ),\n\n while_statement: $ => seq(\n \'while\',\n field(\'condition\', $.expression),\n \':\',\n field(\'body\', $._suite),\n optional(field(\'alternative\', $.else_clause))\n ),\n\n try_statement: $ => seq(\n \'try\',\n \':\',\n field(\'body\', $._suite),\n choice(\n seq(\n repeat1($.except_clause),\n optional($.else_clause),\n optional($.finally_clause)\n ),\n $.finally_clause\n )\n ),\n\n except_clause: $ => seq(\n \'except\',\n optional(seq(\n $.expression,\n optional(seq(\n choice(\'as\', \',\'),\n $.expression\n ))\n )),\n \':\',\n $._suite\n ),\n\n finally_clause: $ => seq(\n \'finally\',\n \':\',\n $._suite\n ),\n\n with_statement: $ => seq(\n optional(\'async\'),\n \'with\',\n commaSep1($.with_item),\n \':\',\n field(\'body\', $._suite)\n ),\n\n with_item: $ => seq(\n field(\'value\', $.expression),\n optional(seq(\n \'as\',\n field(\'alias\', $.pattern)\n ))\n ),\n\n function_definition: $ => seq(\n optional(\'async\'),\n \'def\',\n field(\'name\', $.identifier),\n field(\'parameters\', $.parameters),\n optional(\n seq(\n \'->\',\n field(\'return_type\', $.type)\n )\n ),\n \':\',\n field(\'body\', $._suite)\n ),\n\n parameters: $ => seq(\n \'(\',\n optional($._parameters),\n \')\'\n ),\n\n lambda_parameters: $ => $._parameters,\n\n _parameters: $ => seq(\n commaSep1($.parameter),\n optional(\',\')\n ),\n\n _patterns: $ => seq(\n commaSep1($.pattern),\n optional(\',\')\n ),\n\n parameter: $ => choice(\n $.identifier,\n $.keyword_identifier,\n $.typed_parameter,\n $.default_parameter,\n $.typed_default_parameter,\n $.list_splat_pattern,\n $.tuple_pattern,\n alias(\'*\', $.list_splat_pattern),\n $.dictionary_splat_pattern\n ),\n\n pattern: $ => choice(\n $.identifier,\n $.keyword_identifier,\n $.subscript,\n $.attribute,\n $.list_splat_pattern,\n $.tuple_pattern,\n $.list_pattern\n ),\n\n tuple_pattern: $ => seq(\n \'(\',\n optional($._patterns),\n \')\'\n ),\n\n list_pattern: $ => seq(\n \'[\',\n optional($._patterns),\n \']\'\n ),\n\n default_parameter: $ => seq(\n field(\'name\', choice($.identifier, $.keyword_identifier)),\n \'=\',\n field(\'value\', $.expression)\n ),\n\n typed_default_parameter: $ => prec(PREC.typed_parameter, seq(\n field(\'name\', choice($.identifier, $.keyword_identifier)),\n \':\',\n field(\'type\', $.type),\n \'=\',\n field(\'value\', $.expression)\n )),\n\n list_splat_pattern: $ => seq(\n \'*\',\n choice($.identifier, $.keyword_identifier, $.subscript, $.attribute)\n ),\n\n dictionary_splat_pattern: $ => seq(\n \'**\',\n choice($.identifier, $.keyword_identifier, $.subscript, $.attribute)\n ),\n\n list_splat: $ => seq(\n \'*\',\n $.expression,\n ),\n\n dictionary_splat: $ => seq(\n \'**\',\n $.expression\n ),\n\n global_statement: $ => seq(\n \'global\',\n commaSep1($.identifier)\n ),\n\n nonlocal_statement: $ => seq(\n \'nonlocal\',\n commaSep1($.identifier)\n ),\n\n exec_statement: $ => seq(\n \'exec\',\n field(\'code\', $.string),\n optional(\n seq(\n \'in\',\n commaSep1($.expression)\n )\n )\n ),\n\n class_definition: $ => seq(\n \'class\',\n field(\'name\', $.identifier),\n field(\'superclasses\', optional($.argument_list)),\n \':\',\n field(\'body\', $._suite)\n ),\n\n parenthesized_list_splat: $ => prec(PREC.parenthesized_list_splat, seq(\n \'(\',\n choice(\n alias($.parenthesized_list_splat, $.parenthesized_expression),\n $.list_splat,\n ),\n \')\',\n )),\n\n argument_list: $ => seq(\n \'(\',\n optional(commaSep1(\n choice(\n $.expression,\n $.list_splat,\n $.dictionary_splat,\n alias($.parenthesized_list_splat, $.parenthesized_expression),\n $.keyword_argument\n )\n )),\n optional(\',\'),\n \')\'\n ),\n\n decorated_definition: $ => seq(\n repeat1($.decorator),\n field(\'definition\', choice(\n $.class_definition,\n $.function_definition\n ))\n ),\n\n decorator: $ => seq(\n \'@\',\n $.dotted_name,\n field(\'arguments\', optional($.argument_list)),\n $._newline\n ),\n\n _suite: $ => choice(\n alias($._simple_statements, $.block),\n seq($._indent, $.block),\n alias($._newline, $.block)\n ),\n\n block: $ => seq(\n repeat($._statement),\n $._dedent\n ),\n\n expression_list: $ => prec.right(seq(\n commaSep1($.expression),\n optional(\',\')\n )),\n\n dotted_name: $ => sep1($.identifier, \'.\'),\n\n // Expressions\n _expression_within_for_in_clause: $ => choice(\n $.expression,\n alias($.lambda_within_for_in_clause, $.lambda)\n ),\n\n expression: $ => choice(\n $.comparison_operator,\n $.not_operator,\n $.boolean_operator,\n $.await,\n $.lambda,\n $.primary_expression,\n $.conditional_expression,\n $.named_expression\n ),\n\n primary_expression: $ => choice(\n $.binary_operator,\n $.identifier,\n $.keyword_identifier,\n $.string,\n $.concatenated_string,\n $.integer,\n $.float,\n $.true,\n $.false,\n $.none,\n $.unary_operator,\n $.attribute,\n $.subscript,\n $.call,\n $.list,\n $.list_comprehension,\n $.dictionary,\n $.dictionary_comprehension,\n $.set,\n $.set_comprehension,\n $.tuple,\n $.parenthesized_expression,\n $.generator_expression,\n $.ellipsis\n ),\n\n not_operator: $ => prec(PREC.not, seq(\n \'not\',\n field(\'argument\', $.expression)\n )),\n\n boolean_operator: $ => choice(\n prec.left(PREC.and, seq(\n field(\'left\', $.expression),\n field(\'operator\', \'and\'),\n field(\'right\', $.expression)\n )),\n prec.left(PREC.or, seq(\n field(\'left\', $.expression),\n field(\'operator\', \'or\'),\n field(\'right\', $.expression)\n ))\n ),\n\n binary_operator: $ => {\n const table = [\n [prec.left, \'+\', PREC.plus],\n [prec.left, \'-\', PREC.plus],\n [prec.left, \'*\', PREC.times],\n [prec.left, \'@\', PREC.times],\n [prec.left, \'/\', PREC.times],\n [prec.left, \'%\', PREC.times],\n [prec.left, \'//\', PREC.times],\n [prec.right, \'**\', PREC.power],\n [prec.left, \'|\', PREC.bitwise_or],\n [prec.left, \'&\', PREC.bitwise_and],\n [prec.left, \'^\', PREC.xor],\n [prec.left, \'<<\', PREC.shift],\n [prec.left, \'>>\', PREC.shift],\n ];\n\n return choice(...table.map(([fn, operator, precedence]) => fn(precedence, seq(\n field(\'left\', $.primary_expression),\n field(\'operator\', operator),\n field(\'right\', $.primary_expression)\n ))));\n },\n\n unary_operator: $ => prec(PREC.unary, seq(\n field(\'operator\', choice(\'+\', \'-\', \'~\')),\n field(\'argument\', $.primary_expression)\n )),\n\n comparison_operator: $ => prec.left(PREC.compare, seq(\n $.primary_expression,\n repeat1(seq(\n choice(\n \'<\',\n \'<=\',\n \'==\',\n \'!=\',\n \'>=\',\n \'>\',\n \'<>\',\n \'in\',\n seq(\'not\', \'in\'),\n \'is\',\n seq(\'is\', \'not\')\n ),\n $.primary_expression\n ))\n )),\n\n lambda: $ => prec(PREC.lambda, seq(\n \'lambda\',\n field(\'parameters\', optional($.lambda_parameters)),\n \':\',\n field(\'body\', $.expression)\n )),\n\n lambda_within_for_in_clause: $ => seq(\n \'lambda\',\n field(\'parameters\', optional($.lambda_parameters)),\n \':\',\n field(\'body\', $._expression_within_for_in_clause)\n ),\n\n assignment: $ => seq(\n field(\'left\', $.left_hand_side),\n choice(\n seq(\'=\', field(\'right\', $._right_hand_side)),\n seq(\':\', field(\'type\', $.type)),\n seq(\':\', field(\'type\', $.type), \'=\', field(\'right\', $._right_hand_side))\n )\n ),\n\n augmented_assignment: $ => seq(\n field(\'left\', $.left_hand_side),\n field(\'operator\', choice(\n \'+=\', \'-=\', \'*=\', \'/=\', \'@=\', \'//=\', \'%=\', \'**=\',\n \'>>=\', \'<<=\', \'&=\', \'^=\', \'|=\'\n )),\n field(\'right\', $._right_hand_side)\n ),\n\n left_hand_side: $ => $._patterns,\n\n _right_hand_side: $ => choice(\n $.expression_list,\n $.assignment,\n $.augmented_assignment,\n $.yield\n ),\n\n yield: $ => seq(\n \'yield\',\n choice(\n seq(\n \'from\',\n $.expression\n ),\n optional($.expression_list)\n )\n ),\n\n attribute: $ => prec(PREC.call, seq(\n field(\'object\', $.primary_expression),\n \'.\',\n field(\'attribute\', $.identifier)\n )),\n\n subscript: $ => prec(PREC.call, seq(\n field(\'value\', $.primary_expression),\n \'[\',\n field(\'subscript\', commaSep1(choice($.expression, $.slice))),\n optional(\',\'),\n \']\'\n )),\n\n slice: $ => seq(\n optional($.expression),\n \':\',\n optional($.expression),\n optional(seq(\':\', optional($.expression)))\n ),\n\n ellipsis: $ => \'...\',\n\n call: $ => prec(PREC.call, seq(\n field(\'function\', $.primary_expression),\n field(\'arguments\', choice(\n $.generator_expression,\n $.argument_list\n ))\n )),\n\n typed_parameter: $ => prec(PREC.typed_parameter, seq(\n choice(\n $.identifier,\n $.list_splat_pattern,\n $.dictionary_splat_pattern\n ),\n \':\',\n field(\'type\', $.type)\n )),\n\n type: $ => $.expression,\n\n keyword_argument: $ => seq(\n field(\'name\', choice($.identifier, $.keyword_identifier)),\n \'=\',\n field(\'value\', $.expression)\n ),\n\n // Literals\n\n list: $ => seq(\n \'[\',\n optional($._collection_elements),\n \']\'\n ),\n\n _comprehension_clauses: $ => seq(\n $.for_in_clause,\n repeat(choice(\n $.for_in_clause,\n $.if_clause\n ))\n ),\n\n list_comprehension: $ => seq(\n \'[\',\n field(\'body\', $.expression),\n $._comprehension_clauses,\n \']\'\n ),\n\n dictionary: $ => seq(\n \'{\',\n optional(commaSep1(choice($.pair, $.dictionary_splat))),\n optional(\',\'),\n \'}\'\n ),\n\n dictionary_comprehension: $ => seq(\n \'{\',\n field(\'body\', $.pair),\n $._comprehension_clauses,\n \'}\'\n ),\n\n pair: $ => seq(\n field(\'key\', $.expression),\n \':\',\n field(\'value\', $.expression)\n ),\n\n set: $ => seq(\n \'{\',\n commaSep1(choice($.expression, $.list_splat)),\n optional(\',\'),\n \'}\'\n ),\n\n set_comprehension: $ => seq(\n \'{\',\n field(\'body\', $.expression),\n $._comprehension_clauses,\n \'}\'\n ),\n\n parenthesized_expression: $ => prec(PREC.parenthesized_expression, seq(\n \'(\',\n choice($.expression, $.yield),\n \')\'\n )),\n\n _collection_elements: $ => seq(\n commaSep1(choice(\n $.expression, $.yield, $.list_splat, $.parenthesized_list_splat\n )),\n optional(\',\')\n ),\n\n tuple: $ => seq(\n \'(\',\n optional($._collection_elements),\n \')\'\n ),\n\n generator_expression: $ => seq(\n \'(\',\n field(\'body\', $.expression),\n $._comprehension_clauses,\n \')\'\n ),\n\n for_in_clause: $ => seq(\n optional(\'async\'),\n \'for\',\n field(\'left\', $.left_hand_side),\n \'in\',\n field(\'right\', commaSep1($._expression_within_for_in_clause)),\n optional(\',\')\n ),\n\n if_clause: $ => seq(\n \'if\',\n $.expression\n ),\n\n conditional_expression: $ => prec.right(PREC.conditional, seq(\n $.expression,\n \'if\',\n $.expression,\n \'else\',\n $.expression\n )),\n\n concatenated_string: $ => seq(\n $.string,\n repeat1($.string)\n ),\n\n string: $ => seq(\n alias($._string_start, \'\"\'),\n repeat(choice($.interpolation, $.escape_sequence, $._not_escape_sequence, $._string_content)),\n alias($._string_end, \'\"\')\n ),\n\n interpolation: $ => seq(\n \'{\',\n $.expression,\n optional($.type_conversion),\n optional($.format_specifier),\n \'}\'\n ),\n\n escape_sequence: $ => token(prec(1, seq(\n \'\\\\\',\n choice(\n /u[a-fA-F\\d]{4}/,\n /U[a-fA-F\\d]{8}/,\n /x[a-fA-F\\d]{2}/,\n /\\d{3}/,\n /\\r?\\n/,\n /[\'\"abfrntv\\\\]/,\n )\n ))),\n\n _not_escape_sequence: $ => \'\\\\\',\n\n format_specifier: $ => seq(\n \':\',\n repeat(choice(\n /[^{}\\n]+/,\n $.format_expression\n ))\n ),\n\n format_expression: $ => seq(\'{\', $.expression, \'}\'),\n\n type_conversion: $ => /![a-z]/,\n\n integer: $ => token(choice(\n seq(\n choice(\'0x\', \'0X\'),\n repeat1(/_?[A-Fa-f0-9]+/),\n optional(/[Ll]/)\n ),\n seq(\n choice(\'0o\', \'0O\'),\n repeat1(/_?[0-7]+/),\n optional(/[Ll]/)\n ),\n seq(\n choice(\'0b\', \'0B\'),\n repeat1(/_?[0-1]+/),\n optional(/[Ll]/)\n ),\n seq(\n repeat1(/[0-9]+_?/),\n choice(\n optional(/[Ll]/), // long numbers\n optional(/[jJ]/) // complex numbers\n )\n )\n )),\n\n float: $ => {\n const digits = repeat1(/[0-9]+_?/);\n const exponent = seq(/[eE][\\+-]?/, digits)\n\n return token(seq(\n choice(\n seq(digits, \'.\', optional(digits), optional(exponent)),\n seq(optional(digits), \'.\', digits, optional(exponent)),\n seq(digits, exponent)\n ),\n optional(choice(/[Ll]/, /[jJ]/))\n ))\n },\n\n identifier: $ => /[a-zA-Z\u{3b1}-\u{3c9}\u{391}-\u{3a9}_][a-zA-Z\u{3b1}-\u{3c9}\u{391}-\u{3a9}_0-9]*/,\n\n keyword_identifier: $ => alias(choice(\'print\', \'exec\'), $.identifier),\n\n true: $ => \'True\',\n false: $ => \'False\',\n none: $ => \'None\',\n\n await: $ => prec(PREC.unary, seq(\n \'await\',\n $.expression\n )),\n\n comment: $ => token(seq(\'#\', /.*/)),\n\n _semicolon: $ => \';\'\n }\n})\n\nfunction commaSep1 (rule) {\n return sep1(rule, \',\')\n}\n\nfunction sep1 (rule, separator) {\n return seq(rule, repeat(seq(separator, rule)))\n}\n";
The source of the Python tree-sitter grammar description.