This commit is contained in:
Maieul BOYER 2024-06-07 18:42:48 +02:00
parent f80d3611b1
commit f9a7d5b38b
No known key found for this signature in database
3 changed files with 1278 additions and 90 deletions

5
.gitignore vendored
View file

@ -67,4 +67,7 @@ tree-sitter-sh/bindings/
tree-sitter-sh/package-lock.json tree-sitter-sh/package-lock.json
tree-sitter-sh/pyproject.toml tree-sitter-sh/pyproject.toml
tree-sitter-sh/setup.py tree-sitter-sh/setup.py
tree-sitter-sh/src/ tree-sitter-sh/src/grammar.json
tree-sitter-sh/src/parser.c
tree-sitter-sh/src/tree_sitter/
tree-sitter-sh/src/node-types.json

View file

@ -9,16 +9,8 @@
// @ts-check // @ts-check
const SPECIAL_CHARACTERS = [ const SPECIAL_CHARACTERS = [
'\'', '"', "|", "&", ";", "<", ">", "(", ")", "$", "`", "\\", "\"", "'", " ", "\t", "\n",
'<', '>', ]
'{', '}',
'\\[', '\\]',
'(', ')',
'`', '$',
'|', '&', ';',
'\\',
'\\s',
];
const PREC = { const PREC = {
UPDATE: 0, UPDATE: 0,
@ -63,7 +55,6 @@ module.exports = grammar({
$._multiline_variable_name, $._multiline_variable_name,
$._special_variable_name, $._special_variable_name,
$._statement_not_subshell, $._statement_not_subshell,
$._redirect,
], ],
externals: $ => [ externals: $ => [
@ -76,17 +67,11 @@ module.exports = grammar({
$._empty_value, $._empty_value,
$._concat, $._concat,
$.variable_name, // Variable name followed by an operator like '=' or '+=' $.variable_name, // Variable name followed by an operator like '=' or '+='
$.test_operator,
$.regex, $.regex,
$._regex_no_slash,
$._regex_no_space,
$._expansion_word, $._expansion_word,
$.extglob_pattern, $.extglob_pattern,
$._bare_dollar, $._bare_dollar,
$._brace_start,
$._immediate_double_hash, $._immediate_double_hash,
'}',
']',
'<<', '<<',
'<<-', '<<-',
/\n/, /\n/,
@ -174,7 +159,7 @@ module.exports = grammar({
field('body', $._statement), field('body', $._statement),
field('redirect', repeat1(choice($.file_redirect, $.heredoc_redirect))), field('redirect', repeat1(choice($.file_redirect, $.heredoc_redirect))),
), ),
field('redirect', repeat1($._redirect)), field('redirect', repeat1($.file_redirect)),
))), ))),
for_statement: $ => seq( for_statement: $ => seq(
@ -229,64 +214,43 @@ module.exports = grammar({
'in', 'in',
optional($._terminator), optional($._terminator),
optional(seq( optional(seq(
repeat($.case_item), repeat(field('cases', $.case_item)),
alias($.last_case_item, $.case_item), field('cases', alias($._case_item_last, $.case_item))
)), )),
'esac', 'esac',
), ),
case_item: $ => seq( _case_item_last: $ => seq(
choice(
seq(
optional('('),
field('value', choice($._literal, $._extglob_blob)),
repeat(seq('|', field('value', choice($._literal, $._extglob_blob)))),
')',
),
),
optional($._statements),
prec(1, choice(
field('termination', ';;'),
field('fallthrough', choice(';&', ';;&')),
)),
),
last_case_item: $ => seq(
optional('('), optional('('),
field('value', choice($._literal, $._extglob_blob)), field('value', choice($._literal, $._extglob_blob)),
repeat(seq('|', field('value', choice($._literal, $._extglob_blob)))), repeat(seq('|', field('value', choice($._literal, $._extglob_blob)))),
')', ')',
optional($._statements), repeat('\n'),
optional(prec(1, ';;')), choice(field('statements', $._statements)),
optional(';;')
),
case_item: $ => seq(
optional('('),
field('value', choice($._literal, $._extglob_blob)),
repeat(seq('|', field('value', choice($._literal, $._extglob_blob)))),
')',
repeat('\n'),
choice(field('statements', $._statements)),
';;'
), ),
function_definition: $ => prec.right(seq( function_definition: $ => prec.right(seq(
choice( field('name', $.word),
seq( '(', ')',
'function', field('body', choice($.compound_statement, $.subshell)),
field('name', $.word), field('redirect', optional($.file_redirect)),
optional(seq('(', ')')),
),
seq(
field('name', $.word),
'(', ')',
),
),
field(
'body',
choice(
$.compound_statement,
$.subshell,
$.if_statement,
),
),
field('redirect', optional($._redirect)),
)), )),
compound_statement: $ => seq( compound_statement: $ => seq(
'{', '{',
optional($._terminated_statement), $._terminated_statement,
token(prec(-1, '}')), token(prec(1, '}')),
), ),
subshell: $ => seq('(', $._statements, ')'), subshell: $ => seq('(', $._statements, ')'),
@ -336,7 +300,7 @@ module.exports = grammar({
command: $ => prec.left(seq( command: $ => prec.left(seq(
repeat(choice( repeat(choice(
$.variable_assignment, $.variable_assignment,
field('redirect', $._redirect), field('redirect', $.file_redirect),
)), )),
field('name', $.command_name), field('name', $.command_name),
choice( choice(
@ -386,7 +350,7 @@ module.exports = grammar({
optional(choice( optional(choice(
alias($._heredoc_pipeline, $.pipeline), alias($._heredoc_pipeline, $.pipeline),
seq( seq(
field('redirect', repeat1($._redirect)), field('redirect', repeat1($.file_redirect)),
optional($._heredoc_expression), optional($._heredoc_expression),
), ),
$._heredoc_expression, $._heredoc_expression,
@ -428,19 +392,16 @@ module.exports = grammar({
$.heredoc_end, $.heredoc_end,
), ),
_redirect: $ => $.file_redirect,
// Literals // Literals
_literal: $ => choice( _literal: $ => choice(
$.concatenation, $.concatenation,
$._primary_expression, $._primary_expression,
alias(prec(-2, repeat1($._special_character)), $.word), // alias(prec(-2, repeat1($._special_character)), $.word),
), ),
_primary_expression: $ => choice( _primary_expression: $ => choice(
$.word, $.word,
alias($.test_operator, $.word),
$.string, $.string,
$.raw_string, $.raw_string,
$.number, $.number,
@ -448,18 +409,10 @@ module.exports = grammar({
$.simple_expansion, $.simple_expansion,
$.command_substitution, $.command_substitution,
$.arithmetic_expansion, $.arithmetic_expansion,
$.brace_expression,
), ),
arithmetic_expansion: $ => seq('$((', commaSep1($._arithmetic_expression), '))'), arithmetic_expansion: $ => seq('$((', optional($._arithmetic_expression), '))'),
brace_expression: $ => seq(
alias($._brace_start, '{'),
alias(token.immediate(/\d+/), $.number),
token.immediate('..'),
alias(token.immediate(/\d+/), $.number),
token.immediate('}'),
),
_arithmetic_expression: $ => prec(1, choice( _arithmetic_expression: $ => prec(1, choice(
$._arithmetic_literal, $._arithmetic_literal,
alias($._arithmetic_unary_expression, $.unary_expression), alias($._arithmetic_unary_expression, $.unary_expression),
@ -534,23 +487,14 @@ module.exports = grammar({
field('operator', choice('++', '--')), field('operator', choice('++', '--')),
)), )),
_arithmetic_parenthesized_expression: $ => seq( _arithmetic_parenthesized_expression: $ => seq('(', $._arithmetic_expression, ')'),
'(',
$._arithmetic_expression,
')',
),
concatenation: $ => prec(-1, seq( concatenation: $ => prec(-1, seq(
choice( $._primary_expression,
$._primary_expression,
alias($._special_character, $.word),
),
repeat1(seq( repeat1(seq(
choice($._concat, alias(/`\s*`/, '``')), choice($._concat, alias(/`\s*`/, '``')),
choice( choice(
$._primary_expression, $._primary_expression,
alias($._special_character, $.word),
alias($._comment_word, $.word), alias($._comment_word, $.word),
alias($._bare_dollar, '$'), alias($._bare_dollar, '$'),
), ),
@ -558,8 +502,6 @@ module.exports = grammar({
optional(seq($._concat, '$')), optional(seq($._concat, '$')),
)), )),
_special_character: _ => token(prec(-1, choice('{', '}', '[', ']'))),
string: $ => seq( string: $ => seq(
'"', '"',
repeat(seq( repeat(seq(

1243
tree-sitter-sh/src/scanner.c Normal file

File diff suppressed because it is too large Load diff