Fix the remaining 12 shift/reduce conflicts
[tiger.ml.git] / tiger / src / lib / tiger / tiger_parser.mly
CommitLineData
543d3420
SK
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 */
7c9381cf 52%left THEN
b0047ce7 53%left ELSE
c7598faf 54%nonassoc ASSIGN
ccbe4cfc 55%left OF DO
543d3420
SK
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
70program:
71 | exp EOF
72 {
73 sprintf "program[%s]" $1
74 }
a0db5523 75 ;
543d3420
SK
76
77exp:
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 }
ef945634 90 | ID LBRACK exp RBRACK OF exp
543d3420 91 {
ef945634 92 let type_id = $1 in
a0db5523
SK
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
543d3420 98 }
ef945634 99 | ID LBRACE rec_field_assignments RBRACE
543d3420 100 {
ef945634
SK
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
543d3420
SK
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 }
b9397ef5 119 | ID LPAREN RPAREN
543d3420 120 {
29de275c
SK
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
543d3420 129 }
6a74bf44 130 | exp PLUS exp
543d3420 131 {
6a74bf44
SK
132 sprintf "op_plus[%s + %s]" $1 $3
133 }
134 | exp MINUS exp
135 {
136 sprintf "op_minus[%s - %s]" $1 $3
137 }
138 | exp TIMES exp
139 {
140 sprintf "op_times[%s * %s]" $1 $3
141 }
142 | exp DIVIDE exp
143 {
144 sprintf "op_divide[%s / %s]" $1 $3
145 }
146 | exp EQ exp
147 {
148 sprintf "op_eq[%s = %s]" $1 $3
149 }
150 | exp NEQ exp
151 {
152 sprintf "op_neq[%s <> %s]" $1 $3
153 }
154 | exp GT exp
155 {
156 sprintf "op_gt[%s > %s]" $1 $3
157 }
158 | exp LT exp
159 {
160 sprintf "op_lt[%s < %s]" $1 $3
161 }
162 | exp GE exp
163 {
164 sprintf "op_ge[%s >= %s]" $1 $3
165 }
166 | exp LE exp
167 {
168 sprintf "op_le[%s <= %s]" $1 $3
169 }
170 | exp AND exp
171 {
172 sprintf "op_and[%s & %s]" $1 $3
173 }
174 | exp OR exp
175 {
176 sprintf "op_or[%s | %s]" $1 $3
543d3420
SK
177 }
178 | IF exp THEN exp ELSE exp
179 {
180 let e1 = $2 in
181 let e2 = $4 in
182 let e3 = $6 in
183 sprintf "if_then_else[%s, then[%s], else[%s]]" e1 e2 e3
184 }
185 | IF exp THEN exp
186 {
187 sprintf "if_then[%s, then[%s]]" $2 $4
188 }
189 | WHILE exp DO exp
190 {
191 sprintf "while[%s, do[%s]]" $2 $4
192 }
ffff6f35 193 | FOR ID ASSIGN exp TO exp DO exp
543d3420
SK
194 {
195 let id = $2 in
196 let e1 = $4 in
197 let e2 = $6 in
198 let e3 = $8 in
199 sprintf "for[%s := %s, to[%s], do[%s]]" id e1 e2 e3
200 }
201 | BREAK
202 {
203 "break[]"
204 }
e7dfac93 205 | LPAREN exps RPAREN
543d3420 206 {
e7dfac93 207 sprintf "exps[%s]" $2
543d3420 208 }
e7dfac93 209 | LET decs IN exps END
543d3420
SK
210 {
211 let decs = $2 in
e7dfac93
SK
212 let exps = $4 in
213 sprintf "let[decs[%s], in[exps[%s]]]" decs exps
543d3420 214 }
b9397ef5 215 | LPAREN RPAREN
543d3420 216 {
b9397ef5
SK
217 (* Perhaps "void"? *)
218 "unit[]"
543d3420 219 }
a0db5523 220 ;
543d3420 221
b3c9d54d
SK
222rec_field_assignments:
223 | ID EQ exp
224 {
225 let id = $1 in
226 let exp = $3 in
227 sprintf "%S = %s" id exp
228 }
229 | ID EQ exp COMMA rec_field_assignments
230 {
231 let id = $1 in
232 let exp = $3 in
233 let rec_field_assignments = $5 in
234 sprintf "%S = %s, %s" id exp rec_field_assignments
235 }
a0db5523 236 ;
b3c9d54d 237
e7dfac93 238exps:
543d3420
SK
239 | exp
240 {
a0db5523
SK
241 let exp = $1 in
242 sprintf "%s" exp
543d3420 243 }
e7dfac93 244 | exp SEMICOLON exps
543d3420 245 {
a0db5523
SK
246 let exp = $1 in
247 let exps = $3 in
248 sprintf "%s; %s" exp exps
543d3420 249 }
a0db5523 250 ;
543d3420
SK
251
252decs:
253 | dec
254 {
255 sprintf "%s" $1
256 }
257 | dec decs
258 {
259 sprintf "%s %s" $1 $2
260 }
a0db5523 261 ;
543d3420
SK
262
263dec:
3fbeb7c1
SK
264 /* Tydec */
265 | TYPE ID EQ ID
ef945634 266 {
3fbeb7c1
SK
267 let type_id_new = $2 in
268 let type_id_orig = $4 in
269 sprintf "tydec_alias[from[%s], to[%s]]" type_id_new type_id_orig
ef945634 270 }
3fbeb7c1 271 | TYPE ID EQ LBRACE RBRACE
543d3420 272 {
3fbeb7c1
SK
273 let type_id = $2 in
274 sprintf "tydec_empty_record[%s]" type_id
543d3420 275 }
3fbeb7c1 276 | TYPE ID EQ LBRACE tyfields RBRACE
543d3420 277 {
3fbeb7c1
SK
278 let type_id = $2 in
279 let tyfields = $5 in
280 sprintf "tydec_record[%s, fields[%s]]" type_id tyfields
281 }
282 | TYPE ID EQ ARRAY OF ID
283 {
284 let type_id = $2 in
285 let element_type_id = $6 in
286 sprintf "tydec_array[%s, elements_of_type[%s]]" type_id element_type_id
543d3420
SK
287 }
288
3fbeb7c1 289 /* Vardec */
ffff6f35 290 | VAR ID ASSIGN exp
543d3420
SK
291 {
292 let id = $2 in
293 let exp = $4 in
294 sprintf "vardec[%s, exp[%s]]" id exp
295 }
ffff6f35 296 | VAR ID COLON ID ASSIGN exp
543d3420
SK
297 {
298 let id = $2 in
ef945634 299 let type_id = $4 in
543d3420 300 let exp = $6 in
ef945634 301 sprintf "vardec[%s, type_id[%s], exp[%s]]" id type_id exp
543d3420
SK
302 }
303
3fbeb7c1
SK
304 /* Fundec */
305 | FUNCTION ID LPAREN RPAREN EQ exp
543d3420 306 {
3fbeb7c1
SK
307 let id = $2 in
308 let exp = $6 in
309 sprintf "fundec[%s, arguments[], exp[%s]]" id exp
543d3420 310 }
3fbeb7c1 311 | FUNCTION ID LPAREN tyfields RPAREN EQ exp
543d3420 312 {
3fbeb7c1
SK
313 let id = $2 in
314 let tyfields = $4 in
315 let exp = $7 in
316 sprintf "fundec[%s, arguments[%s], exp[%s]]" id tyfields exp
543d3420 317 }
3fbeb7c1 318 | FUNCTION ID LPAREN tyfields RPAREN COLON ID EQ exp
543d3420 319 {
3fbeb7c1
SK
320 let id = $2 in
321 let tyfields = $4 in
322 let type_id = $7 in
323 let exp = $9 in
324 sprintf
325 "fundec[%s, tyfields[%s], type_id[%s], exp[%s]]"
326 id tyfields type_id exp
543d3420 327 }
a0db5523 328 ;
543d3420
SK
329
330tyfields:
a87678f0 331 | ID COLON ID
543d3420 332 {
a87678f0
SK
333 let id_1 = $1 in
334 let id_2 = $3 in
335 sprintf "%s : %s" id_1 id_2
543d3420 336 }
a87678f0 337 | ID COLON ID COMMA tyfields
543d3420 338 {
a87678f0
SK
339 let id_1 = $1 in
340 let id_2 = $3 in
341 let tyfield = sprintf "%s : %s" id_1 id_2 in
342 let tyfields = $5 in
343 sprintf "%s, %s" tyfield tyfields
543d3420 344 }
a0db5523 345 ;
543d3420 346
543d3420
SK
347fun_args:
348 | exp
349 {
350 $1
351 }
352 | exp COMMA fun_args
353 {
354 sprintf "%s, %s" $1 $3
355 }
a0db5523 356 ;
543d3420 357
543d3420 358lvalue:
a0db5523 359 | ID lvalue_part
543d3420 360 {
ffff6f35 361 let id = $1 in
a0db5523
SK
362 let part = $2 in
363 sprintf "lvalue[%s, part[%s]]" id part
543d3420 364 }
a0db5523
SK
365 ;
366
367lvalue_part:
368 | {"epsilon[]"}
369 | lvalue_subscript {$1}
370 | lvalue_field_access {$1}
371 ;
372
373lvalue_subscript:
374 | LBRACK exp RBRACK
543d3420 375 {
a0db5523
SK
376 let exp = $2 in
377 sprintf "subscript[%s]" exp
543d3420 378 }
a0db5523
SK
379 ;
380
381lvalue_field_access:
382 | DOT ID
543d3420 383 {
a0db5523
SK
384 let field = $2 in
385 sprintf "field_access[%s]" field
543d3420 386 }
a0db5523 387 ;
543d3420
SK
388
389%%
This page took 0.054062 seconds and 4 git commands to generate.