33// Whitespace and comments
44WHITESPACE = _{ " " | "\t" | ("\\" ~ WHITESPACE* ~ NEWLINE) }
55COMMENT = _{ "#" ~ (!NEWLINE ~ ANY)* }
6+ NUMBER = @{ INT ~ ("." ~ ASCII_DIGIT*)? ~ (^"e" ~ INT)? }
7+ INT = { ("+" | "-")? ~ ASCII_DIGIT+ }
68
79// Basic tokens
810QUOTED_WORD = { DOUBLE_QUOTED | SINGLE_QUOTED }
@@ -11,6 +13,7 @@ UNQUOTED_PENDING_WORD = ${
1113 (TILDE_PREFIX ~ (!(OPERATOR | WHITESPACE | NEWLINE) ~ (
1214 EXIT_STATUS |
1315 UNQUOTED_ESCAPE_CHAR |
16+ "$" ~ ARITHMETIC_EXPRESSION |
1417 SUB_COMMAND |
1518 ("$" ~ "{" ~ VARIABLE ~ "}" | "$" ~ VARIABLE) |
1619 UNQUOTED_CHAR |
@@ -20,6 +23,7 @@ UNQUOTED_PENDING_WORD = ${
2023 (!(OPERATOR | WHITESPACE | NEWLINE) ~ (
2124 EXIT_STATUS |
2225 UNQUOTED_ESCAPE_CHAR |
26+ "$" ~ ARITHMETIC_EXPRESSION |
2327 SUB_COMMAND |
2428 ("$" ~ "{" ~ VARIABLE ~ "}" | "$" ~ VARIABLE) |
2529 UNQUOTED_CHAR |
@@ -69,7 +73,7 @@ QUOTED_ESCAPE_CHAR = ${ "\\" ~ "$" | "$" ~ !"(" ~ !"{" ~ !VARIABLE | "\\" ~ ("`"
6973UNQUOTED_CHAR = ${ ("\\" ~ " ") | !("]]" | "[[" | "(" | ")" | "<" | ">" | "|" | "&" | ";" | "\"" | "'" | "$") ~ ANY }
7074QUOTED_CHAR = ${ !"\"" ~ ANY }
7175
72- VARIABLE = ${ (ASCII_ALPHANUMERIC | "_")+ }
76+ VARIABLE = ${ (ASCII_ALPHA | "_") ~ ( ASCII_ALPHANUMERIC | "_")* }
7377SUB_COMMAND = { "$(" ~ complete_command ~ ")"}
7478
7579DOUBLE_QUOTED = @{ "\"" ~ QUOTED_PENDING_WORD ~ "\"" }
@@ -148,6 +152,7 @@ command = !{
148152
149153compound_command = {
150154 brace_group |
155+ ARITHMETIC_EXPRESSION |
151156 subshell |
152157 for_clause |
153158 case_clause |
@@ -156,7 +161,86 @@ compound_command = {
156161 until_clause
157162}
158163
159- subshell = !{ "(" ~ compound_list ~ ")" }
164+ ARITHMETIC_EXPRESSION = !{ "((" ~ arithmetic_sequence ~ "))" }
165+ arithmetic_sequence = !{ arithmetic_expr ~ ("," ~ arithmetic_expr)* }
166+ arithmetic_expr = { parentheses_expr | variable_assignment | triple_conditional_expr | binary_arithmetic_expr | binary_conditional_expression | unary_arithmetic_expr | VARIABLE | NUMBER }
167+ parentheses_expr = !{ "(" ~ arithmetic_sequence ~ ")" }
168+
169+ variable_assignment = !{
170+ VARIABLE ~ assignment_operator ~ arithmetic_expr
171+ }
172+
173+ triple_conditional_expr = !{
174+ (parentheses_expr | variable_assignment | binary_arithmetic_expr | binary_conditional_expression | unary_arithmetic_expr | VARIABLE | NUMBER) ~
175+ "?" ~ (parentheses_expr | variable_assignment | binary_arithmetic_expr | binary_conditional_expression | unary_arithmetic_expr | VARIABLE | NUMBER) ~
176+ ":" ~ (parentheses_expr | variable_assignment | binary_arithmetic_expr | binary_conditional_expression | unary_arithmetic_expr | VARIABLE | NUMBER)
177+ }
178+
179+ binary_arithmetic_expr = _{
180+ (parentheses_expr | binary_conditional_expression | unary_arithmetic_expr | variable_assignment | VARIABLE | NUMBER) ~
181+ (binary_arithmetic_op ~
182+ (parentheses_expr | variable_assignment | binary_conditional_expression | unary_arithmetic_expr | VARIABLE | NUMBER)
183+ )+
184+ }
185+
186+ binary_arithmetic_op = _{
187+ add | subtract | power | multiply | divide | modulo | left_shift | right_shift |
188+ bitwise_and | bitwise_xor | bitwise_or | logical_and | logical_or
189+ }
190+
191+ add = { "+" }
192+ subtract = { "-" }
193+ multiply = { "*" }
194+ divide = { "/" }
195+ modulo = { "%" }
196+ power = { "**" }
197+ left_shift = { "<<" }
198+ right_shift = { ">>" }
199+ bitwise_and = { "&" }
200+ bitwise_xor = { "^" }
201+ bitwise_or = { "|" }
202+ logical_and = { "&&" }
203+ logical_or = { "||" }
204+
205+ unary_arithmetic_expr = !{
206+ (unary_arithmetic_op | post_arithmetic_op) ~ (parentheses_expr | VARIABLE | NUMBER) |
207+ (parentheses_expr | VARIABLE | NUMBER) ~ post_arithmetic_op
208+ }
209+
210+ unary_arithmetic_op = _{
211+ unary_plus | unary_minus | logical_not | bitwise_not
212+ }
213+
214+ unary_plus = { "+" }
215+ unary_minus = { "-" }
216+ logical_not = { "!" }
217+ bitwise_not = { "~" }
218+
219+ post_arithmetic_op = !{
220+ increment | decrement
221+ }
222+
223+ increment = { "++" }
224+ decrement = { "--" }
225+
226+ assignment_operator = _{
227+ assign | multiply_assign | divide_assign | modulo_assign | add_assign | subtract_assign |
228+ left_shift_assign | right_shift_assign | bitwise_and_assign | bitwise_xor_assign | bitwise_or_assign
229+ }
230+
231+ assign = { "=" }
232+ multiply_assign = { "*=" }
233+ divide_assign = { "/=" }
234+ modulo_assign = { "%=" }
235+ add_assign = { "+=" }
236+ subtract_assign = { "-=" }
237+ left_shift_assign = { "<<=" }
238+ right_shift_assign = { ">>=" }
239+ bitwise_and_assign = { "&=" }
240+ bitwise_xor_assign = { "^=" }
241+ bitwise_or_assign = { "|=" }
242+
243+ subshell = !{ "(" ~ compound_list ~ ")" }
160244compound_list = !{ (newline_list? ~ term ~ separator?)+ }
161245term = !{ and_or ~ (separator ~ and_or)* }
162246
@@ -232,16 +316,16 @@ string_conditional_op = !{
232316
233317binary_conditional_expression = !{
234318 UNQUOTED_PENDING_WORD ~ (
235- binary_string_conditional_op |
236- binary_arithmetic_conditional_op
319+ binary_bash_conditional_op |
320+ binary_posix_conditional_op
237321 ) ~ UNQUOTED_PENDING_WORD
238322}
239323
240- binary_string_conditional_op = !{
324+ binary_bash_conditional_op = !{
241325 "==" | "=" | "!=" | "<" | ">"
242326}
243327
244- binary_arithmetic_conditional_op = !{
328+ binary_posix_conditional_op = !{
245329 "-eq" | "-ne" | "-lt" | "-le" | "-gt" | "-ge"
246330}
247331
0 commit comments