-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgrammar.ebnf
53 lines (42 loc) · 1.79 KB
/
grammar.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
(* simple grammar. ignores string escapes *)
(* if we wanted explicit argument names (I'm not sure about yet) just do *)
(* arguments -> '(' [argument {',' argument}] ')' *)
(* argument -> expression | declare *)
program = {statement};
statement = assign | declare | break | continue | return | assert | block | if
| while | for | fn | expression | data;
assign = [ call, '.' ], ident, assign_op, expression;
declare = ident, '=:', expression;
break = 'break';
continue = 'continue';
return = 'return', [expression];
assert = 'assert', expression;
block = 'do', {statement}, 'end';
if = 'if', expression, 'do', {statement},
{'elseif', expression, 'do', {statement}},
['else', {statement}], 'end';
while = 'while', expression, block;
for = 'for', declare, ',', expression, ',', assign, block;
fn = 'fn', ident, '(', parameters, ')', block;
data = 'data', ident, 'do', {declare}, {fn}, 'end';
expression = logic_or;
logic_or = logic_and, {'||', logic_and};
logic_and = bit_or, {'&&', bit_or};
bit_or = bit_xor, {'|', bit_xor};
bit_xor = bit_and, {'^', bit_and};
bit_and = equality, {'&', equality};
equality = comparison, {('!=' | '=='), comparison};
comparison = bit_shift, {('>' | '>=' | '<' | '<='), bit_shift};
bit_shift = term, {('>>' | '<<'), term};
term = factor, {('+' | '-'), factor};
factor = unary, {('*' | '/'), unary};
unary = ('!' | '-'), unary | call;
call = primary, {arguments | ('.', ident)};
primary = ('(', expression, ')') | 'true' | 'false' | 'nil' | 'me' | number | string | ident;
arguments = '(', [expression, {',', expression}], ')';
parameters = '(', [ident, {',', ident}], ')';
anon_fn = 'fn', parameters, block;
assign_op = '=' | '+=' | '-=' | '/=' | '*=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=';
ident = /NON_WHITESPACE+/;
number = /INTEGER(.INTEGER)?/;
string = /".*"/;