2021-06-17 17:06:32 -04:00
|
|
|
commands = [
|
|
|
|
"if",
|
|
|
|
"elseif",
|
|
|
|
"else",
|
|
|
|
"endif",
|
|
|
|
"foreach",
|
|
|
|
"endforeach",
|
|
|
|
"while",
|
|
|
|
"endwhile",
|
|
|
|
"function",
|
|
|
|
"endfunction",
|
|
|
|
"macro",
|
|
|
|
"endmacro",
|
2022-12-03 07:09:00 -05:00
|
|
|
"block",
|
2023-06-28 09:14:23 -04:00
|
|
|
"endblock",
|
2021-06-17 17:06:32 -04:00
|
|
|
];
|
|
|
|
|
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
|
|
|
|
2021-06-27 07:14:31 -04:00
|
|
|
externals: ($) => [$.bracket_argument, $.bracket_comment, $.line_comment],
|
2021-06-30 15:17:16 -04:00
|
|
|
extras: (_) => [],
|
2021-06-25 20:18:08 -04:00
|
|
|
|
2021-04-06 16:55:44 -04:00
|
|
|
rules: {
|
2021-06-29 14:35:34 -04:00
|
|
|
source_file: ($) => repeat($._untrimmed_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),
|
2021-06-17 16:32:18 -04:00
|
|
|
_escape_identity: (_) => /\\[^A-Za-z0-9;]/,
|
|
|
|
_escape_encoded: (_) => choice("\\t", "\\r", "\\n"),
|
2023-06-28 09:14:23 -04:00
|
|
|
_escape_semicolon: (_) => choice(";", "\\;"),
|
2021-04-11 09:04:28 -04:00
|
|
|
|
2021-06-30 01:40:33 -04:00
|
|
|
variable: ($) => prec.left(repeat1(choice(/[a-zA-Z0-9/_.+-]/, $.escape_sequence, $.variable_ref))),
|
2021-06-03 18:19:26 -04:00
|
|
|
variable_ref: ($) => choice($.normal_var, $.env_var, $.cache_var),
|
2021-06-30 14:39:02 -04:00
|
|
|
normal_var: ($) => seq("$", "{", $.variable, "}"),
|
|
|
|
env_var: ($) => seq("$", "ENV", "{", $.variable, "}"),
|
|
|
|
cache_var: ($) => seq("$", "CACHE", "{", $.variable, "}"),
|
2021-04-17 15:16:33 -04:00
|
|
|
|
2021-07-06 12:46:05 -04:00
|
|
|
gen_exp: ($) => seq("$", "<", optional($._gen_exp_content), ">"),
|
|
|
|
_gen_exp_content: ($) => seq($.argument, optional($._gen_exp_arguments)),
|
|
|
|
_gen_exp_arguments: ($) => seq(":", repeat(seq($.argument, optional(/[,;]/)))),
|
|
|
|
|
2021-06-03 18:19:26 -04:00
|
|
|
argument: ($) => choice($.bracket_argument, $.quoted_argument, $.unquoted_argument),
|
2021-07-01 07:36:35 -04:00
|
|
|
_untrimmed_argument: ($) => choice(/\s/, $.bracket_comment, $.line_comment, $.argument, $._paren_argument),
|
2021-07-01 11:02:13 -04:00
|
|
|
_paren_argument: ($) => seq("(", repeat($._untrimmed_argument), ")"),
|
2021-04-10 15:55:47 -04:00
|
|
|
|
2021-06-03 18:19:26 -04:00
|
|
|
quoted_argument: ($) => seq('"', optional($.quoted_element), '"'),
|
2022-01-26 13:41:41 -05:00
|
|
|
quoted_element: ($) => repeat1(choice($.variable_ref, $.gen_exp, $._quoted_text, $.escape_sequence)),
|
2023-06-28 09:14:23 -04:00
|
|
|
_quoted_text: (_) => prec.left(repeat1(choice("$", /[^\\"]/))),
|
2021-04-11 11:27:20 -04:00
|
|
|
|
2023-06-28 09:14:23 -04:00
|
|
|
unquoted_argument: ($) =>
|
|
|
|
prec.right(repeat1(choice($.variable_ref, $.gen_exp, $._unquoted_text, $.escape_sequence))),
|
|
|
|
_unquoted_text: (_) => prec.left(repeat1(choice("$", /[^()#"\\']/))),
|
|
|
|
|
|
|
|
body: ($) => prec.right(repeat1($._untrimmed_command_invocation)),
|
2023-06-28 10:33:56 -04:00
|
|
|
argument_list: ($) => repeat1($._untrimmed_argument),
|
2021-04-11 09:48:26 -04:00
|
|
|
|
2023-06-28 10:33:56 -04:00
|
|
|
if_command: ($) => command($.if, $.argument_list),
|
|
|
|
elseif_command: ($) => command($.elseif, $.argument_list),
|
|
|
|
else_command: ($) => command($.else, optional($.argument_list)),
|
|
|
|
endif_command: ($) => command($.endif, optional($.argument_list)),
|
2023-06-28 09:14:23 -04:00
|
|
|
if_condition: ($) => seq($.if_command, repeat(choice($.body, $.elseif_command, $.else_command)), $.endif_command),
|
2021-06-17 16:33:05 -04:00
|
|
|
|
2023-06-28 10:33:56 -04:00
|
|
|
foreach_command: ($) => command($.foreach, $.argument_list),
|
2021-06-16 15:37:14 -04:00
|
|
|
endforeach_command: ($) => command($.endforeach, optional($.argument)),
|
2023-06-28 09:14:23 -04:00
|
|
|
foreach_loop: ($) => seq($.foreach_command, $.body, $.endforeach_command),
|
2021-06-17 16:33:05 -04:00
|
|
|
|
2023-06-28 10:33:56 -04:00
|
|
|
while_command: ($) => command($.while, $.argument_list),
|
2021-06-29 14:35:34 -04:00
|
|
|
endwhile_command: ($) => command($.endwhile, optional(seq(/\s*/, $.argument, /\s*/))),
|
2023-06-28 09:14:23 -04:00
|
|
|
while_loop: ($) => seq($.while_command, $.body, $.endwhile_command),
|
2021-06-17 16:43:12 -04:00
|
|
|
|
2023-06-28 10:33:56 -04:00
|
|
|
function_command: ($) => command($.function, $.argument_list),
|
|
|
|
endfunction_command: ($) => command($.endfunction, optional($.argument_list)),
|
2023-06-28 09:14:23 -04:00
|
|
|
function_def: ($) => seq($.function_command, $.body, $.endfunction_command),
|
2021-06-17 16:32:18 -04:00
|
|
|
|
2023-06-28 10:33:56 -04:00
|
|
|
macro_command: ($) => command($.macro, $.argument_list),
|
|
|
|
endmacro_command: ($) => command($.endmacro, optional($.argument_list)),
|
2023-06-28 09:14:23 -04:00
|
|
|
macro_def: ($) => seq($.macro_command, $.body, $.endmacro_command),
|
2021-06-17 17:06:32 -04:00
|
|
|
|
2023-06-28 10:33:56 -04:00
|
|
|
block_command: ($) => command($.block, $.argument_list),
|
|
|
|
endblock_command: ($) => command($.endblock, optional($.argument_list)),
|
2023-06-28 09:14:23 -04:00
|
|
|
block_def: ($) => seq($.block_command, $.body, $.endblock_command),
|
2022-12-03 07:09:00 -05:00
|
|
|
|
2023-06-28 10:33:56 -04:00
|
|
|
normal_command: ($) => command($.identifier, optional($.argument_list)),
|
2021-06-16 15:37:14 -04:00
|
|
|
|
2021-06-17 17:06:32 -04:00
|
|
|
_command_invocation: ($) =>
|
2022-12-03 07:09:00 -05:00
|
|
|
choice($.normal_command, $.if_condition, $.foreach_loop, $.while_loop, $.function_def, $.macro_def, $.block_def),
|
2021-06-30 15:17:16 -04:00
|
|
|
_untrimmed_command_invocation: ($) => choice(/\s/, $.bracket_comment, $.line_comment, $._command_invocation),
|
2021-06-17 17:06:32 -04:00
|
|
|
|
|
|
|
...commandNames(...commands),
|
2021-06-17 16:32:18 -04:00
|
|
|
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 command(name_rule, arg_rule) {
|
2021-06-29 14:35:34 -04:00
|
|
|
return seq(name_rule, repeat(/[\t ]/), "(", arg_rule, ")");
|
2021-06-14 16:07:04 -04:00
|
|
|
}
|