Add variable expansions
This commit is contained in:
parent
af279907bb
commit
d2ac184c81
|
@ -100,3 +100,31 @@ cat a b 2> /dev/null
|
||||||
(command (simple_command
|
(command (simple_command
|
||||||
(file_redirect (file_descriptor) (file_descriptor))
|
(file_redirect (file_descriptor) (file_descriptor))
|
||||||
(command_name))))
|
(command_name))))
|
||||||
|
|
||||||
|
===============================
|
||||||
|
Variable expansions
|
||||||
|
===============================
|
||||||
|
|
||||||
|
cat $FOO
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(program
|
||||||
|
(command (simple_command
|
||||||
|
(command_name)
|
||||||
|
(expansion (variable_name)))))
|
||||||
|
|
||||||
|
===============================
|
||||||
|
Variable expansion operators
|
||||||
|
===============================
|
||||||
|
|
||||||
|
cat ${BAR} ${ABC=def} ${GHI:?jkl}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(program
|
||||||
|
(command (simple_command
|
||||||
|
(command_name)
|
||||||
|
(operator_expansion (variable_name))
|
||||||
|
(operator_expansion (variable_name) (argument))
|
||||||
|
(operator_expansion (variable_name) (argument)))))
|
||||||
|
|
25
grammar.js
25
grammar.js
|
@ -23,7 +23,11 @@ module.exports = grammar({
|
||||||
rename($.leading_word, 'command_name'),
|
rename($.leading_word, 'command_name'),
|
||||||
optional(seq(
|
optional(seq(
|
||||||
/\s+/,
|
/\s+/,
|
||||||
repeat(rename($.word, 'argument'))
|
repeat(choice(
|
||||||
|
rename($.word, 'argument'),
|
||||||
|
$.expansion,
|
||||||
|
$.operator_expansion
|
||||||
|
))
|
||||||
)),
|
)),
|
||||||
repeat(
|
repeat(
|
||||||
$.file_redirect
|
$.file_redirect
|
||||||
|
@ -55,6 +59,21 @@ module.exports = grammar({
|
||||||
rename($.word, 'argument')
|
rename($.word, 'argument')
|
||||||
),
|
),
|
||||||
|
|
||||||
|
expansion: $ => seq(
|
||||||
|
'$',
|
||||||
|
rename($.word, 'variable_name')
|
||||||
|
),
|
||||||
|
|
||||||
|
operator_expansion: $ => seq(
|
||||||
|
'${',
|
||||||
|
rename($.leading_word, 'variable_name'),
|
||||||
|
optional(seq(
|
||||||
|
choice(':', ':?', '='),
|
||||||
|
rename($.word, 'argument')
|
||||||
|
)),
|
||||||
|
'}'
|
||||||
|
),
|
||||||
|
|
||||||
file_redirect: $ => seq(
|
file_redirect: $ => seq(
|
||||||
optional($.file_descriptor),
|
optional($.file_descriptor),
|
||||||
choice('<', '>', '<&', '>&'),
|
choice('<', '>', '<&', '>&'),
|
||||||
|
@ -66,9 +85,9 @@ module.exports = grammar({
|
||||||
|
|
||||||
file_descriptor: $ => token(prec(1, /\d+/)),
|
file_descriptor: $ => token(prec(1, /\d+/)),
|
||||||
|
|
||||||
leading_word: $ => /[^\s=|;]+/,
|
leading_word: $ => /[^\s=|;:{}]+/,
|
||||||
|
|
||||||
word: $ => /[^\s<>&]+/,
|
word: $ => /[^\s$<>{}&]+/,
|
||||||
|
|
||||||
control_operator: $ => choice(
|
control_operator: $ => choice(
|
||||||
'\n',
|
'\n',
|
||||||
|
|
|
@ -74,12 +74,25 @@
|
||||||
{
|
{
|
||||||
"type": "REPEAT",
|
"type": "REPEAT",
|
||||||
"content": {
|
"content": {
|
||||||
|
"type": "CHOICE",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
"type": "RENAME",
|
"type": "RENAME",
|
||||||
"content": {
|
"content": {
|
||||||
"type": "SYMBOL",
|
"type": "SYMBOL",
|
||||||
"name": "word"
|
"name": "word"
|
||||||
},
|
},
|
||||||
"value": "argument"
|
"value": "argument"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "expansion"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "operator_expansion"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -205,6 +218,82 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"expansion": {
|
||||||
|
"type": "SEQ",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": "$"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "RENAME",
|
||||||
|
"content": {
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "word"
|
||||||
|
},
|
||||||
|
"value": "variable_name"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"operator_expansion": {
|
||||||
|
"type": "SEQ",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": "${"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "RENAME",
|
||||||
|
"content": {
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "leading_word"
|
||||||
|
},
|
||||||
|
"value": "variable_name"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CHOICE",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "SEQ",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "CHOICE",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": ":"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": ":?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": "="
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "RENAME",
|
||||||
|
"content": {
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "word"
|
||||||
|
},
|
||||||
|
"value": "argument"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "BLANK"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": "}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"file_redirect": {
|
"file_redirect": {
|
||||||
"type": "SEQ",
|
"type": "SEQ",
|
||||||
"members": [
|
"members": [
|
||||||
|
@ -273,11 +362,11 @@
|
||||||
},
|
},
|
||||||
"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",
|
||||||
|
|
2388
src/parser.c
2388
src/parser.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue