-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgrammar.ebnf
109 lines (87 loc) · 2.66 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
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
105
106
107
108
109
(* JACKAL formal grammar by spsandwichman
all words in UPPERCASE are jackal keywords.
{} indicates repetition (0 or more)
[] indicates optionals (0 or 1)
() indicates grouping
things like "ident" and "literal" are not defined here but are assumed to exist
some things like nested function decls, PUBLIC/EXPORT declarations in functions, etc.
will be parsed as valid but eliminated during a semantic analysis phase.
*)
(* comma-separated list with optional trailing comma *)
list<X> = [X {"," X} [","]]
file = {decl}
storageclass = PUBLIC | PRIVATE | EXPORT
decl =
| [storageclass] ident ":" type ["=" (expr | compoundexpr)]
| [storageclass] ident ":" "=" (expr | compoundexpr)
| [storageclass] fndecl
| EXTERN ident ":" type (* EXTERN parses differently so it cant go in storageclass *)
| EXTERN FN fnproto
| typedecl
fnproto = ["(" type ")"] ident "(" list<param> ")" [":" type]
fndecl = FN fnproto {stmt} END
typedecl =
| STRUCT [PACKED] ident list<field> END
| UNION ident list<field> END
| ENUM ident ":" type list<variant> END
| TYPE ident ":" type
| FNPTR fnproto
param = (IN | OUT) field | "..." ident ident (* fn and fnptr *)
field = ident ":" type (* structs and unions *)
variant = ident | ident "=" expr (* enums *)
assignop =
| "="
| "+=" | "-=" | "*=" | "/=" | "%="
| "&=" | "|=" | "$=" | "<<=" | ">>="
stmt =
| expr
| expr assignop expr
| decl
| BARRIER
| BREAK
| CONTINUE
| LEAVE
| RETURN expr
| "@" ident (* label *)
| GOTO ident
| NOTHING (* blank statement *)
| IF expr THEN {stmt} (END | else)
| WHILE expr DO {stmt} END
else =
| ELSEIF expr THEN {stmt} else
| ELSE {stmt} END
binop =
| "+" | "-" | "*" | "/" | "%" | "<<" | ">>" | "|" | "&" | "$"
| "!=" | "==" | "<" | ">" | "<=" | ">=" | AND | OR
compoundexpr =
| "{" list<item> "}"
| "{" list<expr> "}"
item = "[" expr "]" "=" expr
expr =
| expr binop expr (* no precedence for now its ok *)
| unary
unop =
| "&" | "-" | "~" | NOT | SIZEOFVALUE
unary =
| CONTAINEROF expr TO type "." ident {"." ident}
| CAST expr TO type
| unop unary
| atomic
atomic =
| ident | literal | TRUE | FALSE | NULLPTR
| "(" expr ")"
| OFFSETOF type "." ident
| SIZEOF type
| atomic "[" expr "]"
| atomic "^"
| atomic "." ident
| atomic "(" list<argument> ")"
argument = [OUT] expr
type =
| basetype
| basetype "[" expr "]"
basetype =
| QUAD | UQUAD | LONG | ULONG | INT | UINT | BYTE | UBYTE | VOID
| ident
| "(" type ")"
| "^" basetype