Make sure $( is always considered as cmd substitution ##newshell (#17699)

Sometimes argument could be "value$", but this commits ensures that if
the argument is "value$(...)", then `$(...)` is considered as a
cmd_substitution_arg.
This commit is contained in:
Riccardo Schirone 2020-09-23 21:43:36 +02:00 committed by GitHub
parent 22468fdc0a
commit 13ca72df81
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 24610 additions and 23551 deletions

View file

@ -65,3 +65,24 @@ Nested command substitution
args: (args (arg (cmd_substitution_arg
(arged_command command: (cmd_identifier)
args: (args (arg (arg_identifier)))))))))))))
=======================================
Nested command substitution 2
=======================================
?e Hello$(?e Wor$(?e ld))
---
(commands
(arged_command (cmd_identifier)
(args (arg (concatenation
(arg_identifier)
(cmd_substitution_arg
(arged_command (cmd_identifier)
(args (arg (concatenation
(arg_identifier)
(cmd_substitution_arg
(arged_command (cmd_identifier)
(args (arg (arg_identifier)))))))))))))))

View file

@ -258,6 +258,7 @@ s $
?v $*
?v $$$ test
?v $alias
?e hello$alias
?e test
---
@ -275,6 +276,8 @@ s $
(arg (arg_identifier))))
(arged_command (cmd_identifier)
(args (arg (arg_identifier))))
(arged_command (cmd_identifier)
(args (arg (arg_identifier))))
(arged_command (cmd_identifier)
(args (arg (arg_identifier)))))

View file

