forked from madlambda/nash
-
Notifications
You must be signed in to change notification settings - Fork 0
/
spec.ebnf
104 lines (81 loc) · 3.37 KB
/
spec.ebnf
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/* Nash program */
program = { statement } .
/* Statement */
statement = varDecl | command | fnInv | builtin | comment .
/* Variable declaration */
varDecl = assignValue | assignCmdOut .
assignValue = identifierList "=" varSpecList .
identifierList = identifier [ "," identifierList ] .
varSpecList = varSpec [ "," varSpecList ] .
varSpec = ( list | string ) .
string = stringLit | ( stringConcat { stringConcat } ) .
assignCmdOut = identifier "<=" ( command | fnInv ) .
/* Command */
command = ( [ "(" ] cmdpart [ ")" ] | pipe ) .
cmdpart = [ "-" ] ( cmdname | abscmd ) { argument } { redirect } .
cmdname = identifier .
abscmd = filename .
argument = ( unicode_char { unicode_char } ) | stringLit .
pipe = [ "(" ] cmdpart "|" cmdpart [ { "|" cmdpart } ] [ ")" ] .
redirect = ( ">" ( filename | uri | variable ) |
">" "[" unicode_digit "]" ( filename | uri | variable ) |
">" "[" unicode_digit "=" ( unicode_digit | identifier ) "]" |
">" "[" unicode_digit "=" "]" ) .
/* Builtin */
builtin = importDecl | rforkDecl | ifDecl | forDecl | setenvDecl |
fnDecl | bindfn | dump .
/* Import statement */
importDecl = "import" ( filename | stringLit ) .
/* Rfork scope */
rforkDecl = "rfork" rforkFlags "{" program "}" .
rforkFlags = { identifier } .
/* If-else-if */
ifDecl = "if" ( variable | string ) comparison
( variable | string ) "{" program "}"
[ "else" "{" program "}" ]
[ "else" ifDecl ] .
/* For loop */
forDecl = "for" [ identifier "in" ( list | variable | fnInv) ] "{" program "}" .
/* Function declaration */
fnDecl = "fn" identifier "(" fnArgs ")" "{"
program [ returnDecl ]
"}" .
fnArgs = { fnArg [ "," ] } .
fnArg = identifier [ "..." ] .
/* return declaration */
returnDecl = "return" [ ( variable | stringLit | list | fnInv ) ] .
/* Function invocation */
fnInv = ( variable | identifier ) "(" fnArgValues ")" .
fnArgValues = { fnArgValue [ "," ] } .
fnArgValue = [ stringLit | stringConcat | list | (variable [ "..." ]) | (list [ "..." ]) fnInv ] .
/* Function binding */
bindfn = "bindfn" identifier identifier .
/* dump shell state */
dump = "dump" [ filename ] .
/* Set environment variable */
setenvDecl = "setenv" ( identifier | varDecl ) .
/* Comment */
comment = "#" { unicode_char } .
/* Lists */
list = "(" { argument } ")" .
letter = unicode_letter | "_" .
filename = { [ "/" ] { unicode_letter } } .
ipaddr = unicode_digit { unicode_digit } "."
unicode_digit { unicode_digit } "."
unicode_digit { unicode_digit } "."
unicode_digit { unicode_digit } "." .
port = unicode_digit { unicode_digit } .
networkaddr = ipaddr ":" port .
location = filename | networkaddr .
schema = "file" | "tcp" | "udp" | "unix" .
uri = schema "://" location .
identifier = letter { letter | unicode_digit } .
variable = "$" identifier .
comparison = "==" | "!=" .
stringLit = "\"" { unicode_char | newline } "\"" .
stringConcat = ( stringLit | variable ) "+" (stringLit | variable ) .
/* terminals */
newline = /* the Unicode code point U+000A */ .
unicode_char = /* an arbitrary Unicode code point except newline */ .
unicode_letter = /* a Unicode code point classified as "Letter" */ .
unicode_digit = /* a Unicode code point classified as "Number, decimal digit" */ .