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