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