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
|
(pipeline
|
||||||
(simple_command (command_name) (argument) (argument))
|
(simple_command (command_name) (argument) (argument))
|
||||||
(simple_command (command_name) (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(
|
simple_command: $ => seq(
|
||||||
repeat($.environment_variable_assignment),
|
repeat(choice(
|
||||||
|
$.environment_variable_assignment,
|
||||||
|
$.file_redirect
|
||||||
|
)),
|
||||||
rename($.leading_word, 'command_name'),
|
rename($.leading_word, 'command_name'),
|
||||||
optional(seq(
|
optional(seq(
|
||||||
/\s+/,
|
/\s+/,
|
||||||
repeat(rename($.word, 'argument'))
|
repeat(rename($.word, 'argument'))
|
||||||
))
|
)),
|
||||||
|
repeat(
|
||||||
|
$.file_redirect
|
||||||
|
)
|
||||||
),
|
),
|
||||||
|
|
||||||
pipeline: $ => prec.left(seq(
|
pipeline: $ => prec.left(seq(
|
||||||
|
@ -49,9 +55,20 @@ module.exports = grammar({
|
||||||
rename($.word, 'argument')
|
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=|;]+/,
|
leading_word: $ => /[^\s=|;]+/,
|
||||||
|
|
||||||
word: $ => /[^\s]+/,
|
word: $ => /[^\s<>&]+/,
|
||||||
|
|
||||||
control_operator: $ => choice(
|
control_operator: $ => choice(
|
||||||
'\n',
|
'\n',
|
||||||
|
|
|
@ -40,8 +40,17 @@
|
||||||
{
|
{
|
||||||
"type": "REPEAT",
|
"type": "REPEAT",
|
||||||
"content": {
|
"content": {
|
||||||
|
"type": "CHOICE",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
"type": "SYMBOL",
|
"type": "SYMBOL",
|
||||||
"name": "environment_variable_assignment"
|
"name": "environment_variable_assignment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "file_redirect"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -79,6 +88,13 @@
|
||||||
"type": "BLANK"
|
"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": {
|
"leading_word": {
|
||||||
"type": "PATTERN",
|
"type": "PATTERN",
|
||||||
"value": "[^\\s=|;]+"
|
"value": "[^\\s=|;]+"
|
||||||
},
|
},
|
||||||
"word": {
|
"word": {
|
||||||
"type": "PATTERN",
|
"type": "PATTERN",
|
||||||
"value": "[^\\s]+"
|
"value": "[^\\s<>&]+"
|
||||||
},
|
},
|
||||||
"control_operator": {
|
"control_operator": {
|
||||||
"type": "CHOICE",
|
"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