Add process substitutions

This commit is contained in:
Max Brunsfeld 2017-07-15 22:22:38 -07:00
parent 1b5e1557f2
commit 5081293f65
4 changed files with 26053 additions and 17422 deletions

View File

@ -71,6 +71,28 @@ echo $(echo $(echo hi))
(command_name) (command_name)
(word))))))) (word)))))))
=============================
Process substitutions
=============================
wc -c <(echo abc && echo def)
echo abc > >(wc -c)
---
(program
(command
(command_name)
(word)
(process_substitution (list
(command (command_name) (word))
(command (command_name) (word)))))
(command
(command_name)
(word)
(file_redirect (process_substitution
(command (command_name) (word))))))
============================= =============================
Single quoted strings Single quoted strings
============================= =============================

View File

@ -207,7 +207,8 @@ module.exports = grammar({
$.raw_string, $.raw_string,
$.expansion, $.expansion,
$.simple_expansion, $.simple_expansion,
$.command_substitution $.command_substitution,
$.process_substitution
), ),
string: $ => seq( string: $ => seq(
@ -251,6 +252,13 @@ module.exports = grammar({
seq('`', $.command, '`') seq('`', $.command, '`')
), ),
process_substitution: $ => seq(
choice('<', '>'),
'(',
$.statement,
')'
),
leading_word: $ => /[^`"\\\s#=|;:{}()]+/, leading_word: $ => /[^`"\\\s#=|;:{}()]+/,
word: $ => /[^"`#\\\s$<>{}&;()]+/, word: $ => /[^"`#\\\s$<>{}&;()]+/,

392
src/grammar.json vendored
View File

@ -344,6 +344,86 @@
} }
] ]
}, },
"subshell": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "REPEAT",
"content": {
"type": "SYMBOL",
"name": "_terminated_statement"
}
},
{
"type": "STRING",
"value": ")"
}
]
},
"pipeline": {
"type": "PREC_LEFT",
"value": 1,
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "statement"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "|"
},
{
"type": "STRING",
"value": "|&"
}
]
},
{
"type": "SYMBOL",
"name": "statement"
}
]
}
},
"list": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "statement"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "&&"
},
{
"type": "STRING",
"value": "||"
}
]
},
{
"type": "SYMBOL",
"name": "statement"
}
]
}
},
"bracket_command": { "bracket_command": {
"type": "CHOICE", "type": "CHOICE",
"members": [ "members": [
@ -488,86 +568,6 @@
] ]
} }
}, },
"pipeline": {
"type": "PREC_LEFT",
"value": 1,
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "statement"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "|"
},
{
"type": "STRING",
"value": "|&"
}
]
},
{
"type": "SYMBOL",
"name": "statement"
}
]
}
},
"list": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "statement"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "&&"
},
{
"type": "STRING",
"value": "||"
}
]
},
{
"type": "SYMBOL",
"name": "statement"
}
]
}
},
"subshell": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "REPEAT",
"content": {
"type": "SYMBOL",
"name": "_terminated_statement"
}
},
{
"type": "STRING",
"value": ")"
}
]
},
"environment_variable_assignment": { "environment_variable_assignment": {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
@ -598,6 +598,124 @@
} }
] ]
}, },
"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": "STRING",
"value": "&>>"
},
{
"type": "STRING",
"value": "<&"
},
{
"type": "STRING",
"value": ">&"
}
]
},
{
"type": "SYMBOL",
"name": "expression"
}
]
},
"heredoc_redirect": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "<<"
},
{
"type": "STRING",
"value": "<<-"
}
]
},
{
"type": "SYMBOL",
"name": "heredoc"
}
]
},
"heredoc": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_simple_heredoc"
},
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_heredoc_beginning"
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "expansion"
},
{
"type": "SYMBOL",
"name": "simple_expansion"
},
{
"type": "SYMBOL",
"name": "_heredoc_middle"
}
]
}
},
{
"type": "SYMBOL",
"name": "_heredoc_end"
}
]
}
]
},
"expression": { "expression": {
"type": "CHOICE", "type": "CHOICE",
"members": [ "members": [
@ -624,6 +742,10 @@
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "command_substitution" "name": "command_substitution"
},
{
"type": "SYMBOL",
"name": "process_substitution"
} }
] ]
}, },
@ -640,8 +762,8 @@
"type": "CHOICE", "type": "CHOICE",
"members": [ "members": [
{ {
"type": "SYMBOL", "type": "PATTERN",
"name": "_quoted_chars" "value": "[^\"$]+"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
@ -664,10 +786,6 @@
} }
] ]
}, },
"_quoted_chars": {
"type": "PATTERN",
"value": "[^\"$]+"
},
"raw_string": { "raw_string": {
"type": "PATTERN", "type": "PATTERN",
"value": "'[^']*'" "value": "'[^']*'"
@ -809,21 +927,9 @@
} }
] ]
}, },
"file_redirect": { "process_substitution": {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "file_descriptor"
},
{
"type": "BLANK"
}
]
},
{ {
"type": "CHOICE", "type": "CHOICE",
"members": [ "members": [
@ -834,96 +940,20 @@
{ {
"type": "STRING", "type": "STRING",
"value": ">" "value": ">"
},
{
"type": "STRING",
"value": ">>"
},
{
"type": "STRING",
"value": "&>"
},
{
"type": "STRING",
"value": "&>>"
},
{
"type": "STRING",
"value": "<&"
},
{
"type": "STRING",
"value": ">&"
} }
] ]
}, },
{
"type": "SYMBOL",
"name": "expression"
}
]
},
"heredoc_redirect": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{ {
"type": "STRING", "type": "STRING",
"value": "<<" "value": "("
},
{
"type": "SYMBOL",
"name": "statement"
}, },
{ {
"type": "STRING", "type": "STRING",
"value": "<<-" "value": ")"
}
]
},
{
"type": "SYMBOL",
"name": "heredoc"
}
]
},
"heredoc": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_simple_heredoc"
},
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_heredoc_beginning"
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "expansion"
},
{
"type": "SYMBOL",
"name": "simple_expansion"
},
{
"type": "SYMBOL",
"name": "_heredoc_middle"
}
]
}
},
{
"type": "SYMBOL",
"name": "_heredoc_end"
}
]
} }
] ]
}, },

43053
src/parser.c vendored

File diff suppressed because it is too large Load Diff