const kPrec = { kIdentifier: -1, // 标识符 kIf: 0, kElif: 1, kExprOperator: 1, // @ & kAssignment: 2, // := += -= /= *= ... kTernary: 3, // ?: kLogicalOr: 4, // or .|| kLogicalAnd: 5, // and .&& kBitwiseOr: 6, // .| kBitwiseXor: 7, // .^ kBitwiseAnd: 8, // .& kComparsion: 9, // = .= <> .<> > .> <= .<= >= .>= like in is kSet: 10, // union/2 intersect outersect minus kMatrixConcat: 10, // :| | kRange:10, // -> 数列初始化 kAddSub: 11, // + - kShift: 12, // shl rol shr ror kTimes: 13, // * / \ % mod div kMatrixTimes: 13, // :* :/ :\ kLogarithm: 14, // ~ kDerivative: 14, // ! 求导 kConcat: 14, // $ kSigned: 15, // ± kBitwiseNot: 16, // .! kLogicalNot: 16, // not .!! kMatrixInverse: 16, // ! 矩阵求逆 kMatrixTranspose: 16, // ` 矩阵转置 kFunctionPointer: 16, // ## 函数指针 kPrefix: 17, // ++ -- kMatrixPower: 17, // :^ kPower: 17, // ^ kPostfix: 18, // ++ -- kCall: 18, // func() kAttribute: 18, // obj.attr kSubscript: 18, // a[] a[:] a[1:] a[:1,2] kParenthesized: 19, // (expr) kArray: 20, } const kSemicolon = ';' module.exports = grammar({ name: 'tsf', word: $ => $.identifier, conflicts: $ => [ [$._left_hand_side, $.primary_expression], [$.tssql_select_expression, $._table_or_subquery], ], inline:$ => [ $._statement ], extras: $ => [ /\s/, $.line_comment, $.block_comment, $.nested_comment, ], rules: { root: $ => choice( $.unit, repeat($._statement) ), _statement: $ => choice( $._simple_statement, $._compound_statement ), _simple_statement: $ => choice( $.var_statement, $.static_statement, $.global_statement, $.const_statement, $.assignment_statement, $.expression_statement, $.uses_statement, $.break_statement, $.continue_statement, $.return_statement, $.inherited_statement, ), _compound_statement: $ => choice( $.if_statement, $.for_statement, $.while_statement, $.repeat_statement, $.case_statement, $.try_statement, $.anonymous_function_statement, $.function_declaration_statement, $.function_definition_statement, $.class_definition_statement, $.external_method_statement, $.matrix_iteration_statement, ), var_statement: $ => seq( $.var_declaration, kSemicolon ), static_statement: $ => seq( $.static_declaration, kSemicolon ), global_statement: $ => seq( $.global_declaration, kSemicolon ), const_statement: $ => seq( kw('const'), field('name', $.identifier), optional($._type_annotation), '=', field('value', $.expression), kSemicolon ), var_declaration: $ => seq( kw('var'), $._variable_declaration, optional($._type_annotation), ), static_declaration: $ => seq( kw('static'), $._variable_declaration, optional($._type_annotation), ), global_declaration: $ => seq( kw('global'), $._variable_declaration, optional($._type_annotation), ), _variable_declaration: $ => sep1(field('name', $.identifier), ','), _type_annotation: $ => seq( ':', $.type_specification ), type_specification: _ => field('type', /[_a-zA-Z][_a-zA-Z0-9 .]*/), assignment_statement: $ => choice( seq( choice( $.assignment_expression, $.augmented_assignment_expression, ), kSemicolon ), seq( field('left', $._left_hand_side), field('operator', ':='), field('right', $.anonymous_function_statement), ) ), break_statement: _ => seq(kw('break'), kSemicolon), continue_statement: _ => seq(kw('continue'), kSemicolon), return_statement: $ => seq(kw('return'), optional($.expression), kSemicolon), inherited_statement: $ => seq( $.inherited_expression, kSemicolon, ), _built_in_expression: $ => choice( $.echo_expression, $.raise_expression, $.new_expression, ), echo_expression: $ => prec.left(1, seq( kw('echo'), sep1($.expression, ','), )), raise_expression: $ => seq( kw('raise'), $.expression, ), inherited_expression: $ => seq( kw('inherited'), optional($.expression), ), new_expression: $ => seq( kw('new'), $.expression ), expression_statement: $ => seq( choice( $.expression, $.tssql_dml_expression, ), kSemicolon ), expression: $ => choice( $.operator_expression, $.tssql_select_expression, $.primary_expression, $._built_in_expression, ), operator_expression: $ => choice( $.expr_expression, $.ternary_expression, $.logical_or_expression, $.logical_and_expression, $.logical_not_expression, $.comparison_expression, $.bitwise_or_expression, $.bitwise_and_expression, $.bitwise_xor_expression, $.bitwise_not_expression, $.shift_expression, $.addition_expression, $.multiplication_expression, $.power_expression, $.logarithm_expression, $.matrix_multiplication_expression, $.matrix_power_expression, $.matrix_concatenation_expression, $.matrix_transpose_expression, $.range_expression, $.set_operation_expression, $.concatenation_expression, $.unary_plus_expression, $.unary_minus_expression, $.prefix_increment_expression, $.prefix_decrement_expression, $.postfix_increment_expression, $.postfix_decrement_expression, $.derivative_expression, $.function_pointer_expression, ), expr_expression: $ => prec.right(kPrec.kExprOperator, seq( field('operator', choice('@', '&')), field('argument', $.expression), )), assignment_expression: $ => prec.left(kPrec.kAssignment, seq( field('left', $._left_hand_side), field('operator', ':='), field('right', $._right_hand_side), )), augmented_assignment_expression: $ => prec.left(kPrec.kAssignment, seq( field('left', $._left_hand_side), field('operator', choice( '+=', '-=', '*=', '/=', '\\=', '^=', '~=', '%=', seq(kw('div'), '='), '|=', ':|=', '&=', ':*=', ':/=', ':\\=', ':^=', '::=', '.|=', '.&=', '.||=', '.&&=', '.^=', seq(kw('union'), '='), seq(kw('union2'), '='), seq(kw('intersect'), '='), seq(kw('outersect'), '='), seq(kw('minus'), '='), )), field('right', $._right_hand_side), )), _with_assignment_expression: $ => choice( $.expression, $.assignment_expression, $.augmented_assignment_expression, ), ternary_expression: $ => prec.left(kPrec.kTernary, seq( field('condition', $.expression), '?', optional(field('consequence', $._with_assignment_expression)), ':', field('alternative', $._with_assignment_expression) )), logical_or_expression: $ => prec.left(kPrec.kLogicalOr, seq( field('left', $.expression), field('operator', choice(kw('or'), '.||', '||')), field('right', $.expression), )), logical_and_expression: $ => prec.left(kPrec.kLogicalAnd, seq( field('left', $.expression), field('operator', choice(kw('and'), '.&&', '&&')), field('right', $.expression), )), logical_not_expression: $ => prec.left(kPrec.kLogicalNot, seq( field('operator', choice(kw('not'), '.!!')), field('argument', $.expression), )), comparison_expression: $ => prec.left(kPrec.kComparsion, seq( $.expression, repeat1(seq( field('operators', choice( '=', '<>', '>', '>=', '<', '<=', '.=', '.<>', '.>', '.>=', '.<', '.<=', $.in, kw('is'), kw('like') )), $.expression )), )), bitwise_or_expression: $ => prec.left(kPrec.kBitwiseOr, seq( field('left', $.expression), field('operator', '.|'), field('right', $.expression) )), bitwise_and_expression: $ => prec.left(kPrec.kBitwiseAnd, seq( field('left', $.expression), field('operator', '.&'), field('right', $.expression) )), bitwise_xor_expression: $ => prec.left(kPrec.kBitwiseXor, seq( field('left', $.expression), field('operator', '.^'), field('right', $.expression) )), bitwise_not_expression: $ => prec.left(kPrec.kBitwiseNot, seq( field('operator', '.!'), field('argument', $.expression) )), shift_expression: $ => prec.left(kPrec.kShift, seq( field('left', $.expression), field('operator', choice(kw('shl'), kw('rol'), kw('shr'), kw('ror'))), field('right', $.expression) )), addition_expression: $ => prec.left(kPrec.kAddSub, seq( field('left', $.expression), field('operator', choice('+', '-')), field('right', $.expression) )), multiplication_expression: $ => prec.left(kPrec.kTimes, seq( field('left', $.expression), field('operator', choice('*', '/', '\\', '%', kw('mod'), kw('div'))), field('right', $.expression) )), power_expression: $ => prec.right(kPrec.kPower, seq( field('left', $.expression), field('operator', '^'), field('right', $.expression) )), logarithm_expression: $ => prec.left(kPrec.kLogarithm, seq( field('left', $.expression), field('operator', '~'), field('right', $.expression) )), matrix_multiplication_expression: $ => prec.left(kPrec.kMatrixTimes, seq( field('left', $.expression), field('operator', choice(':*', ':/', ':\\')), field('right', $.expression) )), matrix_power_expression: $ => prec.right(kPrec.kMatrixPower, seq( field('left', $.expression), field('operator', ':^'), field('right', $.expression) )), matrix_concatenation_expression: $ => prec.left(kPrec.kMatrixConcat, seq( field('left', $.expression), field('operator', choice(':|', '|')), field('right', $.expression) )), range_expression: $ => prec.left(kPrec.kRange, seq( field('left', $.expression), field('operator', '->'), field('right', $.expression) )), matrix_transpose_expression: $ => prec(kPrec.kMatrixTranspose, seq( field('operator', '`'), field('argument', $.expression) )), set_operation_expression: $ => prec.left(kPrec.kSet, seq( field('left', $.expression), field('operator', choice( kw('union'), kw('union2'), kw('intersect'), kw('outersect'), kw('minus') )), field('right', $.expression) )), concatenation_expression: $ => prec.left(kPrec.kConcat, seq( field('left', $.expression), field('operator', '$'), field('right', $.expression), )), unary_plus_expression: $ => prec(kPrec.kSigned, seq( field('operator', '+'), field('argument', $.expression), )), unary_minus_expression: $ => prec(kPrec.kSigned, seq( field('operator', '-'), field('argument', $.expression), )), prefix_increment_expression: $ => prec.right(kPrec.kPrefix, seq( field('operator', '++'), field('argument', $.expression), )), prefix_decrement_expression: $ => prec.right(kPrec.kPrefix, seq( field('operator', '--'), field('argument', $.expression), )), postfix_increment_expression: $ => prec.right(kPrec.kPostfix, seq( field('argument', $.expression), field('operator', '++'), )), postfix_decrement_expression: $ => prec.right(kPrec.kPostfix, seq( field('argument', $.expression), field('operator', '--'), )), derivative_expression: $ => prec.left(kPrec.kDerivative, seq( field('operator', '!'), field('argument', $.expression), )), function_pointer_expression: $ => prec(kPrec.kFunctionPointer, seq( field('operator', '##'), field('argument', $.expression), )), anonymous_function_expression: $ => seq( kw('function'), $._parameter_signature, field('return_type', optional($._type_annotation)), optional(kSemicolon), field('body', $.block_statement) ), unpack_pattern: $ => prec.dynamic(1, seq( '[', $._unpack_vars, ']' )), _unpack_vars: $ => seq( field('variable', $.identifier), repeat1(seq(',', field('variable', $.identifier))), ), _left_hand_side: $ => choice( $._assignable_identifier, $.var_declaration, $.static_declaration, $.global_declaration, $.attribute, $.subscript, $.unpack_pattern, ), _right_hand_side: $ => choice( $.expression, $.assignment_expression, $.augmented_assignment_expression, ), tssql_select_expression: $ => choice( $.select_expression, $.sselect_expression, $.vselect_expression, $.mselect_expression, ), tssql_dml_expression: $ => choice( $.update_expression, $.delete_expression, $.insert_expression, ), select_expression: $ => seq( kw('select'), $._select_clause, ), sselect_expression: $ => seq( kw('sselect'), $._select_clause, ), vselect_expression: $ => seq( kw('vselect'), $._select_clause, ), mselect_expression: $ => seq( kw('mselect'), $._select_clause, ), update_expression: $ => seq( kw('update'), field('table', $.identifier), kw('set'), field('assignments', sep1($.update_assignment, ',')), optional(field('where', $.where_clause)), kw('end'), ), delete_expression: $ => seq( kw('delete'), kw('from'), field('table', $.identifier), optional(field('where', $.where_clause)), ), insert_expression: $ => seq( kw('insert'), kw('into'), field('table', $.identifier), optional($.insert_fields), choice( $.values_clause, field('source', $.identifier) ), ), insert_fields: $ => seq( kw('insertfields'), '(', sep1($.sql_field, ','), ')' ), values_clause: $ => seq( kw('values'), '(', sep1($.expression, ','), ')' ), update_assignment: $ => seq( field('column', $.primary_expression), '=', field('value', $.expression) ), _select_clause: $ => seq( optional(field('distinct', kw('distinct'))), optional(field('drange', $.drange_clause)), optional(field('columns', $.select_list)), field('from', $.from_clause), optional(field('where', $.where_clause)), optional(field('group_by', $.group_by_clause)), optional(field('order_by', $.order_by_clause)), optional(field('having', $.having_clause)), kw('end') ), drange_clause: $ => seq( kw('drange'), '(', choice( $.drange_to, $.drange_of, ), ')' ), drange_to: $ => seq( field('start', $.expression), kw('to'), field('end', $.expression) ), drange_of: $ => seq( field('part', $.expression), kw('of'), field('total', $.expression) ), select_list: $ => seq( $.select_list_item, repeat(seq(',', $.select_list_item)) ), select_list_item: $ => choice( prec(10, '*'), $.select_item ), select_item: $ => seq( field('expression', $.expression), optional($.alias_clause) ), alias_clause: $ => seq( kw('as'), choice( field('alias', $.string), $.nil, ) ), from_clause: $ => seq( kw('from'), $.from_item, ), from_item: $ => choice( $._table_or_subquery, $.join_clause, ), _table_or_subquery: $ => choice( $.expression, seq('(', $.select_expression, ')') ), table_name: $ => $.identifier, sql_field: $ => choice( $._sql_field_with_table, // ⚠️ 带表前缀的字段:[1].* 或 [1].["field"] $._sql_field_simple, // ⚠️ 简单字段:["field"] ), _sql_field_with_table: $ => prec(kPrec.kSubscript + 3, seq( '[', field('table_index', $.number), ']', '.', choice( '*', seq('[', field('field_name', choice($.string, $.number)), ']') ) )), // ⚠️ 简单的 SQL 字段或参数引用 _sql_field_simple: $ => prec(kPrec.kSubscript + 2, seq( '[', field('ref', choice($.string, $.number)), ']' )), where_clause: $ => seq( kw('where'), field('condition', $.expression) ), group_by_clause: $ => seq( kw('group'), kw('by'), field('expressions', sep1($.expression, ',')) ), order_by_clause: $ => seq( kw('order'), kw('by'), field('expressions', sep1($._order_by_item, ',')) ), _order_by_item: $ => seq( field('expression', $.expression), optional(field('direction', choice(kw('asc'), kw('desc')))) ), having_clause: $ => seq( kw('having'), field('condition', $.expression) ), join_clause: $ => prec.left(1, seq( $._table_or_subquery, repeat1($._join_part) )), _join_part: $ => seq( field('join_type', $.join_type), field('right', $._table_or_subquery), optional(field('condition', choice( $.on_condition, $.with_condition ))) ), join_type: _ => choice( kw('join'), seq(kw('left'), kw('join')), seq(kw('right'), kw('join')), seq(kw('full'), kw('join')), seq(kw('cross'), kw('join')), ',' // comma join ), on_condition: $ => seq( kw('on'), field('condition', $.expression) ), with_condition: $ => seq( kw('with'), '(', field('left_fields', sep1($.sql_field, ',')), kw('on'), field('right_fields', sep1($.sql_field, ',')), ')' ), primary_expression: $ => choice( $.attribute, $.subscript, $.parenthesized_expression, $.call, $.array, $._literal, $._assignable_identifier, $._reserved_keyword, $.sql_field, ), // identifier: _ => /[a-zA-Z_][a-zA-Z0-9_]*/, identifier: _ => token(prec(kPrec.kIdentifier, /[a-zA-Z_][a-zA-Z0-9_]*/)), _literal: $ => choice( $.number, $.string, $.boolean, $.nil, $.infinity, $.ellipsis ), _assignable_identifier: $ => choice( $.identifier, $.type, $.do, ), _reserved_keyword: $ => choice( $.class, $.in ), type: _ => kw('type'), class: _ => kw('class'), in: _ => kw('in'), do: _ => kw('do'), number: _ => token(choice( /0[xX][0-9a-fA-F]+/, /0[bB][01]+/, /0[oO][0-7]+/, /[+-]?\d+\.\d*(?:[eE][+-]?\d+)?/, // 123.456, 123., +123. /[+-]?\.\d+(?:[eE][+-]?\d+)?/, // .456, +.456 /[+-]?\d+(?:[eE][+-]?\d+)?/, // 123, +123, 123e10 )), string: _ => token(choice( seq( '"', repeat(choice( /[^"\\]/, seq('\\', /./), // escape sequence )), '"' ), seq( "'", repeat(choice( /[^'\\]/, seq('\\', /./), // escape sequence )), "'" ) )), escape_sequence: _ => token(seq('\\', /./)), boolean: $ => choice( $.true, $.false, ), true: _ => kw('true'), false: _ => kw('false'), nil: _ => kw('nil'), infinity: $ => choice( $.minus_inf, $.plus_inf, ), minus_inf: _ => kw('-inf'), plus_inf: _ => kw('+inf'), ellipsis: _ => '...', call: $ => prec(kPrec.kCall, seq( field('function', $.primary_expression), '(', field('arguments', optional($.argument_list)), ')' )), attribute: $ => prec(kPrec.kAttribute, seq( field('object', choice($.primary_expression)), '.', field('attribute', $.identifier), )), subscript: $ => prec.dynamic(2, prec(kPrec.kSubscript, seq( field('value', $.primary_expression), '[', field('subscript', $._index_spec), ']', ))), parenthesized_expression: $ => seq('(', $._with_assignment_expression, ')'), array: $ => prec(kPrec.kArray, seq( kw('array'), '(', optional($._array_elements), ')' )), argument_list: $ => sep1($.argument, ','), argument: $ => choice( $.expression, seq( field('name', $.identifier), ':', field('value', $.expression), ), '*' ), _index_spec: $ => choice( $._multi_index, $._single_index, ), _multi_index: $ => seq( $._index_item, repeat1(seq(',', $._index_item)) ), _single_index: $ => $._index_item, _index_item: $ => choice( $.expression, // string, array都在里面 $.slice, $.empty_slice, ), empty_slice: _ => ':', slice: $ => choice( $.range_slice, $.start_slice, $.end_slice, $.step_slice, ), range_slice: $ => seq($.expression, ':', $.expression), start_slice: $ => seq($.expression, ':'), end_slice: $ => seq(':', $.expression), step_slice: $ => seq($.expression, ':', $.expression, ':', $.expression), _array_elements: $ => seq( sep1($.array_element, ','), optional(',') ), array_element: $ => choice( $.key_value_pair, prec(1, $.parenthesized_array), $.expression ), key_value_pair: $ => seq( field('key', $.expression), ':', field('value', choice( $.expression, $.parenthesized_array )) ), parenthesized_array: $ => prec(1, seq( '(', choice( seq($.key_value_pair, ',', sep1($.key_value_pair, ',')), $.key_value_pair, seq($.expression, ',', sep1($.expression, ',')), $.expression ), optional(','), ')' )), line_comment: _ => token(seq('//', /.*/)), block_comment:_ => token(seq( '{', /([^$}][^}]*)?/, '}' )), nested_comment: _ => token(/[(][*]([^*]*[*]+[^)*])*[^*]*[*]+[)]/), if_statement: $ => prec.right(kPrec.kIf, seq( $.if_clause, repeat(field('alternative', $.else_if_clause)), optional(field('alternative', $.else_clause)) )), if_clause: $ => seq( kw('if'), field('condition', $._with_assignment_expression), kw('then'), field('consequence', $._statement_suite) ), else_if_clause: $ => prec(kPrec.kElif, seq( kw('else'), kw('if'), field('condition', $._with_assignment_expression), kw('then'), field('consequence', $._statement_suite) )), else_clause: $ => seq( kw('else'), field('consequence', $._statement_suite) ), _statement_suite: $ => choice( seq($.block_statement, optional(kSemicolon)), $.single_suite, ), single_suite: $ => $._statement, block_statement: $ => seq( kw('begin'), repeat($._statement), kw('end'), ), for_statement: $ => choice( $.for_in_statement, $.for_to_statement, ), for_in_statement: $ => seq( kw('for'), field('key', $.identifier), ',', field('value', $.identifier), kw('in'), field('collection', $.expression), $.do, field('body', $._statement_suite) ), for_to_statement: $ => seq( kw('for'), field('counter', $.identifier), ':=', field('start', $.expression), field('direction', choice(kw('to'), kw('downto'))), field('end', $.expression), $.do, field('body', $._statement_suite) ), while_statement: $ => seq( kw('while'), field('condition', $.expression), $.do, field('body', $._statement_suite) ), repeat_statement: $ => seq( kw('repeat'), field('body', repeat($.single_suite)), kw('until'), field('condition', $.expression), kSemicolon, ), case_statement: $ => seq( kw('case'), field('discriminant', $.expression), // 被匹配的表达式 kw('of'), field('branches', repeat($.case_branch)), field('default', optional($.case_else)), kw('end'), optional(kSemicolon), ), case_branch: $ => seq( field('values', $.case_values), ':', field('consequence', $._statement_suite) ), case_values: $ => sep1( field('value', $.expression), ',' ), case_else: $ => seq( kw('else'), field('consequence', $._statement_suite) ), try_statement: $ => seq( kw('try'), optional(field('body', repeat1($._statement))), kw('except'), optional(field('body', repeat1($._statement))), kw('end'), optional(kSemicolon) ), anonymous_function_statement: $ => seq( $.anonymous_function_expression, optional(kSemicolon), ), function_declaration_statement: $ => seq( kw('function'), field('name', $.identifier), $._parameter_signature, optional(field('return_type', $._type_annotation)), kSemicolon ), function_definition_statement: $ => seq( kw('function'), field('name', $.identifier), $._parameter_signature, field('return_type', optional($._type_annotation)), optional(kSemicolon), field('body', $.block_statement), optional(kSemicolon), ), _parameter_signature: $ => seq( '(', optional(field('parameters', $.parameter_list)), ')', ), parameter_list: $ => sep1($.parameter, kSemicolon), parameter: $ => seq( optional( choice( field('var', kw('var')), field('out', kw('out')), ) ), field('names', sep1($.identifier, ',')), optional(field('type', $._type_annotation)), optional(seq('=', field('default', $.expression))) ), class_definition_statement: $ => seq( $.type, field('name', $.identifier), '=', $.class, optional($._parent_list), optional(field('body', $.class_body)), kw('end'), optional(kSemicolon) ), _parent_list: $ => seq( '(', optional(field('parents', sep1(choice($.identifier, $.attribute), ','))), ')', ), class_body: $ => repeat1($.class_member), class_member: $ => choice( field('access_modifier', $.access_modifier), choice( $.variable_declaration, $.method_declaration, $.property_declaration, ), $.uses_statement, ), access_modifier: _ => choice( kw('public'), kw('protected'), kw('private') ), variable_declaration: $ => seq( optional($._reference_tag), field('variables', $.member_variable), kSemicolon, ), _reference_tag: $ => seq( '[', field('ref_modifier', $.reference_modifier), ']' ), reference_modifier: _ => choice( kw('weakref'), kw('autoref') ), member_variable: $ => choice( $.static_declaration, $.nostatic_declaration, ), nostatic_declaration: $ => seq( $._variable_declaration, optional($._type_annotation), ), method_declaration: $ => choice( $.method_declaration_only, $.method_with_modifier, $.method_with_implementation, ), method_declaration_only: $ => seq( optional($.class), kw('function'), field('name', $.method_name), $._parameter_signature, optional(field('return_type', $._type_annotation)), kSemicolon ), method_with_modifier: $ => seq( kw('function'), field('name', $.method_name), $._parameter_signature, optional(field('return_type', $._type_annotation)), kSemicolon, field('modifier', $.method_modifier), kSemicolon, optional(seq(field('body', $.block_statement), optional(kSemicolon))), ), method_with_implementation: $ => seq( optional($.class), kw('function'), field('name', $.method_name), $._parameter_signature, optional(field('return_type', $._type_annotation)), optional(kSemicolon), field('body', $.block_statement), optional(kSemicolon), ), method_name: $ => choice( $._assignable_identifier, // $.identifier, $.operator_overload, ), operator_overload: $ => seq( kw('operator'), field('operator', $._overloadable_operator) ), _overloadable_operator: _ => choice( '+', '-', '*', '/', '\\', '[]', ), method_modifier: _ => choice( kw('virtual'), kw('override'), kw('overload') ), property_declaration : $ => seq( kw('property'), field('name', $.identifier), optional($._type_annotation), optional($._property_index), field('accessors', $.property_accessors), kSemicolon, ), _property_index: $ => seq( kw('index'), choice( $.number, $.string ) ), property_accessors: $ => choice( $.read_only_accessor, $.write_only_accessor, $.read_write_accessor, $.write_read_accessor, ), read_only_accessor: $ => seq( kw('read'), $.identifier ), write_only_accessor: $ => seq( kw('write'), $.identifier ), read_write_accessor: $ => seq( kw('read'), $.identifier, kw('write'), $.identifier ), write_read_accessor: $ => seq( kw('write'), $.identifier, kw('read'), $.identifier ), // 类外方法实现 external_method_statement: $ => choice( $.modifier_method, $.operator_method, $.normal_method, ), matrix_iteration_statement: $ => seq( field('target', $.expression), '::', field('body', $.block_statement), optional(kSemicolon) ), modifier_method: $ => seq( kw('function'), $._qualified_method_name, $._parameter_signature, optional(field('return_type', $._type_annotation)), kSemicolon, field('modifier', $.method_modifier), kSemicolon, field('body', $.block_statement), optional(kSemicolon), ), operator_method: $ => choice( $._operator_method, $._operator_method_with_modifier, ), normal_method: $ => seq( optional($.class), kw('function'), $._qualified_method_name, $._parameter_signature, optional(field('return_type', $._type_annotation)), optional(kSemicolon), field('body', $.block_statement), optional(kSemicolon), ), _operator_method: $ => seq( kw('function'), kw('operator'), field('class_name', $.identifier), '.', field('operator', $._overloadable_operator), $._parameter_signature, optional(field('return_type', $._type_annotation)), optional(kSemicolon), field('body', $.block_statement), optional(kSemicolon), ), _operator_method_with_modifier: $ => seq( kw('function'), kw('operator'), field('class_name', $.identifier), '.', field('operator', $._overloadable_operator), $._parameter_signature, optional(field('return_type', $._type_annotation)), kSemicolon, field('modifier', $.method_modifier), kSemicolon, field('body', $.block_statement), optional(kSemicolon), ), _qualified_method_name: $ => seq( field('class_name', $.identifier), '.', field('method_name', $.identifier), ), // unit unit: $ => seq( kw('unit'), field('name', $.identifier), kSemicolon, field('interface', $.interface_section), field('implementation', $.implementation_section), optional(field('initialization', $.initialization_section)), optional(field('finalization', $.finalization_section)), kw('end'), '.' ), interface_section: $ => seq( kw('interface'), optional(repeat($._statement)), ), implementation_section: $ => seq( kw('implementation'), optional(repeat($._statement)), ), initialization_section: $ => seq( kw('initialization'), optional(repeat($._statement)), ), finalization_section: $ => seq( kw('finalization'), optional(repeat($._statement)), ), uses_statement: $ => seq( kw('uses'), field('modules', sep1($.identifier, ',')), kSemicolon ), } }); // 辅助函数:用分隔符分隔的序列 function sep1(rule, separator) { return seq(rule, repeat(seq(separator, rule))) } function kw(keyword) { const escapedKeyword = keyword.replace(/[.*+?^${}()|[\]\\-]/g, '\\$&'); return alias( new RustRegex(`(?i)${escapedKeyword}`), keyword.toLowerCase() ) }