blob: 393e60eec0daa7c05a8a6cef50579e79ac6b6080 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
basic_escape_char = @{ "\\\\" | "\\'" }
escape_char = @{ "\\" ~ ANY }
bareword_char = @{
escape_char |
!("|" | ";" | "\"" | "'" | "$" | WHITESPACE | COMMENT) ~ ANY
}
single_string_char = @{ basic_escape_char | (!"'" ~ ANY) }
double_string_char = @{ escape_char | (!"\"" ~ ANY) }
redir_prefix = @{
("in" | "out" | "err" | ASCII_DIGIT*) ~ (">>" | ">" | "<") ~ WHITESPACE*
}
var = @{
("$" ~ XID_START ~ XID_CONTINUE*) |
("$" ~ ("?" | "$" | "*" | ASCII_DIGIT)) |
("${" ~ (!"}" ~ ANY)+ ~ "}")
}
bareword = @{ bareword_char+ }
single_string = @{ single_string_char+ }
double_string = @{ double_string_char+ }
word_part = ${
var |
bareword |
"'" ~ single_string ~ "'" |
"\"" ~ (var | double_string)+ ~ "\""
}
word = ${ word_part+ }
word_or_redirect = ${ redir_prefix? ~ word }
exe = ${ word_or_redirect ~ (w ~ word_or_redirect)* }
list = ${ word ~ (w ~ word)* }
pipeline = ${ exe ~ (w? ~ "|" ~ w? ~ exe)* }
control_if = ${ "if" ~ w ~ pipeline }
control_while = ${ "while" ~ w ~ pipeline }
control_for = ${ "for" ~ w ~ bareword ~ w ~ "in" ~ w ~ list }
control_end = ${ "end" }
control = ${ control_if | control_while | control_for | control_end }
command = ${ control | pipeline }
commands = ${ command ~ (w? ~ ";" ~ w? ~ command)* }
line = ${ SOI ~ w? ~ commands ~ w? ~ EOI }
w = _{ (WHITESPACE | COMMENT)+ }
WHITESPACE = _{ (" " | "\t" | "\n") }
COMMENT = _{ "#" ~ ANY* }
|