2021-04-06 16:55:44 -04:00
|
|
|
module.exports = grammar({
|
2021-06-03 18:19:26 -04:00
|
|
|
name: "cmake",
|
2021-04-06 16:55:44 -04:00
|
|
|
|
|
|
|
rules: {
|
2021-06-07 18:02:13 -04:00
|
|
|
source_file: ($) => repeat($._command_invocation),
|
2021-04-06 17:38:23 -04:00
|
|
|
|
2021-06-03 18:19:26 -04:00
|
|
|
escape_sequence: ($) => choice($._escape_identity, $._escape_encoded, $._escape_semicolon),
|
|
|
|
_escape_identity: ($) => /\\[^A-Za-z0-9;]/,
|
|
|
|
_escape_encoded: ($) => choice("\\t", "\\r", "\\n"),
|
|
|
|
_escape_semicolon: ($) => ";",
|
2021-04-11 09:04:28 -04:00
|
|
|
|
2021-06-04 08:15:12 -04:00
|
|
|
variable: ($) => prec.left(repeat1(choice(/[a-zA-Z0-9/_.+-]/, $.escape_sequence))),
|
2021-06-03 18:19:26 -04:00
|
|
|
variable_ref: ($) => choice($.normal_var, $.env_var, $.cache_var),
|
|
|
|
normal_var: ($) => seq("${", $.variable, "}"),
|
2021-06-16 15:37:14 -04:00
|
|
|
env_var: ($) => seq("$ENV", "{", $.variable, "}"),
|
|
|
|
cache_var: ($) => seq("$CACHE", "{", $.variable, "}"),
|
2021-04-17 15:16:33 -04:00
|
|
|
|
2021-06-03 18:19:26 -04:00
|
|
|
argument: ($) => choice($.bracket_argument, $.quoted_argument, $.unquoted_argument),
|
2021-04-10 15:55:47 -04:00
|
|
|
|
2021-06-03 18:19:26 -04:00
|
|
|
bracket_argument: ($) => seq($._bracket_open, optional($.bracket_content), $._bracket_close),
|
2021-06-16 15:37:14 -04:00
|
|
|
_bracket_open: (_) => seq("[", repeat("="), "["),
|
|
|
|
bracket_content: (_) => repeat1(/[^\]]/),
|
|
|
|
_bracket_close: (_) => seq("]", repeat("="), "]"),
|
2021-04-10 15:55:47 -04:00
|
|
|
|
2021-06-03 18:19:26 -04:00
|
|
|
quoted_argument: ($) => seq('"', optional($.quoted_element), '"'),
|
2021-06-16 15:37:14 -04:00
|
|
|
quoted_element: ($) => repeat1(choice($.variable_ref, /[^\\"]/, $.escape_sequence, seq("\\", newline()))),
|
2021-04-11 11:27:20 -04:00
|
|
|
|
2021-06-03 18:19:26 -04:00
|
|
|
unquoted_argument: ($) => repeat1(choice($.variable_ref, /[^ ()#\"\\]/, $.escape_sequence)),
|
2021-04-11 09:48:26 -04:00
|
|
|
|
2021-06-16 15:37:14 -04:00
|
|
|
foreach_command: ($) => command($.foreach, args(choice($.argument, "IN", "RANGE", "ZIP_LISTS", "LISTS", "ITEMS"))),
|
|
|
|
endforeach_command: ($) => command($.endforeach, optional($.argument)),
|
|
|
|
foreach_loop: ($) => seq($.foreach_command, repeat($._command_invocation), $.endforeach_command),
|
|
|
|
normal_command: ($) => command($.identifier, optional(args($.argument))),
|
2021-04-07 18:17:56 -04:00
|
|
|
|
2021-06-07 18:07:49 -04:00
|
|
|
_command_invocation: ($) => choice($.normal_command, $.foreach_loop),
|
2021-06-16 15:37:14 -04:00
|
|
|
|
|
|
|
...commandNames("foreach", "endforeach"),
|
|
|
|
identifier: ($) => /[A-Za-z_][A-Za-z0-9_]*/,
|
|
|
|
integer: ($) => /[+-]*\d+/,
|
2021-06-03 18:19:26 -04:00
|
|
|
},
|
|
|
|
});
|
2021-06-07 17:02:35 -04:00
|
|
|
|
|
|
|
function iregex(s) {
|
2021-06-16 15:37:14 -04:00
|
|
|
return new RegExp(Array.from(s).reduce((acc, value) => acc + `[${value.toLowerCase()}${value.toUpperCase()}]`, ""));
|
2021-06-07 17:02:35 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
function commandName(name) {
|
2021-06-16 15:37:14 -04:00
|
|
|
return { [name]: (_) => iregex(name) };
|
2021-06-07 17:02:35 -04:00
|
|
|
}
|
|
|
|
|
2021-06-16 15:37:14 -04:00
|
|
|
function commandNames(...names) {
|
2021-06-07 17:02:35 -04:00
|
|
|
return Object.assign({}, ...names.map(commandName));
|
|
|
|
}
|
2021-06-14 16:07:04 -04:00
|
|
|
|
2021-06-16 15:37:14 -04:00
|
|
|
function args(rule) {
|
|
|
|
return seq(rule, repeat(prec.left(seq(repeat1(seperation()), optional(rule)))));
|
|
|
|
}
|
|
|
|
function command(name_rule, arg_rule) {
|
|
|
|
return seq(name_rule, "(", repeat(seperation()), arg_rule, ")");
|
|
|
|
}
|
|
|
|
function seperation() {
|
|
|
|
return choice(space(), newline());
|
|
|
|
}
|
|
|
|
function space() {
|
|
|
|
return /[ \t]+/;
|
|
|
|
}
|
|
|
|
function newline() {
|
|
|
|
return /\n+/;
|
2021-06-14 16:07:04 -04:00
|
|
|
}
|