grammar update
This commit is contained in:
parent
21c10090b3
commit
23d8221303
2 changed files with 612 additions and 641 deletions
|
|
@ -9,7 +9,7 @@
|
|||
// @ts-check
|
||||
|
||||
const SPECIAL_CHARACTERS = [
|
||||
"|", "&", ";", "<", ">", "(", ")", "$", "`", "\\", "\"", "'", " ", "\t", "\n",
|
||||
'|', '&', ';', '<', '>', '(', ')', '$', '`', '\\', '\"', '\'', ' ', '\t', '\n',
|
||||
]
|
||||
|
||||
const PREC = {
|
||||
|
|
@ -35,7 +35,7 @@ const PREC = {
|
|||
};
|
||||
|
||||
module.exports = grammar({
|
||||
name: 'bash',
|
||||
name: 'sh',
|
||||
|
||||
conflicts: $ => [
|
||||
[$.command, $.variable_assignments],
|
||||
|
|
@ -106,10 +106,7 @@ module.exports = grammar({
|
|||
optional($._terminator),
|
||||
)),
|
||||
|
||||
_terminated_statement: $ => repeat1(seq(
|
||||
$._statement,
|
||||
$._terminator,
|
||||
)),
|
||||
_terminated_statement: $ => repeat1(seq($._statement, $._terminator)),
|
||||
|
||||
// Statements
|
||||
|
||||
|
|
@ -119,39 +116,35 @@ module.exports = grammar({
|
|||
),
|
||||
|
||||
_statement_not_subshell: $ => choice(
|
||||
$.case_statement,
|
||||
$.command,
|
||||
$.compound_statement,
|
||||
$.for_statement,
|
||||
$.function_definition,
|
||||
$.if_statement,
|
||||
$.list,
|
||||
$.negated_command,
|
||||
$.pipeline,
|
||||
$.redirected_statement,
|
||||
$.variable_assignment,
|
||||
$.variable_assignments,
|
||||
$.command,
|
||||
$.declaration_command,
|
||||
$.unset_command,
|
||||
$.negated_command,
|
||||
$.for_statement,
|
||||
$.while_statement,
|
||||
$.if_statement,
|
||||
$.case_statement,
|
||||
$.pipeline,
|
||||
$.list,
|
||||
$.compound_statement,
|
||||
$.function_definition,
|
||||
),
|
||||
|
||||
_statement_not_pipeline: $ => prec(1, choice(
|
||||
$.case_statement,
|
||||
$.command,
|
||||
$.compound_statement,
|
||||
$.for_statement,
|
||||
$.function_definition,
|
||||
$.if_statement,
|
||||
$.list,
|
||||
$.negated_command,
|
||||
$.redirected_statement,
|
||||
$.subshell,
|
||||
$.variable_assignment,
|
||||
$.variable_assignments,
|
||||
$.command,
|
||||
$.declaration_command,
|
||||
$.unset_command,
|
||||
$.negated_command,
|
||||
$.for_statement,
|
||||
$.while_statement,
|
||||
$.if_statement,
|
||||
$.case_statement,
|
||||
$.list,
|
||||
$.compound_statement,
|
||||
$.function_definition,
|
||||
$.subshell,
|
||||
)),
|
||||
|
||||
redirected_statement: $ => prec.dynamic(-1, prec.right(-1, choice(
|
||||
|
|
@ -163,7 +156,7 @@ module.exports = grammar({
|
|||
))),
|
||||
|
||||
for_statement: $ => seq(
|
||||
choice('for', 'select'),
|
||||
'for',
|
||||
field('variable', $._simple_variable_name),
|
||||
optional(seq(
|
||||
'in',
|
||||
|
|
@ -226,7 +219,7 @@ module.exports = grammar({
|
|||
repeat(seq('|', field('value', choice($._literal, $._extglob_blob)))),
|
||||
')',
|
||||
repeat('\n'),
|
||||
choice(field('statements', $._statements)),
|
||||
choice(field('cmds', $._statements)),
|
||||
optional(';;')
|
||||
),
|
||||
|
||||
|
|
@ -236,21 +229,17 @@ module.exports = grammar({
|
|||
repeat(seq('|', field('value', choice($._literal, $._extglob_blob)))),
|
||||
')',
|
||||
repeat('\n'),
|
||||
choice(field('statements', $._statements)),
|
||||
choice(field('cmds', $._statements)),
|
||||
';;'
|
||||
),
|
||||
|
||||
function_definition: $ => prec.right(seq(
|
||||
field('name', $.word),
|
||||
'(', ')',
|
||||
field('body', choice($.compound_statement, $.subshell)),
|
||||
field('redirect', optional($.file_redirect)),
|
||||
field('body', choice($.compound_statement, $.subshell, $.command, $.while_statement, $.if_statement, $.for_statement, $.variable_assignments, repeat1($.file_redirect))),
|
||||
)),
|
||||
|
||||
compound_statement: $ => seq(
|
||||
'{', $._terminated_statement, token(prec(1, '}'))
|
||||
),
|
||||
|
||||
compound_statement: $ => seq('{', $._terminated_statement, '}'),
|
||||
subshell: $ => seq('(', $._statements, ')'),
|
||||
|
||||
pipeline: $ => prec.right(seq(
|
||||
|
|
@ -275,23 +264,6 @@ module.exports = grammar({
|
|||
),
|
||||
),
|
||||
|
||||
declaration_command: $ => prec.left(seq(
|
||||
choice('declare', 'typeset', 'export', 'readonly', 'local'),
|
||||
repeat(choice(
|
||||
$._literal,
|
||||
$._simple_variable_name,
|
||||
$.variable_assignment,
|
||||
)),
|
||||
)),
|
||||
|
||||
unset_command: $ => prec.left(seq(
|
||||
choice('unset', 'unsetenv'),
|
||||
repeat(choice(
|
||||
$._literal,
|
||||
$._simple_variable_name,
|
||||
)),
|
||||
)),
|
||||
|
||||
command: $ => prec.left(seq(
|
||||
repeat(choice(
|
||||
$.variable_assignment,
|
||||
|
|
@ -300,8 +272,8 @@ module.exports = grammar({
|
|||
field('name', $.command_name),
|
||||
choice(
|
||||
repeat(choice(
|
||||
field('argument', $._literal),
|
||||
field('argument', alias($._bare_dollar, '$')),
|
||||
field('arg', $._literal),
|
||||
field('arg', alias($._bare_dollar, '$')),
|
||||
)),
|
||||
$.subshell,
|
||||
),
|
||||
|
|
@ -325,22 +297,22 @@ module.exports = grammar({
|
|||
variable_assignments: $ => seq($.variable_assignment, repeat1($.variable_assignment)),
|
||||
|
||||
file_redirect: $ => prec.left(seq(
|
||||
field('descriptor', optional($.file_descriptor)),
|
||||
field('fd', optional($.file_descriptor)),
|
||||
choice(
|
||||
seq(
|
||||
choice('<', '>', '>>', '&>', '&>>', '<&', '>&', '>|'),
|
||||
field('destination', repeat1($._literal)),
|
||||
field('op', choice('<', '>', '>>', '&>', '&>>', '<&', '>&', '>|')),
|
||||
field('dest', repeat1($._literal)),
|
||||
),
|
||||
seq(
|
||||
choice('<&-', '>&-'), // close file descriptor
|
||||
optional(field('destination', $._literal)),
|
||||
field('op', choice('<&-', '>&-')),
|
||||
field('dest', optional($._literal)),
|
||||
),
|
||||
),
|
||||
)),
|
||||
|
||||
heredoc_redirect: $ => seq(
|
||||
field('descriptor', optional($.file_descriptor)),
|
||||
choice('<<', '<<-'),
|
||||
field('fd', optional($.file_descriptor)),
|
||||
field('op', choice('<<', '<<-')),
|
||||
$.heredoc_start,
|
||||
optional(choice(
|
||||
alias($._heredoc_pipeline, $.pipeline),
|
||||
|
|
@ -361,11 +333,11 @@ module.exports = grammar({
|
|||
),
|
||||
|
||||
_heredoc_expression: $ => seq(
|
||||
field('operator', choice('||', '&&')),
|
||||
field('op', choice('||', '&&')),
|
||||
field('right', $._statement),
|
||||
),
|
||||
|
||||
_heredoc_command: $ => repeat1(field('argument', $._literal)),
|
||||
_heredoc_command: $ => repeat1(field('arg', $._literal)),
|
||||
|
||||
_heredoc_body: $ => seq(
|
||||
$.heredoc_body,
|
||||
|
|
@ -441,7 +413,7 @@ module.exports = grammar({
|
|||
return choice(...table.map(([operator, precedence]) =>
|
||||
prec.left(precedence, seq(
|
||||
field('left', $._arithmetic_expression),
|
||||
field('operator', operator),
|
||||
field('op', operator),
|
||||
field('right', $._arithmetic_expression),
|
||||
))
|
||||
));
|
||||
|
|
@ -457,22 +429,22 @@ module.exports = grammar({
|
|||
|
||||
arithmetic_unary_expression: $ => choice(
|
||||
prec(PREC.PREFIX, seq(
|
||||
field('operator', tokenLiterals(1, '++', '--')),
|
||||
field('op', tokenLiterals(1, '++', '--')),
|
||||
$._arithmetic_expression,
|
||||
)),
|
||||
prec(PREC.UNARY, seq(
|
||||
field('operator', tokenLiterals(1, '-', '+', '~')),
|
||||
field('op', tokenLiterals(1, '-', '+', '~')),
|
||||
$._arithmetic_expression,
|
||||
)),
|
||||
prec.right(PREC.UNARY, seq(
|
||||
field('operator', '!'),
|
||||
field('op', '!'),
|
||||
$._arithmetic_expression,
|
||||
)),
|
||||
),
|
||||
|
||||
arithmetic_postfix_expression: $ => prec(PREC.POSTFIX, seq(
|
||||
$._arithmetic_expression,
|
||||
field('operator', choice('++', '--')),
|
||||
field('op', choice('++', '--')),
|
||||
)),
|
||||
|
||||
arithmetic_parenthesized_expression: $ => seq('(', $._arithmetic_expression, ')'),
|
||||
|
|
@ -536,13 +508,13 @@ module.exports = grammar({
|
|||
'}',
|
||||
),
|
||||
_expansion_body: $ => seq(
|
||||
choice($.variable_name, $._simple_variable_name, $._special_variable_name),
|
||||
optional(choice($._expansion_expression, $._expansion_regex)),
|
||||
field('name', choice($.variable_name, $._simple_variable_name, $._special_variable_name)),
|
||||
field('op', optional(choice($.expansion_expression, $.expansion_regex))),
|
||||
),
|
||||
|
||||
|
||||
_expansion_expression: $ => prec(1, seq(
|
||||
field('operator', immediateLiterals(':-', '-', ':=', '=', ':?', '?', ':+', '+',)),
|
||||
expansion_expression: $ => prec(1, seq(
|
||||
field('op', immediateLiterals(':-', '-', ':=', '=', ':?', '?', ':+', '+',)),
|
||||
optional(seq(
|
||||
choice(
|
||||
alias($._concatenation_in_expansion, $.concatenation),
|
||||
|
|
@ -555,8 +527,8 @@ module.exports = grammar({
|
|||
)),
|
||||
)),
|
||||
|
||||
_expansion_regex: $ => seq(
|
||||
field('operator', choice('#', alias($._immediate_double_hash, '##'), '%', '%%')),
|
||||
expansion_regex: $ => seq(
|
||||
field('op', choice('#', alias($._immediate_double_hash, '##'), '%', '%%')),
|
||||
repeat(choice(
|
||||
$.regex,
|
||||
alias(')', $.regex),
|
||||
|
|
@ -597,7 +569,6 @@ module.exports = grammar({
|
|||
seq('$(', $._statements, ')'),
|
||||
seq('$(', field('redirect', $.file_redirect), ')'),
|
||||
prec(1, seq('`', $._statements, '`')),
|
||||
seq('$`', $._statements, '`'),
|
||||
),
|
||||
|
||||
_extglob_blob: $ => choice(
|
||||
|
|
|
|||
|
|
@ -1204,32 +1204,32 @@ brace_start:
|
|||
return false;
|
||||
}
|
||||
|
||||
void *tree_sitter_bash_external_scanner_create()
|
||||
void *tree_sitter_sh_external_scanner_create()
|
||||
{
|
||||
Scanner *scanner = calloc(1, sizeof(Scanner));
|
||||
array_init(&scanner->heredocs);
|
||||
return scanner;
|
||||
}
|
||||
|
||||
bool tree_sitter_bash_external_scanner_scan(void *payload, TSLexer *lexer, const bool *valid_symbols)
|
||||
bool tree_sitter_sh_external_scanner_scan(void *payload, TSLexer *lexer, const bool *valid_symbols)
|
||||
{
|
||||
Scanner *scanner = (Scanner *)payload;
|
||||
return scan(scanner, lexer, valid_symbols);
|
||||
}
|
||||
|
||||
unsigned tree_sitter_bash_external_scanner_serialize(void *payload, char *state)
|
||||
unsigned tree_sitter_sh_external_scanner_serialize(void *payload, char *state)
|
||||
{
|
||||
Scanner *scanner = (Scanner *)payload;
|
||||
return serialize(scanner, state);
|
||||
}
|
||||
|
||||
void tree_sitter_bash_external_scanner_deserialize(void *payload, const char *state, unsigned length)
|
||||
void tree_sitter_sh_external_scanner_deserialize(void *payload, const char *state, unsigned length)
|
||||
{
|
||||
Scanner *scanner = (Scanner *)payload;
|
||||
deserialize(scanner, state, length);
|
||||
}
|
||||
|
||||
void tree_sitter_bash_external_scanner_destroy(void *payload)
|
||||
void tree_sitter_sh_external_scanner_destroy(void *payload)
|
||||
{
|
||||
Scanner *scanner = (Scanner *)payload;
|
||||
for (size_t i = 0; i < scanner->heredocs.size; i++)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue