Define initial grammar
[tiger.ml.git] / tiger / src / lib / tiger / tiger_parser.mly
1 %{
2 open Printf
3 %}
4
5 /* Declarations */
6 %token AND
7 %token ARRAY
8 %token ASSIGN
9 %token BREAK
10 %token COLON
11 %token COMMA
12 %token DIVIDE
13 %token DO
14 %token DOT
15 %token ELSE
16 %token END
17 %token EOF
18 %token EQ
19 %token FOR
20 %token FUNCTION
21 %token GE
22 %token GT
23 %token <string> ID
24 %token IF
25 %token IN
26 %token <int> INT
27 %token LBRACE
28 %token LBRACK
29 %token LE
30 %token LET
31 %token LPAREN
32 %token LT
33 %token MINUS
34 %token NEQ
35 %token NIL
36 %token OF
37 %token OR
38 %token PLUS
39 %token RBRACE
40 %token RBRACK
41 %token RPAREN
42 %token SEMICOLON
43 %token <string> STRING
44 %token THEN
45 %token TIMES
46 %token TO
47 %token TYPE
48 %token VAR
49 %token WHILE
50
51 /* from lowest precedence */
52 %left OR
53 %left AND
54 %nonassoc EQ NEQ GT LT GE LE
55 %left PLUS MINUS
56 %left TIMES DIVIDE
57 %nonassoc UMINUS
58 /* to highest precedence */
59
60 %type <string> program
61
62 %start program
63
64 %%
65
66 program:
67 | exp EOF
68 {
69 sprintf "program[%s]" $1
70 }
71
72 exp:
73 | NIL
74 {
75 "nil[]"
76 }
77 | INT
78 {
79 sprintf "int[%d]" $1
80 }
81 | MINUS exp %prec UMINUS
82 {
83 sprintf "negation[%s]" $2
84 }
85 | type_id LBRACK exp RBRACK OF exp
86 {
87 sprintf "array[type[%s], size[%s], val[%s]]" $1 $3 $6
88 }
89 | type_id LBRACE rec_field_assignments RBRACE
90 {
91 sprintf "record[type[%s], rec_field_assignments[%s]]" $1 $3
92 }
93 | lvalue
94 {
95 $1
96 }
97 | lvalue ASSIGN exp
98 {
99 sprintf "assign[%s := %s]" $1 $3
100 }
101 | STRING
102 {
103 sprintf "string[%S]" $1
104 }
105 | fun_call
106 {
107 $1
108 }
109 | exp op exp
110 {
111 sprintf "op[%s %s %s]" $1 $2 $3
112 }
113 | IF exp THEN exp ELSE exp
114 {
115 let e1 = $2 in
116 let e2 = $4 in
117 let e3 = $6 in
118 sprintf "if_then_else[%s, then[%s], else[%s]]" e1 e2 e3
119 }
120 | IF exp THEN exp
121 {
122 sprintf "if_then[%s, then[%s]]" $2 $4
123 }
124 | WHILE exp DO exp
125 {
126 sprintf "while[%s, do[%s]]" $2 $4
127 }
128 | FOR id ASSIGN exp TO exp DO exp
129 {
130 let id = $2 in
131 let e1 = $4 in
132 let e2 = $6 in
133 let e3 = $8 in
134 sprintf "for[%s := %s, to[%s], do[%s]]" id e1 e2 e3
135 }
136 | BREAK
137 {
138 "break[]"
139 }
140 | LPAREN seq RPAREN
141 {
142 sprintf "seq[%s]" $2
143 }
144 | LET decs IN seq END
145 {
146 let decs = $2 in
147 let seq = $4 in
148 sprintf "let[decs[%s], in[seq[%s]]]" decs seq
149 }
150 | unit
151 {
152 $1
153 }
154
155 seq:
156 | exp
157 {
158 sprintf "%s" $1
159 }
160 | exp SEMICOLON seq
161 {
162 sprintf "%s; %s" $1 $3
163 }
164
165 decs:
166 | dec
167 {
168 sprintf "%s" $1
169 }
170 | dec decs
171 {
172 sprintf "%s %s" $1 $2
173 }
174
175 dec:
176 | tydec {$1}
177 | vardec {$1}
178 | fundec {$1}
179
180 fundec:
181 | FUNCTION id LPAREN tyfields RPAREN EQ exp
182 {
183 let id = $2 in
184 let tyfields = $4 in
185 let exp = $7 in
186 sprintf "fundec[%s, tyfields[%s], exp[%s]]" id tyfields exp
187 }
188 | FUNCTION id LPAREN tyfields RPAREN COLON type_id EQ exp
189 {
190 let id = $2 in
191 let tyfields = $4 in
192 let type_id = $7 in
193 let exp = $9 in
194 sprintf
195 "fundec[%s, tyfields[%s], type_id[%s], exp[%s]]"
196 id tyfields type_id exp
197 }
198
199 vardec:
200 | VAR id ASSIGN exp
201 {
202 let id = $2 in
203 let exp = $4 in
204 sprintf "vardec[%s, exp[%s]]" id exp
205 }
206 | VAR id COLON type_id ASSIGN exp
207 {
208 let id = $2 in
209 let tyid = $4 in
210 let exp = $6 in
211 sprintf "vardec[%s, type_id[%s], exp[%s]]" id tyid exp
212 }
213
214 tydec:
215 | TYPE type_id EQ ty
216 {
217 sprintf "tydec[%s, %s]" $2 $4
218 }
219
220 ty:
221 | type_id
222 {$1}
223 | LBRACE RBRACE
224 {
225 "record[]"
226 }
227 | LBRACE tyfields RBRACE
228 {
229 let tyfields = $2 in
230 sprintf "record[%s]" tyfields
231 }
232 | ARRAY OF type_id
233 {
234 let type_id = $3 in
235 sprintf "array_of_type[%s]" type_id
236 }
237
238 tyfields:
239 /*| epsilon */
240 | tyfield
241 {$1}
242 | tyfield COMMA tyfields
243 {
244 let tyfield = $1 in
245 let tyfields = $3 in
246 sprintf "%s, %s" tyfield tyfields
247 }
248
249 tyfield:
250 | id COLON type_id
251 {
252 let id = $1 in
253 let type_id = $3 in
254 sprintf "tyfield[%s, %s]" id type_id
255 }
256
257 id:
258 | ID
259 {
260 sprintf "id[%S]" $1
261 }
262
263 /* Perhaps "void"? */
264 unit:
265 | LPAREN RPAREN
266 {
267 "unit[]"
268 }
269
270 type_id:
271 | id
272 {
273 sprintf "type_id[%S]" $1
274 }
275
276 rec_field_assignments:
277 | id EQ exp
278 {
279 sprintf "%S = %s" $1 $3
280 }
281 | id EQ exp COMMA rec_field_assignments
282 {
283 sprintf "%S = %s, %s" $1 $3 $5
284 }
285
286 fun_call:
287 | id unit
288 {
289 sprintf "fun_call[%s, %s]" $1 $2
290 }
291 | id LPAREN fun_args RPAREN
292 {
293 sprintf "fun_call[%s, %s]" $1 $3
294 }
295
296 fun_args:
297 | exp
298 {
299 $1
300 }
301 | exp COMMA fun_args
302 {
303 sprintf "%s, %s" $1 $3
304 }
305
306 op:
307 | PLUS {"+"}
308 | MINUS {"-"}
309 | TIMES {"*"}
310 | DIVIDE {"/"}
311 | EQ {"="}
312 | NEQ {"<>"}
313 | GT {">"}
314 | LT {"<"}
315 | GE {">="}
316 | LE {"<="}
317 | AND {"&"}
318 | OR {"|"}
319
320 lvalue:
321 | id
322 {
323 sprintf "lvalue[%s]" $1
324 }
325 | lvalue DOT id
326 {
327 sprintf "get_record_field[%s, %s]" $1 $3
328 }
329 | lvalue LBRACK exp RBRACK
330 {
331 sprintf "get_array_subscript[%s, %s]" $1 $3
332 }
333
334 %%
This page took 0.081439 seconds and 5 git commands to generate.