111 lines
2.2 KiB
JavaScript
111 lines
2.2 KiB
JavaScript
|
const PREC = {
|
||
|
range: 15,
|
||
|
call: 14,
|
||
|
field: 13,
|
||
|
unary: 12,
|
||
|
cast: 11,
|
||
|
multiplicative: 10,
|
||
|
additive: 9,
|
||
|
shift: 8,
|
||
|
bitand: 7,
|
||
|
bitxor: 6,
|
||
|
bitor: 5,
|
||
|
comparative: 4,
|
||
|
and: 3,
|
||
|
or: 2,
|
||
|
assign: 0,
|
||
|
closure: -1,
|
||
|
};
|
||
|
|
||
|
module.exports = grammar({
|
||
|
name: "rhai",
|
||
|
|
||
|
externals: ($) => [
|
||
|
$._string_content,
|
||
|
$.raw_string_literal,
|
||
|
$.float_literal,
|
||
|
$.block_comment,
|
||
|
],
|
||
|
|
||
|
extras: (_) => [/\s/],
|
||
|
|
||
|
word: ($) => $.identifier,
|
||
|
|
||
|
inline: ($) => [$._declaration_statement],
|
||
|
|
||
|
supertypes: ($) => [
|
||
|
$._expression,
|
||
|
$._literal,
|
||
|
$._literal_pattern,
|
||
|
$._declaration_statement,
|
||
|
$._pattern,
|
||
|
],
|
||
|
|
||
|
rules: {
|
||
|
source_file: ($) => repeat($._statement),
|
||
|
|
||
|
// statements
|
||
|
|
||
|
_statement: ($) => choice($.expression_statement, $._declaration_statement),
|
||
|
|
||
|
expression_statement: ($) => choice(seq($._expression, ";")),
|
||
|
|
||
|
_declaration_statement: ($) => choice($.let_declaration),
|
||
|
|
||
|
let_declaration: ($) =>
|
||
|
seq(
|
||
|
"let",
|
||
|
field("pattern", $._pattern),
|
||
|
optional(seq("=", field("value", $._expression))),
|
||
|
";"
|
||
|
),
|
||
|
|
||
|
// patterns
|
||
|
|
||
|
_pattern: ($) => choice($._literal_pattern, $.identifier, "_"),
|
||
|
|
||
|
// expressions
|
||
|
|
||
|
_expression: ($) =>
|
||
|
choice($.assignment_expression, $._literal, prec.left($.identifier)),
|
||
|
|
||
|
assignment_expression: ($) =>
|
||
|
prec.left(
|
||
|
PREC.assign,
|
||
|
seq(field("left", $._expression), "=", field("right", $._expression))
|
||
|
),
|
||
|
|
||
|
// literals
|
||
|
_literal: ($) =>
|
||
|
choice($.string_literal, $.raw_string_literal, $.integer_literal),
|
||
|
|
||
|
_literal_pattern: ($) =>
|
||
|
choice($.string_literal, $.raw_string_literal, $.integer_literal),
|
||
|
|
||
|
integer_literal: (_) => token(seq(choice(/[0-9][0-9_]*/))),
|
||
|
|
||
|
string_literal: ($) => seq(
|
||
|
alias(/b?"/, '"'),
|
||
|
repeat(choice($.escape_sequence, $._string_content)),
|
||
|
token.immediate('"')
|
||
|
),
|
||
|
|
||
|
escape_sequence: (_) =>
|
||
|
token.immediate(
|
||
|
seq(
|
||
|
"\\",
|
||
|
choice(
|
||
|
/[^xu]/,
|
||
|
/u[0-9a-fA-F]{4}/,
|
||
|
/u{[0-9a-fA-F]+}/,
|
||
|
/x[0-9a-fA-F]{2}/
|
||
|
)
|
||
|
)
|
||
|
),
|
||
|
|
||
|
// identifiers
|
||
|
|
||
|
identifier: ($) => /(r#)?[_\p{XID_Start}][_\p{XID_Continue}]*/,
|
||
|
},
|
||
|
});
|