tree-sitter-cmake/grammar.js
2021-06-04 14:15:12 +02:00

98 lines
3.2 KiB
JavaScript

module.exports = grammar({
name: "cmake",
rules: {
source_file: ($) => repeat($.command_invocation),
line_ending: ($) => $.newline,
seperation: ($) => choice($.space, $.line_ending),
space: ($) => /[ \t]+/,
newline: ($) => /\n/,
identifier: ($) => /[A-Za-z_][A-Za-z0-9_]*/,
integer: ($) => /[+-]*\d+/,
escape_sequence: ($) => choice($._escape_identity, $._escape_encoded, $._escape_semicolon),
_escape_identity: ($) => /\\[^A-Za-z0-9;]/,
_escape_encoded: ($) => choice("\\t", "\\r", "\\n"),
_escape_semicolon: ($) => ";",
variable: ($) => prec.left(repeat1(choice(/[a-zA-Z0-9/_.+-]/, $.escape_sequence))),
variable_ref: ($) => choice($.normal_var, $.env_var, $.cache_var),
normal_var: ($) => seq("${", $.variable, "}"),
env_var: ($) => seq("$ENV{", $.variable, "}"),
cache_var: ($) => seq("$CACHE{", $.variable, "}"),
argument: ($) => choice($.bracket_argument, $.quoted_argument, $.unquoted_argument),
bracket_argument: ($) => seq($._bracket_open, optional($.bracket_content), $._bracket_close),
_bracket_open: ($) => seq("[", repeat("="), "["),
bracket_content: ($) => repeat1(/[^\]]/),
_bracket_close: ($) => seq("]", repeat("="), "]"),
quoted_argument: ($) => seq('"', optional($.quoted_element), '"'),
quoted_element: ($) =>
repeat1(choice($.variable_ref, /[^\\"]/, $.escape_sequence, seq("\\", $.newline))),
unquoted_argument: ($) => repeat1(choice($.variable_ref, /[^ ()#\"\\]/, $.escape_sequence)),
arguments: ($) => seq($.argument, repeat($._seperated_arguments)),
_seperated_arguments: ($) => prec.left(seq(repeat1($.seperation), optional($.argument))),
foreach_loop: ($) =>
seq(
repeat($.space),
"foreach",
repeat($.seperation),
"(",
repeat($.seperation),
choice($.foreach_items, $.foreach_range, $.foreach_lists_items, $.foreach_zip_lists),
")",
repeat($.command_invocation),
repeat($.space),
"endforeach",
repeat($.seperation),
"(",
optional($.variable),
")"
),
foreach_items: ($) =>
seq(field("loop_var", $.variable), repeat($.seperation), optional($.arguments)),
foreach_lists_items: ($) => seq("b"),
foreach_zip_lists: ($) => seq("c"),
foreach_range: ($) => choice($.foreach_range_stop, $.foreach_range_full),
foreach_range_stop: ($) =>
seq(
field("loop_var", $.variable),
repeat1($.seperation),
"RANGE",
repeat1($.seperation),
field("stop", $.integer)
),
foreach_range_full: ($) =>
seq(
field("loop_var", $.variable),
repeat1($.seperation),
"RANGE",
repeat1($.seperation),
field("start", $.integer),
repeat1($.seperation),
field("stop", $.integer),
optional(seq(repeat1($.seperation), field("step", $.integer)))
),
normal_command: ($) =>
seq(
repeat($.space),
$.identifier,
repeat($.space),
"(",
repeat($.seperation),
optional($.arguments),
")"
),
command_invocation: ($) => choice($.normal_command, $.foreach_loop),
},
});