Add while statements
This commit is contained in:
parent
dc84753599
commit
cce4a65d33
|
@ -7,7 +7,7 @@ whoami
|
|||
---
|
||||
|
||||
(program
|
||||
(command (simple_command (command_name))))
|
||||
(command (command_name)))
|
||||
|
||||
===============================
|
||||
Commands with arguments
|
||||
|
@ -19,8 +19,8 @@ cat -n file1.txt file2.txt
|
|||
---
|
||||
|
||||
(program
|
||||
(command (simple_command (command_name) (argument)))
|
||||
(command (simple_command (command_name) (argument) (argument) (argument))))
|
||||
(command (command_name) (argument))
|
||||
(command (command_name) (argument) (argument) (argument)))
|
||||
|
||||
===================================
|
||||
Commands with environment variables
|
||||
|
@ -32,15 +32,15 @@ VAR1=a VAR2="ok" git diff --word-diff=color
|
|||
---
|
||||
|
||||
(program
|
||||
(command (simple_command
|
||||
(command
|
||||
(environment_variable_assignment (variable_name) (argument))
|
||||
(command_name)))
|
||||
(command (simple_command
|
||||
(command_name))
|
||||
(command
|
||||
(environment_variable_assignment (variable_name) (argument))
|
||||
(environment_variable_assignment (variable_name) (argument))
|
||||
(command_name)
|
||||
(argument)
|
||||
(argument))))
|
||||
(argument)))
|
||||
|
||||
===================================
|
||||
Pipelines
|
||||
|
@ -52,31 +52,32 @@ cat foo | grep -v bar
|
|||
---
|
||||
|
||||
(program
|
||||
(command (pipeline
|
||||
(simple_command (command_name))
|
||||
(simple_command (command_name))))
|
||||
(command (pipeline
|
||||
(simple_command (command_name) (argument))
|
||||
(simple_command (command_name) (argument) (argument)))))
|
||||
(pipeline
|
||||
(command (command_name))
|
||||
(command (command_name)))
|
||||
(pipeline
|
||||
(command (command_name) (argument))
|
||||
(command (command_name) (argument) (argument))))
|
||||
|
||||
===================================
|
||||
Lists
|
||||
===================================
|
||||
|
||||
a | b && c; d e f | e g
|
||||
a | b && c && d; d e f || e g
|
||||
|
||||
---
|
||||
|
||||
(program
|
||||
(command (list
|
||||
(list
|
||||
(list
|
||||
(pipeline
|
||||
(simple_command (command_name))
|
||||
(simple_command (command_name)))
|
||||
(simple_command (command_name)))
|
||||
(pipeline
|
||||
(simple_command (command_name) (argument) (argument))
|
||||
(simple_command (command_name) (argument))))))
|
||||
(command (command_name))
|
||||
(command (command_name)))
|
||||
(command (command_name)))
|
||||
(command (command_name)))
|
||||
(list
|
||||
(command (command_name) (argument) (argument))
|
||||
(command (command_name) (argument))))
|
||||
|
||||
===============================
|
||||
File redirects
|
||||
|
@ -89,17 +90,45 @@ cat a b 2> /dev/null
|
|||
---
|
||||
|
||||
(program
|
||||
(command (simple_command
|
||||
(command
|
||||
(command_name)
|
||||
(file_redirect (file_name))))
|
||||
(command (simple_command
|
||||
(file_redirect (file_name)))
|
||||
(command
|
||||
(command_name)
|
||||
(argument)
|
||||
(argument)
|
||||
(file_redirect (file_descriptor) (file_name))))
|
||||
(command (simple_command
|
||||
(file_redirect (file_descriptor) (file_name)))
|
||||
(command
|
||||
(file_redirect (file_descriptor) (file_descriptor))
|
||||
(command_name))))
|
||||
(command_name)))
|
||||
|
||||
===============================
|
||||
Variable expansions
|
||||
===============================
|
||||
|
||||
cat $FOO
|
||||
|
||||
---
|
||||
|
||||
(program
|
||||
(command
|
||||
(command_name)
|
||||
(expansion (variable_name))))
|
||||
|
||||
===============================
|
||||
Variable expansion operators
|
||||
===============================
|
||||
|
||||
cat ${BAR} ${ABC=def} ${GHI:?jkl}
|
||||
|
||||
---
|
||||
|
||||
(program
|
||||
(command
|
||||
(command_name)
|
||||
(operator_expansion (variable_name))
|
||||
(operator_expansion (variable_name) (argument))
|
||||
(operator_expansion (variable_name) (argument))))
|
||||
|
||||
===============================
|
||||
Heredoc redirects
|
||||
|
@ -116,13 +145,13 @@ JS
|
|||
---
|
||||
|
||||
(program
|
||||
(command (simple_command
|
||||
(command
|
||||
(command_name)
|
||||
(heredoc_redirect (heredoc))))
|
||||
(command (simple_command
|
||||
(heredoc_redirect (heredoc)))
|
||||
(command
|
||||
(command_name)
|
||||
(argument)
|
||||
(heredoc_redirect (heredoc)))))
|
||||
(heredoc_redirect (heredoc))))
|
||||
|
||||
===============================
|
||||
Heredocs with variables
|
||||
|
@ -137,37 +166,9 @@ exit
|
|||
---
|
||||
|
||||
(program
|
||||
(command (simple_command
|
||||
(command
|
||||
(command_name)
|
||||
(heredoc_redirect (heredoc
|
||||
(expansion (variable_name))
|
||||
(operator_expansion (variable_name))))))
|
||||
(command (simple_command (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)))))
|
||||
(operator_expansion (variable_name)))))
|
||||
(command (command_name)))
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
====================================
|
||||
While statements
|
||||
====================================
|
||||
|
||||
while something happens; do
|
||||
echo a
|
||||
echo b
|
||||
done
|
||||
|
||||
---
|
||||
|
||||
(program
|
||||
(while_statement
|
||||
(command (command_name) (argument))
|
||||
(do_group
|
||||
(command (command_name) (argument))
|
||||
(command (command_name) (argument)))))
|
|
@ -27,11 +27,11 @@ f=g \
|
|||
---
|
||||
|
||||
(program
|
||||
(command (simple_command
|
||||
(command
|
||||
(command_name)
|
||||
(argument)
|
||||
(argument)))
|
||||
(command (simple_command
|
||||
(argument))
|
||||
(command
|
||||
(environment_variable_assignment
|
||||
(variable_name)
|
||||
(argument))
|
||||
|
@ -39,4 +39,4 @@ f=g \
|
|||
(variable_name)
|
||||
(argument))
|
||||
(command_name)
|
||||
(argument))))
|
||||
(argument)))
|
||||
|
|
55
grammar.js
55
grammar.js
|
@ -1,7 +1,7 @@
|
|||
module.exports = grammar({
|
||||
name: 'bash',
|
||||
|
||||
inline: $ => [$.control_operator],
|
||||
inline: $ => [$.statement],
|
||||
|
||||
externals: $ => [
|
||||
$._simple_heredoc,
|
||||
|
@ -16,18 +16,33 @@ module.exports = grammar({
|
|||
],
|
||||
|
||||
rules: {
|
||||
program: $ => repeat($.command),
|
||||
program: $ => repeat($._terminated_statement),
|
||||
|
||||
command: $ => seq(
|
||||
choice(
|
||||
$.simple_command,
|
||||
_terminated_statement: $ => seq(
|
||||
$.statement,
|
||||
choice(';', ';;', '\n')
|
||||
),
|
||||
|
||||
statement: $ => choice(
|
||||
$.command,
|
||||
$.while_statement,
|
||||
$.pipeline,
|
||||
$.list
|
||||
),
|
||||
$.control_operator
|
||||
|
||||
while_statement: $ => seq(
|
||||
'while',
|
||||
$._terminated_statement,
|
||||
$.do_group
|
||||
),
|
||||
|
||||
simple_command: $ => seq(
|
||||
do_group: $ => seq(
|
||||
'do',
|
||||
repeat($._terminated_statement),
|
||||
'done'
|
||||
),
|
||||
|
||||
command: $ => seq(
|
||||
repeat(choice(
|
||||
$.environment_variable_assignment,
|
||||
$.file_redirect
|
||||
|
@ -47,23 +62,16 @@ module.exports = grammar({
|
|||
))
|
||||
),
|
||||
|
||||
pipeline: $ => prec.left(seq(
|
||||
$.simple_command,
|
||||
pipeline: $ => prec.left(1, seq(
|
||||
$.statement,
|
||||
choice('|', '|&'),
|
||||
$.simple_command
|
||||
$.statement
|
||||
)),
|
||||
|
||||
list: $ => prec.left(seq(
|
||||
choice(
|
||||
$.simple_command,
|
||||
$.list,
|
||||
$.pipeline
|
||||
),
|
||||
choice('&&', ';'),
|
||||
choice(
|
||||
$.simple_command,
|
||||
$.pipeline
|
||||
)
|
||||
$.statement,
|
||||
choice('&&', '||'),
|
||||
$.statement
|
||||
)),
|
||||
|
||||
environment_variable_assignment: $ => seq(
|
||||
|
@ -118,12 +126,7 @@ module.exports = grammar({
|
|||
|
||||
leading_word: $ => /[^\\\s#=|;:{}]+/,
|
||||
|
||||
word: $ => /[^#\\\s$<>{}&]+/,
|
||||
|
||||
control_operator: $ => choice(
|
||||
'\n',
|
||||
';;'
|
||||
),
|
||||
word: $ => /[^#\\\s$<>{}&;]+/,
|
||||
|
||||
comment: $ => /#.*/,
|
||||
}
|
||||
|
|
119
src/grammar.json
119
src/grammar.json
|
@ -5,18 +5,45 @@
|
|||
"type": "REPEAT",
|
||||
"content": {
|
||||
"type": "SYMBOL",
|
||||
"name": "command"
|
||||
"name": "_terminated_statement"
|
||||
}
|
||||
},
|
||||
"command": {
|
||||
"_terminated_statement": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "statement"
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": ";"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": ";;"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "\n"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"statement": {
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "simple_command"
|
||||
"name": "command"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "while_statement"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
|
@ -28,13 +55,44 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"while_statement": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "while"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "control_operator"
|
||||
"name": "_terminated_statement"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "do_group"
|
||||
}
|
||||
]
|
||||
},
|
||||
"simple_command": {
|
||||
"do_group": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "do"
|
||||
},
|
||||
{
|
||||
"type": "REPEAT",
|
||||
"content": {
|
||||
"type": "SYMBOL",
|
||||
"name": "_terminated_statement"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "done"
|
||||
}
|
||||
]
|
||||
},
|
||||
"command": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
|
@ -122,13 +180,13 @@
|
|||
},
|
||||
"pipeline": {
|
||||
"type": "PREC_LEFT",
|
||||
"value": 0,
|
||||
"value": 1,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "simple_command"
|
||||
"name": "statement"
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
|
@ -145,7 +203,7 @@
|
|||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "simple_command"
|
||||
"name": "statement"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -155,23 +213,10 @@
|
|||
"value": 0,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "simple_command"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "list"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "pipeline"
|
||||
}
|
||||
]
|
||||
"name": "statement"
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
|
@ -182,22 +227,13 @@
|
|||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": ";"
|
||||
"value": "||"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "simple_command"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "pipeline"
|
||||
}
|
||||
]
|
||||
"name": "statement"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -439,20 +475,7 @@
|
|||
},
|
||||
"word": {
|
||||
"type": "PATTERN",
|
||||
"value": "[^#\\\\\\s$<>{}&]+"
|
||||
},
|
||||
"control_operator": {
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "\n"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": ";;"
|
||||
}
|
||||
]
|
||||
"value": "[^#\\\\\\s$<>{}&;]+"
|
||||
},
|
||||
"comment": {
|
||||
"type": "PATTERN",
|
||||
|
@ -501,6 +524,6 @@
|
|||
}
|
||||
],
|
||||
"inline": [
|
||||
"control_operator"
|
||||
"statement"
|
||||
]
|
||||
}
|
3975
src/parser.c
3975
src/parser.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue