Fix distinction between numeric args and redirect file descriptors
This commit is contained in:
parent
86e67f9403
commit
a0406c8906
|
@ -23,7 +23,7 @@ cat -n file1.txt file2.txt
|
||||||
(command (command_name) (argument) (argument) (argument)))
|
(command (command_name) (argument) (argument) (argument)))
|
||||||
|
|
||||||
===============================
|
===============================
|
||||||
Commands with string arguments
|
Commands with quoted arguments
|
||||||
===============================
|
===============================
|
||||||
|
|
||||||
echo "hello $(whoami), this is $(uname)"
|
echo "hello $(whoami), this is $(uname)"
|
||||||
|
@ -37,6 +37,17 @@ echo 'hi'
|
||||||
(command_substitution (command (command_name)))))
|
(command_substitution (command (command_name)))))
|
||||||
(command (command_name) (single_quoted_argument)))
|
(command (command_name) (single_quoted_argument)))
|
||||||
|
|
||||||
|
===============================
|
||||||
|
Commands with numeric arguments
|
||||||
|
===============================
|
||||||
|
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(program
|
||||||
|
(command (command_name) (argument)))
|
||||||
|
|
||||||
===================================
|
===================================
|
||||||
Commands with environment variables
|
Commands with environment variables
|
||||||
===================================
|
===================================
|
||||||
|
@ -99,7 +110,7 @@ File redirects
|
||||||
===============================
|
===============================
|
||||||
|
|
||||||
whoami > /dev/null
|
whoami > /dev/null
|
||||||
cat a b 2> /dev/null
|
cat a b > /dev/null
|
||||||
2>&1 whoami
|
2>&1 whoami
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -107,14 +118,14 @@ cat a b 2> /dev/null
|
||||||
(program
|
(program
|
||||||
(command
|
(command
|
||||||
(command_name)
|
(command_name)
|
||||||
(file_redirect (file_name)))
|
(file_redirect (argument)))
|
||||||
(command
|
(command
|
||||||
(command_name)
|
(command_name)
|
||||||
(argument)
|
(argument)
|
||||||
(argument)
|
(argument)
|
||||||
(file_redirect (file_descriptor) (file_name)))
|
(file_redirect (argument)))
|
||||||
(command
|
(command
|
||||||
(file_redirect (file_descriptor) (file_descriptor))
|
(file_redirect (file_descriptor) (argument))
|
||||||
(command_name)))
|
(command_name)))
|
||||||
|
|
||||||
===============================
|
===============================
|
||||||
|
|
12
grammar.js
12
grammar.js
|
@ -7,7 +7,8 @@ module.exports = grammar({
|
||||||
$._simple_heredoc,
|
$._simple_heredoc,
|
||||||
$._heredoc_beginning,
|
$._heredoc_beginning,
|
||||||
$._heredoc_middle,
|
$._heredoc_middle,
|
||||||
$._heredoc_end
|
$._heredoc_end,
|
||||||
|
$.file_descriptor
|
||||||
],
|
],
|
||||||
|
|
||||||
extras: $ => [
|
extras: $ => [
|
||||||
|
@ -171,11 +172,8 @@ module.exports = grammar({
|
||||||
|
|
||||||
file_redirect: $ => seq(
|
file_redirect: $ => seq(
|
||||||
optional($.file_descriptor),
|
optional($.file_descriptor),
|
||||||
choice('<', '>', '<&', '>&'),
|
choice('<', '>', '>>', '&>', '&>>', '<&', '>&'),
|
||||||
choice(
|
$.value
|
||||||
$.file_descriptor,
|
|
||||||
rename($.word, 'file_name')
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
|
|
||||||
heredoc_redirect: $ => seq(
|
heredoc_redirect: $ => seq(
|
||||||
|
@ -196,8 +194,6 @@ module.exports = grammar({
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
||||||
file_descriptor: $ => token(prec(1, /\d+/)),
|
|
||||||
|
|
||||||
leading_word: $ => /[^"\\\s#=|;:{}()]+/,
|
leading_word: $ => /[^"\\\s#=|;:{}()]+/,
|
||||||
|
|
||||||
word: $ => /[^"#\\\s$<>{}&;()]+/,
|
word: $ => /[^"#\\\s$<>{}&;()]+/,
|
||||||
|
|
|
@ -646,6 +646,18 @@
|
||||||
"type": "STRING",
|
"type": "STRING",
|
||||||
"value": ">"
|
"value": ">"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": ">>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": "&>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": "&>>"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "STRING",
|
"type": "STRING",
|
||||||
"value": "<&"
|
"value": "<&"
|
||||||
|
@ -657,21 +669,8 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "CHOICE",
|
"type": "SYMBOL",
|
||||||
"members": [
|
"name": "value"
|
||||||
{
|
|
||||||
"type": "SYMBOL",
|
|
||||||
"name": "file_descriptor"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "RENAME",
|
|
||||||
"content": {
|
|
||||||
"type": "SYMBOL",
|
|
||||||
"name": "word"
|
|
||||||
},
|
|
||||||
"value": "file_name"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -739,17 +738,6 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"file_descriptor": {
|
|
||||||
"type": "TOKEN",
|
|
||||||
"content": {
|
|
||||||
"type": "PREC",
|
|
||||||
"value": 1,
|
|
||||||
"content": {
|
|
||||||
"type": "PATTERN",
|
|
||||||
"value": "\\d+"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"leading_word": {
|
"leading_word": {
|
||||||
"type": "PATTERN",
|
"type": "PATTERN",
|
||||||
"value": "[^\"\\\\\\s#=|;:{}()]+"
|
"value": "[^\"\\\\\\s#=|;:{}()]+"
|
||||||
|
@ -819,6 +807,10 @@
|
||||||
{
|
{
|
||||||
"type": "SYMBOL",
|
"type": "SYMBOL",
|
||||||
"name": "_heredoc_end"
|
"name": "_heredoc_end"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "file_descriptor"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"inline": [
|
"inline": [
|
||||||
|
|
17914
src/parser.c
17914
src/parser.c
File diff suppressed because it is too large
Load Diff
|
@ -11,6 +11,7 @@ enum TokenType {
|
||||||
HEREDOC_BEGINNING,
|
HEREDOC_BEGINNING,
|
||||||
HEREDOC_MIDDLE,
|
HEREDOC_MIDDLE,
|
||||||
HEREDOC_END,
|
HEREDOC_END,
|
||||||
|
FILE_DESCRIPTOR,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Scanner {
|
struct Scanner {
|
||||||
|
@ -74,23 +75,35 @@ struct Scanner {
|
||||||
bool scan(TSLexer *lexer, const bool *valid_symbols) {
|
bool scan(TSLexer *lexer, const bool *valid_symbols) {
|
||||||
if (valid_symbols[HEREDOC_MIDDLE]) {
|
if (valid_symbols[HEREDOC_MIDDLE]) {
|
||||||
return scan_heredoc_content(lexer, HEREDOC_MIDDLE, HEREDOC_END);
|
return scan_heredoc_content(lexer, HEREDOC_MIDDLE, HEREDOC_END);
|
||||||
}
|
} else if (valid_symbols[HEREDOC_BEGINNING]) {
|
||||||
|
heredoc_identifier.clear();
|
||||||
|
while (iswalpha(lexer->lookahead)) {
|
||||||
|
heredoc_identifier += lexer->lookahead;
|
||||||
|
advance(lexer);
|
||||||
|
}
|
||||||
|
|
||||||
heredoc_identifier.clear();
|
if (lexer->lookahead != '\n') return false;
|
||||||
while (iswalpha(lexer->lookahead)) {
|
|
||||||
heredoc_identifier += lexer->lookahead;
|
|
||||||
advance(lexer);
|
advance(lexer);
|
||||||
|
|
||||||
|
if (scan_heredoc_end_identifier(lexer)) {
|
||||||
|
lexer->result_symbol = SIMPLE_HEREDOC;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return scan_heredoc_content(lexer, HEREDOC_BEGINNING, SIMPLE_HEREDOC);
|
||||||
|
} else if (valid_symbols[FILE_DESCRIPTOR]) {
|
||||||
|
while (lexer->lookahead == ' ' || lexer->lookahead == '\t') skip(lexer);
|
||||||
|
if (iswdigit(lexer->lookahead)) {
|
||||||
|
advance(lexer);
|
||||||
|
while (iswdigit(lexer->lookahead)) advance(lexer);
|
||||||
|
if (lexer->lookahead == '>' || lexer->lookahead == '<') {
|
||||||
|
lexer->result_symbol = FILE_DESCRIPTOR;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lexer->lookahead != '\n') return false;
|
return false;
|
||||||
advance(lexer);
|
|
||||||
|
|
||||||
if (scan_heredoc_end_identifier(lexer)) {
|
|
||||||
lexer->result_symbol = SIMPLE_HEREDOC;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return scan_heredoc_content(lexer, HEREDOC_BEGINNING, SIMPLE_HEREDOC);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wstring heredoc_identifier;
|
wstring heredoc_identifier;
|
||||||
|
|
Loading…
Reference in New Issue