Fix distinction between numeric args and redirect file descriptors

This commit is contained in:
Max Brunsfeld 2017-07-14 17:14:23 -07:00
parent 86e67f9403
commit a0406c8906
5 changed files with 9743 additions and 8287 deletions

View File

@ -23,7 +23,7 @@ cat -n file1.txt file2.txt
(command (command_name) (argument) (argument) (argument)))
===============================
Commands with string arguments
Commands with quoted arguments
===============================
echo "hello $(whoami), this is $(uname)"
@ -37,6 +37,17 @@ echo 'hi'
(command_substitution (command (command_name)))))
(command (command_name) (single_quoted_argument)))
===============================
Commands with numeric arguments
===============================
exit 1
---
(program
(command (command_name) (argument)))
===================================
Commands with environment variables
===================================
@ -99,7 +110,7 @@ File redirects
===============================
whoami > /dev/null
cat a b 2> /dev/null
cat a b > /dev/null
2>&1 whoami
---
@ -107,14 +118,14 @@ cat a b 2> /dev/null
(program
(command
(command_name)
(file_redirect (file_name)))
(file_redirect (argument)))
(command
(command_name)
(argument)
(argument)
(file_redirect (file_descriptor) (file_name)))
(file_redirect (argument)))
(command
(file_redirect (file_descriptor) (file_descriptor))
(file_redirect (file_descriptor) (argument))
(command_name)))
===============================

View File

@ -7,7 +7,8 @@ module.exports = grammar({
$._simple_heredoc,
$._heredoc_beginning,
$._heredoc_middle,
$._heredoc_end
$._heredoc_end,
$.file_descriptor
],
extras: $ => [
@ -171,11 +172,8 @@ module.exports = grammar({
file_redirect: $ => seq(
optional($.file_descriptor),
choice('<', '>', '<&', '>&'),
choice(
$.file_descriptor,
rename($.word, 'file_name')
)
choice('<', '>', '>>', '&>', '&>>', '<&', '>&'),
$.value
),
heredoc_redirect: $ => seq(
@ -196,8 +194,6 @@ module.exports = grammar({
)
),
file_descriptor: $ => token(prec(1, /\d+/)),
leading_word: $ => /[^"\\\s#=|;:{}()]+/,
word: $ => /[^"#\\\s$<>{}&;()]+/,

View File

@ -646,6 +646,18 @@
"type": "STRING",
"value": ">"
},
{
"type": "STRING",
"value": ">>"
},
{
"type": "STRING",
"value": "&>"
},
{
"type": "STRING",
"value": "&>>"
},
{
"type": "STRING",
"value": "<&"
@ -657,21 +669,8 @@
]
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "file_descriptor"
},
{
"type": "RENAME",
"content": {
"type": "SYMBOL",
"name": "word"
},
"value": "file_name"
}
]
"type": "SYMBOL",
"name": "value"
}
]
},
@ -739,17 +738,6 @@
}
]
},
"file_descriptor": {
"type": "TOKEN",
"content": {
"type": "PREC",
"value": 1,
"content": {
"type": "PATTERN",
"value": "\\d+"
}
}
},
"leading_word": {
"type": "PATTERN",
"value": "[^\"\\\\\\s#=|;:{}()]+"
@ -819,6 +807,10 @@
{
"type": "SYMBOL",
"name": "_heredoc_end"
},
{
"type": "SYMBOL",
"name": "file_descriptor"
}
],
"inline": [

17914
src/parser.c

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,7 @@ enum TokenType {
HEREDOC_BEGINNING,
HEREDOC_MIDDLE,
HEREDOC_END,
FILE_DESCRIPTOR,
};
struct Scanner {
@ -74,23 +75,35 @@ struct Scanner {
bool scan(TSLexer *lexer, const bool *valid_symbols) {
if (valid_symbols[HEREDOC_MIDDLE]) {
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();
while (iswalpha(lexer->lookahead)) {
heredoc_identifier += lexer->lookahead;
if (lexer->lookahead != '\n') 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);
} 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;
advance(lexer);
if (scan_heredoc_end_identifier(lexer)) {
lexer->result_symbol = SIMPLE_HEREDOC;
return true;
}
return scan_heredoc_content(lexer, HEREDOC_BEGINNING, SIMPLE_HEREDOC);
return false;
}
wstring heredoc_identifier;