@ -25,7 +25,6 @@ const ARG_IDENTIFIER_BASE = choice(
repeat1(noneOf(...SPECIAL_CHARACTERS)),
'$$$',
'$$',
'$',
/\$[^\s@|#"'>;`~\\({) ]/,
/\${[^\r\n $}]+}/,
/\\./,
@ -34,7 +33,6 @@ const ARG_IDENTIFIER_BRACE = choice(
repeat1(noneOf(...SPECIAL_CHARACTERS_BRACE)),
'$$$',
'$$',
'$',
/\$[^\s@|#"'>;`~\\({) ]/,
/\${[^\r\n $}]+}/,
/\\./,
@ -43,7 +41,6 @@ const PF_DOT_ARG_IDENTIFIER_BASE = choice(
repeat1(noneOf(...PF_DOT_SPECIAL_CHARACTERS)),
'$$$',
'$$',
'$',
/\$[^\s@|#"'>;`~\\({) ]/,
/\${[^\r\n $}]+}/,
/\\./,
@ -52,7 +49,6 @@ const PF_ARG_IDENTIFIER_BASE = choice(
repeat1(noneOf(...PF_SPECIAL_CHARACTERS)),
'$$$',
'$$',
'$',
/\$[^\s@|#"'>;`~\\({) ]/,
/\${[^\r\n $}]+}/,
/\\./,
@ -437,17 +433,13 @@ module.exports = grammar({
$.pf_args,
)),
),
_pf_dot_arg_identifier: $ => token(seq(
repeat1(PF_DOT_ARG_IDENTIFIER_BASE),
)),
_pf_dot_arg_identifier: $ => argIdentifier(PF_DOT_ARG_IDENTIFIER_BASE),
_pf_arg_parentheses: $ => seq(
alias('(', $.pf_arg_identifier),
$.pf_args,
alias(')', $.pf_arg_identifier),
),
pf_arg_identifier: $ => token(seq(
repeat1(PF_ARG_IDENTIFIER_BASE),
)),
pf_arg_identifier: $ => argIdentifier(PF_ARG_IDENTIFIER_BASE),
_pf_arg: $ => choice(
$.pf_arg_identifier,
$._pf_arg_parentheses,
@ -628,8 +620,8 @@ module.exports = grammar({
)),
_any_command: $ => /[^\r\n;~|]+/,
arg_identifier: $ => token(repeat1(ARG_IDENTIFIER_BASE)),
arg_identifier_brace: $ => token(repeat1(ARG_IDENTIFIER_BRACE)),
arg_identifier: $ => argIdentifier(ARG_IDENTIFIER_BASE),
arg_identifier_brace: $ => argIdentifier(ARG_IDENTIFIER_BRACE),
double_quoted_arg: $ => seq(
'"',
repeat(choice(
@ -686,3 +678,10 @@ function noneOf(...characters) {
const negatedString = characters.map(c => c == '\\' ? '\\\\' : c).join('')
return new RegExp('[^' + negatedString + ']')
}
function argIdentifier(baseCharacters) {
return choice(
token(repeat1(baseCharacters)),
'$'
)
}

View file

@ -2486,11 +2486,11 @@
]
},
"_pf_dot_arg_identifier": {
"type": "TOKEN",
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "TOKEN",
"content": {
"type": "REPEAT1",
"content": {
"type": "CHOICE",
@ -2510,10 +2510,6 @@
"type": "STRING",
"value": "$$"
},
{
"type": "STRING",
"value": "$"
},
{
"type": "PATTERN",
"value": "\\$[^\\s@|#\"'>;`~\\\\({) ]"
@ -2529,8 +2525,12 @@
]
}
}
]
}
},
{
"type": "STRING",
"value": "$"
}
]
},
"_pf_arg_parentheses": {
"type": "SEQ",
@ -2560,11 +2560,11 @@
]
},
"pf_arg_identifier": {
"type": "TOKEN",
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "TOKEN",
"content": {
"type": "REPEAT1",
"content": {
"type": "CHOICE",
@ -2584,10 +2584,6 @@
"type": "STRING",
"value": "$$"
},
{
"type": "STRING",
"value": "$"
},
{
"type": "PATTERN",
"value": "\\$[^\\s@|#\"'>;`~\\\\({) ]"
@ -2603,8 +2599,12 @@
]
}
}
]
}
},
{
"type": "STRING",
"value": "$"
}
]
},
"_pf_arg": {
"type": "CHOICE",
@ -3567,88 +3567,98 @@
"value": "[^\\r\\n;~|]+"
},
"arg_identifier": {
"type": "TOKEN",
"content": {
"type": "REPEAT1",
"content": {
"type": "CHOICE",
"members": [
{
"type": "REPEAT1",
"content": {
"type": "PATTERN",
"value": "[^\\s@|#\"'>;$`~\\\\,()]"
}
},
{
"type": "STRING",
"value": "$$$"
},
{
"type": "STRING",
"value": "$$"
},
{
"type": "STRING",
"value": "$"
},
{
"type": "PATTERN",
"value": "\\$[^\\s@|#\"'>;`~\\\\({) ]"
},
{
"type": "PATTERN",
"value": "\\${[^\\r\\n $}]+}"
},
{
"type": "PATTERN",
"value": "\\\\."
"type": "CHOICE",
"members": [
{
"type": "TOKEN",
"content": {
"type": "REPEAT1",
"content": {
"type": "CHOICE",
"members": [
{
"type": "REPEAT1",
"content": {
"type": "PATTERN",
"value": "[^\\s@|#\"'>;$`~\\\\,()]"
}
},
{
"type": "STRING",
"value": "$$$"
},
{
"type": "STRING",
"value": "$$"
},
{
"type": "PATTERN",
"value": "\\$[^\\s@|#\"'>;`~\\\\({) ]"
},
{
"type": "PATTERN",
"value": "\\${[^\\r\\n $}]+}"
},
{
"type": "PATTERN",
"value": "\\\\."
}
]
}
]
}
},
{
"type": "STRING",
"value": "$"
}
}
]
},
"arg_identifier_brace": {
"type": "TOKEN",
"content": {
"type": "REPEAT1",
"content": {
"type": "CHOICE",
"members": [
{
"type": "REPEAT1",
"content": {
"type": "PATTERN",
"value": "[^\\s@|#\"'>;$`~\\\\,(){}]"
}
},
{
"type": "STRING",
"value": "$$$"
},
{
"type": "STRING",
"value": "$$"
},
{
"type": "STRING",
"value": "$"
},
{
"type": "PATTERN",
"value": "\\$[^\\s@|#\"'>;`~\\\\({) ]"
},
{
"type": "PATTERN",
"value": "\\${[^\\r\\n $}]+}"
},
{
"type": "PATTERN",
"value": "\\\\."
"type": "CHOICE",
"members": [
{
"type": "TOKEN",
"content": {
"type": "REPEAT1",
"content": {
"type": "CHOICE",
"members": [
{
"type": "REPEAT1",
"content": {
"type": "PATTERN",
"value": "[^\\s@|#\"'>;$`~\\\\,(){}]"
}
},
{
"type": "STRING",
"value": "$$$"
},
{
"type": "STRING",
"value": "$$"
},
{
"type": "PATTERN",
"value": "\\$[^\\s@|#\"'>;`~\\\\({) ]"
},
{
"type": "PATTERN",
"value": "\\${[^\\r\\n $}]+}"
},
{
"type": "PATTERN",
"value": "\\\\."
}
]
}
]
}
},
{
"type": "STRING",
"value": "$"
}
}
]
},
"double_quoted_arg": {
"type": "SEQ",

View file

@ -34,6 +34,11 @@
]
}
},
{
"type": "arg_identifier",
"named": true,
"fields": {}
},
{
"type": "arged_command",
"named": true,
@ -8892,6 +8897,11 @@
]
}
},
{
"type": "pf_arg_identifier",
"named": true,
"fields": {}
},
{
"type": "pf_args",
"named": true,
@ -13829,6 +13839,10 @@
"type": "\"",
"named": false
},
{
"type": "$",
"named": false
},
{
"type": "$(",
"named": false
@ -14073,10 +14087,6 @@
"type": "`",
"named": false
},
{
"type": "arg_identifier",
"named": true
},
{
"type": "env",
"named": false
@ -14097,10 +14107,6 @@
"type": "html_redirect_operator",
"named": true
},
{
"type": "pf_arg_identifier",
"named": true
},
{
"type": "pipe_second_command",
"named": true

File diff suppressed because it is too large Load diff