610ea48e939a65008aa97fe393511408bdf85c77
[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 THEN
53 %left ELSE
54 %nonassoc ASSIGN
55 %left OF DO
56 %left OR
57 %left AND
58 %nonassoc EQ NEQ GT LT GE LE
59 %left PLUS MINUS
60 %left TIMES DIVIDE
61 %nonassoc UMINUS
62 /* to highest precedence */
63
64 %type <string> program
65
66 %start program
67
68 %%
69
70 program:
71 | exp EOF
72 {
73 sprintf "program[%s]" $1
74 }
75 ;
76
77 exp:
78 | NIL
79 {
80 "nil[]"
81 }
82 | INT
83 {
84 sprintf "int[%d]" $1
85 }
86 | MINUS exp %prec UMINUS
87 {
88 sprintf "negation[%s]" $2
89 }
90 | ID LBRACK exp RBRACK OF exp
91 {
92 let type_id = $1 in
93 let number_of_elements = $3 in
94 let initial_value = $6 in
95 sprintf
96 "array[type[%s], size[%s], val[%s]]"
97 type_id number_of_elements initial_value
98 }
99 | ID LBRACE rec_field_assignments RBRACE
100 {
101 let type_id = $1 in
102 let rec_field_assignments = $3 in
103 sprintf
104 "record[type[%s], rec_field_assignments[%s]]"
105 type_id rec_field_assignments
106 }
107 | lvalue
108 {
109 $1
110 }
111 | lvalue ASSIGN exp
112 {
113 sprintf "assign[%s := %s]" $1 $3
114 }
115 | STRING
116 {
117 sprintf "string[%S]" $1
118 }
119 | ID LPAREN RPAREN
120 {
121 let id = $1 in
122 sprintf "fun_call[%s, []]" id
123 }
124 | ID LPAREN fun_args RPAREN
125 {
126 let id = $1 in
127 let fun_args = $3 in
128 sprintf "fun_call[%s, %s]" id fun_args
129 }
130 | exp op exp
131 {
132 sprintf "op[%s %s %s]" $1 $2 $3
133 }
134 | IF exp THEN exp ELSE exp
135 {
136 let e1 = $2 in
137 let e2 = $4 in
138 let e3 = $6 in
139 sprintf "if_then_else[%s, then[%s], else[%s]]" e1 e2 e3
140 }
141 | IF exp THEN exp
142 {
143 sprintf "if_then[%s, then[%s]]" $2 $4
144 }
145 | WHILE exp DO exp
146 {
147 sprintf "while[%s, do[%s]]" $2 $4
148 }
149 | FOR ID ASSIGN exp TO exp DO exp
150 {
151 let id = $2 in
152 let e1 = $4 in
153 let e2 = $6 in
154 let e3 = $8 in
155 sprintf "for[%s := %s, to[%s], do[%s]]" id e1 e2 e3
156 }
157 | BREAK
158 {
159 "break[]"
160 }
161 | LPAREN exps RPAREN
162 {
163 sprintf "exps[%s]" $2
164 }
165 | LET decs IN exps END
166 {
167 let decs = $2 in
168 let exps = $4 in
169 sprintf "let[decs[%s], in[exps[%s]]]" decs exps
170 }
171 | LPAREN RPAREN
172 {
173 (* Perhaps "void"? *)
174 "unit[]"
175 }
176 ;
177
178 rec_field_assignments:
179 | ID EQ exp
180 {
181 let id = $1 in
182 let exp = $3 in
183 sprintf "%S = %s" id exp
184 }
185 | ID EQ exp COMMA rec_field_assignments
186 {
187 let id = $1 in
188 let exp = $3 in
189 let rec_field_assignments = $5 in
190 sprintf "%S = %s, %s" id exp rec_field_assignments
191 }
192 ;
193
194 exps:
195 | exp
196 {
197 let exp = $1 in
198 sprintf "%s" exp
199 }
200 | exp SEMICOLON exps
201 {
202 let exp = $1 in
203 let exps = $3 in
204 sprintf "%s; %s" exp exps
205 }
206 ;
207
208 decs:
209 | dec
210 {
211 sprintf "%s" $1
212 }
213 | dec decs
214 {
215 sprintf "%s %s" $1 $2
216 }
217 ;
218
219 dec:
220 /* Tydec */
221 | TYPE ID EQ ID
222 {
223 let type_id_new = $2 in
224 let type_id_orig = $4 in
225 sprintf "tydec_alias[from[%s], to[%s]]" type_id_new type_id_orig
226 }
227 | TYPE ID EQ LBRACE RBRACE
228 {
229 let type_id = $2 in
230 sprintf "tydec_empty_record[%s]" type_id
231 }
232 | TYPE ID EQ LBRACE tyfields RBRACE
233 {
234 let type_id = $2 in
235 let tyfields = $5 in
236 sprintf "tydec_record[%s, fields[%s]]" type_id tyfields
237 }
238 | TYPE ID EQ ARRAY OF ID
239 {
240 let type_id = $2 in
241 let element_type_id = $6 in
242 sprintf "tydec_array[%s, elements_of_type[%s]]" type_id element_type_id
243 }
244
245 /* Vardec */
246 | VAR ID ASSIGN exp
247 {
248 let id = $2 in
249 let exp = $4 in
250 sprintf "vardec[%s, exp[%s]]" id exp
251 }
252 | VAR ID COLON ID ASSIGN exp
253 {
254 let id = $2 in
255 let type_id = $4 in
256 let exp = $6 in
257 sprintf "vardec[%s, type_id[%s], exp[%s]]" id type_id exp
258 }
259
260 /* Fundec */
261 | FUNCTION ID LPAREN RPAREN EQ exp
262 {
263 let id = $2 in
264 let exp = $6 in
265 sprintf "fundec[%s, arguments[], exp[%s]]" id exp
266 }
267 | FUNCTION ID LPAREN tyfields RPAREN EQ exp
268 {
269 let id = $2 in
270 let tyfields = $4 in
271 let exp = $7 in
272 sprintf "fundec[%s, arguments[%s], exp[%s]]" id tyfields exp
273 }
274 | FUNCTION ID LPAREN tyfields RPAREN COLON ID EQ exp
275 {
276 let id = $2 in
277 let tyfields = $4 in
278 let type_id = $7 in
279 let exp = $9 in
280 sprintf
281 "fundec[%s, tyfields[%s], type_id[%s], exp[%s]]"
282 id tyfields type_id exp
283 }
284 ;
285
286 tyfields:
287 | ID COLON ID
288 {
289 let id_1 = $1 in
290 let id_2 = $3 in
291 sprintf "%s : %s" id_1 id_2
292 }
293 | ID COLON ID COMMA tyfields
294 {
295 let id_1 = $1 in
296 let id_2 = $3 in
297 let tyfield = sprintf "%s : %s" id_1 id_2 in
298 let tyfields = $5 in
299 sprintf "%s, %s" tyfield tyfields
300 }
301 ;
302
303 fun_args:
304 | exp
305 {
306 $1
307 }
308 | exp COMMA fun_args
309 {
310 sprintf "%s, %s" $1 $3
311 }
312 ;
313
314 op:
315 | PLUS {"+"}
316 | MINUS {"-"}
317 | TIMES {"*"}
318 | DIVIDE {"/"}
319 | EQ {"="}
320 | NEQ {"<>"}
321 | GT {">"}
322 | LT {"<"}
323 | GE {">="}
324 | LE {"<="}
325 | AND {"&"}
326 | OR {"|"}
327 ;
328
329 lvalue:
330 | ID lvalue_part
331 {
332 let id = $1 in
333 let part = $2 in
334 sprintf "lvalue[%s, part[%s]]" id part
335 }
336 ;
337
338 lvalue_part:
339 | {"epsilon[]"}
340 | lvalue_subscript {$1}
341 | lvalue_field_access {$1}
342 ;
343
344 lvalue_subscript:
345 | LBRACK exp RBRACK
346 {
347 let exp = $2 in
348 sprintf "subscript[%s]" exp
349 }
350 ;
351
352 lvalue_field_access:
353 | DOT ID
354 {
355 let field = $2 in
356 sprintf "field_access[%s]" field
357 }
358 ;
359
360 %%
This page took 0.073887 seconds and 3 git commands to generate.