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