[][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.