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