tree-sitter-cmake/grammar.js

176 lines
4.7 KiB
JavaScript
Raw Normal View History

2021-06-17 17:06:32 -04:00
commands = [
"if",
"elseif",
"else",
"endif",
"foreach",
"endforeach",
"while",
"endwhile",
"function",
"endfunction",
"macro",
"endmacro",
"message",
];
2021-06-17 16:32:18 -04:00
if_args = [
"1",
"ON",
"YES",
"TRUE",
"Y",
"0",
"OFF",
"NO",
"FALSE",
"N",
"IGNORE",
"NOTFOUND",
"NOT",
"AND",
"OR",
"COMMAND",
"POLICY",
"TARGET",
"TEST",
"DEFINED",
"CACHE",
"ENV",
"IN_LIST",
"EXISTS",
"IS_NEWER_THAN",
"IS_DIRECTORY",
"IS_SYMLINK",
"IS_ABSOLUTE",
"MATCHES",
"LESS",
"GREATER",
"EQUAL",
"LESS_EQUAL",
"GREATER_EQUAL",
"STRLESS",
"STRGREATER",
"STREQUAL",
"STRLESS_EQUAL",
"STRGREATER_EQUAL",
"VERSION_LESS",
"VERSION_GREATER",
"VERSION_EQUAL",
"VERSION_LESS_EQUAL",
"VERSION_GREATER_EQUAL",
];
foreach_args = ["IN", "RANGE", "ZIP_LISTS", "LISTS", "ITEMS"];
2021-06-17 17:06:32 -04:00
message_args = [
"FATAL_ERROR",
"SEND_ERROR",
"WARNING",
"AUTHOR_WARNING",
"DEPRECATION",
"NOTICE",
"STATUS",
"VERBOSE",
"DEBUG",
"TRACE",
"CHECK_START",
"CHECK_PASS",
"CHECK_FAIL",
];
2021-04-06 16:55:44 -04:00
module.exports = grammar({
name: "cmake",
2021-04-06 16:55:44 -04:00
externals: ($) => [$.bracket_argument],
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
escape_sequence: ($) => choice($._escape_identity, $._escape_encoded, $._escape_semicolon),
2021-06-17 16:32:18 -04:00
_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, "}"),
2021-06-16 15:37:14 -04:00
env_var: ($) => seq("$ENV", "{", $.variable, "}"),
cache_var: ($) => seq("$CACHE", "{", $.variable, "}"),
argument: ($) => choice($.bracket_argument, $.quoted_argument, $.unquoted_argument),
2021-04-10 15:55:47 -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
unquoted_argument: ($) => repeat1(choice($.variable_ref, /[^ ()#\"\\]/, $.escape_sequence)),
2021-04-11 09:48:26 -04:00
2021-06-17 16:32:18 -04:00
if_command: ($) => command($.if, args(choice($.argument, ...if_args))),
elseif_command: ($) => command($.elseif, args(choice($.argument, ...if_args))),
2021-06-17 16:43:12 -04:00
else_command: ($) => command($.else, optional(choice($.argument, ...if_args))),
endif_command: ($) => command($.endif, optional(choice($.argument, ...if_args))),
2021-06-17 16:33:05 -04:00
if_condition: ($) =>
seq($.if_command, repeat(choice($._command_invocation, $.elseif_command, $.else_command)), $.endif_command),
2021-06-17 16:32:18 -04:00
foreach_command: ($) => command($.foreach, args(choice($.argument, ...foreach_args))),
2021-06-16 15:37:14 -04:00
endforeach_command: ($) => command($.endforeach, optional($.argument)),
2021-06-17 16:32:18 -04:00
foreach_loop: ($) => seq($.foreach_command, repeat($._command_invocation), $.endforeach_command),
2021-06-17 16:33:05 -04:00
2021-06-17 16:43:12 -04:00
while_command: ($) => command($.while, args(choice($.argument, ...if_args))),
endwhile_command: ($) => command($.endwhile, optional(choice($.argument, ...if_args))),
while_loop: ($) => seq($.while_command, repeat($._command_invocation), $.endwhile_command),
2021-06-17 17:06:32 -04:00
function_command: ($) => command($.function, args($.argument)),
endfunction_command: ($) => command($.endfunction, args($.argument)),
function_def: ($) => seq($.function_command, repeat($._command_invocation), $.endfunction_command),
2021-06-17 16:32:18 -04:00
2021-06-17 17:06:32 -04:00
macro_command: ($) => command($.macro, args($.argument)),
endmacro_command: ($) => command($.endmacro, args($.argument)),
macro_def: ($) => seq($.macro_command, repeat($._command_invocation), $.endmacro_command),
message_command: ($) => command($.message, optional(args(choice($.argument, ...message_args)))),
normal_command: ($) => command($.identifier, optional(args($.argument))),
2021-06-16 15:37:14 -04:00
2021-06-17 17:06:32 -04:00
_command_invocation: ($) =>
choice(
$.normal_command,
$.if_condition,
$.foreach_loop,
$.while_loop,
$.function_def,
$.macro_def,
$.message_command
),
...commandNames(...commands),
2021-06-17 16:32:18 -04:00
identifier: (_) => /[A-Za-z_][A-Za-z0-9_]*/,
integer: (_) => /[+-]*\d+/,
},
});
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-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+/;
}