Add file redirects
This commit is contained in:
parent
ab1d553e1d
commit
af279907bb
|
@ -77,3 +77,26 @@ a | b && c; d e f | e g
|
|||
(pipeline
|
||||
(simple_command (command_name) (argument) (argument))
|
||||
(simple_command (command_name) (argument))))))
|
||||
|
||||
===============================
|
||||
File redirects
|
||||
===============================
|
||||
|
||||
whoami > /dev/null
|
||||
cat a b 2> /dev/null
|
||||
2>&1 whoami
|
||||
|
||||
---
|
||||
|
||||
(program
|
||||
(command (simple_command
|
||||
(command_name)
|
||||
(file_redirect (file_name))))
|
||||
(command (simple_command
|
||||
(command_name)
|
||||
(argument)
|
||||
(argument)
|
||||
(file_redirect (file_descriptor) (file_name))))
|
||||
(command (simple_command
|
||||
(file_redirect (file_descriptor) (file_descriptor))
|
||||
(command_name))))
|
||||
|
|
23
grammar.js
23
grammar.js
|
@ -16,12 +16,18 @@ module.exports = grammar({
|
|||
),
|
||||
|
||||
simple_command: $ => seq(
|
||||
repeat($.environment_variable_assignment),
|
||||
repeat(choice(
|
||||
$.environment_variable_assignment,
|
||||
$.file_redirect
|
||||
)),
|
||||
rename($.leading_word, 'command_name'),
|
||||
optional(seq(
|
||||
/\s+/,
|
||||
repeat(rename($.word, 'argument'))
|
||||
))
|
||||
)),
|
||||
repeat(
|
||||
$.file_redirect
|
||||
)
|
||||
),
|
||||
|
||||
pipeline: $ => prec.left(seq(
|
||||
|
@ -49,9 +55,20 @@ module.exports = grammar({
|
|||
rename($.word, 'argument')
|
||||
),
|
||||
|
||||
file_redirect: $ => seq(
|
||||
optional($.file_descriptor),
|
||||
choice('<', '>', '<&', '>&'),
|
||||
choice(
|
||||
$.file_descriptor,
|
||||
rename($.word, 'file_name')
|
||||
)
|
||||
),
|
||||
|
||||
file_descriptor: $ => token(prec(1, /\d+/)),
|
||||
|
||||
leading_word: $ => /[^\s=|;]+/,
|
||||
|
||||
word: $ => /[^\s]+/,
|
||||
word: $ => /[^\s<>&]+/,
|
||||
|
||||
control_operator: $ => choice(
|
||||
'\n',
|
||||
|
|
|
@ -40,8 +40,17 @@
|
|||
{
|
||||
"type": "REPEAT",
|
||||
"content": {
|
||||
"type": "SYMBOL",
|
||||
"name": "environment_variable_assignment"
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "environment_variable_assignment"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "file_redirect"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -79,6 +88,13 @@
|
|||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "REPEAT",
|
||||
"content": {
|
||||
"type": "SYMBOL",
|
||||
"name": "file_redirect"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -189,13 +205,79 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"file_redirect": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "file_descriptor"
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "<"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": ">"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "<&"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": ">&"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "file_descriptor"
|
||||
},
|
||||
{
|
||||
"type": "RENAME",
|
||||
"content": {
|
||||
"type": "SYMBOL",
|
||||
"name": "word"
|
||||
},
|
||||
"value": "file_name"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"file_descriptor": {
|
||||
"type": "TOKEN",
|
||||
"content": {
|
||||
"type": "PREC",
|
||||
"value": 1,
|
||||
"content": {
|
||||
"type": "PATTERN",
|
||||
"value": "\\d+"
|
||||
}
|
||||
}
|
||||
},
|
||||
"leading_word": {
|
||||
"type": "PATTERN",
|
||||
"value": "[^\\s=|;]+"
|
||||
},
|
||||
"word": {
|
||||
"type": "PATTERN",
|
||||
"value": "[^\\s]+"
|
||||
"value": "[^\\s<>&]+"
|
||||
},
|
||||
"control_operator": {
|
||||
"type": "CHOICE",
|
||||
|
|
1628
src/parser.c
1628
src/parser.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue