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))) (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)))
=============================== ===============================

View File

@ -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$<>{}&;()]+/,

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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;