From 142b9db16f007ebbc8fb51deb03d0ac513738c69 Mon Sep 17 00:00:00 2001
From: prsabahrami
Date: Sat, 7 Sep 2024 18:08:06 -0400
Subject: [PATCH] Complex commands parsing fix
---
crates/deno_task_shell/src/grammar.pest | 38 +++++++++++++------------
crates/deno_task_shell/src/parser.rs | 2 --
scripts/for_loop.sh | 23 +++++++++++++++
scripts/if_else.sh | 5 ++++
scripts/while_loop.sh | 5 ++++
5 files changed, 53 insertions(+), 20 deletions(-)
create mode 100644 scripts/for_loop.sh
create mode 100644 scripts/if_else.sh
create mode 100644 scripts/while_loop.sh
diff --git a/crates/deno_task_shell/src/grammar.pest b/crates/deno_task_shell/src/grammar.pest
index 600cedd..0b270ee 100644
--- a/crates/deno_task_shell/src/grammar.pest
+++ b/crates/deno_task_shell/src/grammar.pest
@@ -7,12 +7,12 @@ COMMENT = _{ "#" ~ (!NEWLINE ~ ANY)* }
// Basic tokens
QUOTED_WORD = { DOUBLE_QUOTED | SINGLE_QUOTED }
-UNQUOTED_PENDING_WORD = ${
- (!(WHITESPACE | OPERATOR | NEWLINE) ~ (
+UNQUOTED_PENDING_WORD = ${ !OPERATOR ~
+ (!(WHITESPACE | NEWLINE) ~ (
EXIT_STATUS |
UNQUOTED_ESCAPE_CHAR |
SUB_COMMAND |
- ("$" ~ VARIABLE) |
+ ("$" ~ "{" ~ VARIABLE ~ "}" | "$" ~ VARIABLE) |
UNQUOTED_CHAR |
QUOTED_WORD
)
@@ -24,18 +24,18 @@ QUOTED_PENDING_WORD = ${ (
EXIT_STATUS |
QUOTED_ESCAPE_CHAR |
SUB_COMMAND |
- ("$" ~ VARIABLE) |
+ ("$" ~ "{" ~ VARIABLE ~ "}" | "$" ~ VARIABLE) |
QUOTED_CHAR
)* }
-UNQUOTED_ESCAPE_CHAR = ${ ("\\" ~ "$" | "$" ~ !"(" ~ !VARIABLE) | "\\" ~ (" " | "`" | "\"" | "(" | ")")* }
-QUOTED_ESCAPE_CHAR = ${ "\\" ~ "$" | "$" ~ !"(" ~ !VARIABLE | "\\" ~ ("`" | "\"" | "(" | ")" | "'")* }
+UNQUOTED_ESCAPE_CHAR = ${ ("\\" ~ "$" | "$" ~ !"(" ~ !"{" ~ !VARIABLE) | "\\" ~ (" " | "`" | "\"" | "(" | ")")* }
+QUOTED_ESCAPE_CHAR = ${ "\\" ~ "$" | "$" ~ !"(" ~ !"{" ~ !VARIABLE | "\\" ~ ("`" | "\"" | "(" | ")" | "'")* }
-UNQUOTED_CHAR = ${ ("\\" ~ " ") | !("(" | ")" | "{" | "}" | "<" | ">" | "|" | "&" | ";" | "\"" | "'" | "$") ~ ANY }
+UNQUOTED_CHAR = ${ ("\\" ~ " ") | !("]]" | "[[" | "(" | ")" | "<" | ">" | "|" | "&" | ";" | "\"" | "'" | "$") ~ ANY }
QUOTED_CHAR = ${ !"\"" ~ ANY }
VARIABLE = ${ (ASCII_ALPHANUMERIC | "_")+ }
-SUB_COMMAND = { "$(" ~ complete_command ~ ")" }
+SUB_COMMAND = { "$(" ~ complete_command ~ ")"}
DOUBLE_QUOTED = @{ "\"" ~ QUOTED_PENDING_WORD ~ "\"" }
SINGLE_QUOTED = @{ "'" ~ (!"'" ~ ANY)* ~ "'" }
@@ -64,7 +64,7 @@ EXIT_STATUS = ${ "$?" }
// Operators
OPERATOR = _{
AND_IF | OR_IF | DSEMI | DLESS | DGREAT | LESSAND | GREATAND | LESSGREAT | DLESSDASH | CLOBBER |
- "(" | ")" | "{" | "}" | ";" | "&" | "|" | "<" | ">"
+ "," |"(" | ")" | "{" | "}" | ";" | "&" | "|" | "<" | ">"
}
// Reserved words
@@ -102,12 +102,13 @@ pipeline = !{ Bang? ~ pipe_sequence }
pipe_sequence = !{ command ~ ((StdoutStderr | Stdout) ~ linebreak ~ pipe_sequence)? }
command = !{
- simple_command |
compound_command ~ redirect_list? |
+ simple_command |
function_definition
}
compound_command = {
+ double_square_bracket |
brace_group |
subshell |
for_clause |
@@ -123,10 +124,12 @@ term = !{ and_or ~ (separator ~ and_or)* }
for_clause = {
For ~ name ~ linebreak ~
- (linebreak ~ In ~ wordlist? ~ sequential_sep)? ~
- linebreak ~ do_group
+ (In ~ (brace_group | wordlist)? ~ sequential_sep)? ~
+ do_group
}
+double_square_bracket = !{ "[[" ~ compound_list ~ "]]" }
+
case_clause = !{
Case ~ UNQUOTED_PENDING_WORD ~ linebreak ~
linebreak ~ In ~ linebreak ~
@@ -156,14 +159,13 @@ pattern = !{
if_clause = !{
If ~ compound_list ~
- Then ~ compound_list ~
- else_part? ~
- Fi
+ linebreak ~ Then ~ linebreak ~ compound_list ~ linebreak ~
+ else_part? ~ linebreak ~ Fi
}
else_part = !{
- Elif ~ compound_list ~ Then ~ else_part |
- Else ~ compound_list
+ Elif ~ compound_list ~ Then ~ linebreak ~ else_part |
+ Else ~ linebreak ~ compound_list
}
while_clause = !{ While ~ compound_list ~ do_group }
@@ -185,7 +187,7 @@ simple_command = !{
cmd_prefix = !{ (io_redirect | ASSIGNMENT_WORD)+ }
cmd_suffix = !{ (io_redirect | UNQUOTED_PENDING_WORD)+ }
-cmd_name = @{ (RESERVED_WORD | UNQUOTED_PENDING_WORD) }
+cmd_name = @{ !RESERVED_WORD ~ UNQUOTED_PENDING_WORD }
cmd_word = @{ (ASSIGNMENT_WORD | UNQUOTED_PENDING_WORD) }
redirect_list = !{ io_redirect+ }
diff --git a/crates/deno_task_shell/src/parser.rs b/crates/deno_task_shell/src/parser.rs
index 27919df..53aebb2 100644
--- a/crates/deno_task_shell/src/parser.rs
+++ b/crates/deno_task_shell/src/parser.rs
@@ -332,8 +332,6 @@ struct ShellParser;
pub fn parse(input: &str) -> Result {
let mut pairs = ShellParser::parse(Rule::FILE, input)?;
- // println!("pairs: {:?}", pairs);
-
parse_file(pairs.next().unwrap())
}
diff --git a/scripts/for_loop.sh b/scripts/for_loop.sh
new file mode 100644
index 0000000..9174943
--- /dev/null
+++ b/scripts/for_loop.sh
@@ -0,0 +1,23 @@
+# for i in {1..10}; do
+# echo $i
+# done
+
+
+for i in $(seq 1 2 20); do
+ echo $i
+done
+
+
+# for i in {1..10..2}; do
+# echo $i
+# done
+
+
+# for i in $(1,2,3,4,5); do
+# echo $i
+# done
+
+
+for i in $(ls); do
+ printf "%s\n" "$i"
+done
\ No newline at end of file
diff --git a/scripts/if_else.sh b/scripts/if_else.sh
new file mode 100644
index 0000000..eaa9fa9
--- /dev/null
+++ b/scripts/if_else.sh
@@ -0,0 +1,5 @@
+if [[ $FOO == "bar" ]] then
+ echo "FOO is bar"
+else
+ echo "FOO is not bar"
+fi
\ No newline at end of file
diff --git a/scripts/while_loop.sh b/scripts/while_loop.sh
new file mode 100644
index 0000000..eb0a5ea
--- /dev/null
+++ b/scripts/while_loop.sh
@@ -0,0 +1,5 @@
+COUNTER=-5
+while [[ $COUNTER -lt 5 ]]; do
+ echo The counter is $COUNTER
+ let COUNTER=COUNTER+1
+done
\ No newline at end of file