Add variable expansions

This commit is contained in:
Max Brunsfeld 2017-07-14 13:00:41 -07:00
parent af279907bb
commit d2ac184c81
4 changed files with 1534 additions and 1012 deletions

View File

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

View File

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

View File

@ -74,12 +74,25 @@
{ {
"type": "REPEAT", "type": "REPEAT",
"content": { "content": {
"type": "RENAME", "type": "CHOICE",
"content": { "members": [
"type": "SYMBOL", {
"name": "word" "type": "RENAME",
}, "content": {
"value": "argument" "type": "SYMBOL",
"name": "word"
},
"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",

File diff suppressed because it is too large Load Diff