Assign precedence and associativity to ELSE
[tiger.ml.git] / tiger / src / lib / tiger / tiger_parser.mly
... / ...
CommitLineData
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 ELSE
53%nonassoc ASSIGN
54%left OF DO
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 }
74 ;
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 }
89 | ID LBRACK exp RBRACK OF exp
90 {
91 let type_id = $1 in
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
97 }
98 | ID LBRACE rec_field_assignments RBRACE
99 {
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
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 }
118 | ID LPAREN RPAREN
119 {
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
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 }
148 | FOR ID ASSIGN exp TO exp DO exp
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 }
160 | LPAREN exps RPAREN
161 {
162 sprintf "exps[%s]" $2
163 }
164 | LET decs IN exps END
165 {
166 let decs = $2 in
167 let exps = $4 in
168 sprintf "let[decs[%s], in[exps[%s]]]" decs exps
169 }
170 | LPAREN RPAREN
171 {
172 (* Perhaps "void"? *)
173 "unit[]"
174 }
175 ;
176
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 }
191 ;
192
193exps:
194 | exp
195 {
196 let exp = $1 in
197 sprintf "%s" exp
198 }
199 | exp SEMICOLON exps
200 {
201 let exp = $1 in
202 let exps = $3 in
203 sprintf "%s; %s" exp exps
204 }
205 ;
206
207decs:
208 | dec
209 {
210 sprintf "%s" $1
211 }
212 | dec decs
213 {
214 sprintf "%s %s" $1 $2
215 }
216 ;
217
218dec:
219 /* Tydec */
220 | TYPE ID EQ ID
221 {
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
225 }
226 | TYPE ID EQ LBRACE RBRACE
227 {
228 let type_id = $2 in
229 sprintf "tydec_empty_record[%s]" type_id
230 }
231 | TYPE ID EQ LBRACE tyfields RBRACE
232 {
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
242 }
243
244 /* Vardec */
245 | VAR ID ASSIGN exp
246 {
247 let id = $2 in
248 let exp = $4 in
249 sprintf "vardec[%s, exp[%s]]" id exp
250 }
251 | VAR ID COLON ID ASSIGN exp
252 {
253 let id = $2 in
254 let type_id = $4 in
255 let exp = $6 in
256 sprintf "vardec[%s, type_id[%s], exp[%s]]" id type_id exp
257 }
258
259 /* Fundec */
260 | FUNCTION ID LPAREN RPAREN EQ exp
261 {
262 let id = $2 in
263 let exp = $6 in
264 sprintf "fundec[%s, arguments[], exp[%s]]" id exp
265 }
266 | FUNCTION ID LPAREN tyfields RPAREN EQ exp
267 {
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
272 }
273 | FUNCTION ID LPAREN tyfields RPAREN COLON ID EQ exp
274 {
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
282 }
283 ;
284
285tyfields:
286 | ID COLON ID
287 {
288 let id_1 = $1 in
289 let id_2 = $3 in
290 sprintf "%s : %s" id_1 id_2
291 }
292 | ID COLON ID COMMA tyfields
293 {
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
299 }
300 ;
301
302fun_args:
303 | exp
304 {
305 $1
306 }
307 | exp COMMA fun_args
308 {
309 sprintf "%s, %s" $1 $3
310 }
311 ;
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 {"|"}
326 ;
327
328lvalue:
329 | ID lvalue_part
330 {
331 let id = $1 in
332 let part = $2 in
333 sprintf "lvalue[%s, part[%s]]" id part
334 }
335 ;
336
337lvalue_part:
338 | {"epsilon[]"}
339 | lvalue_subscript {$1}
340 | lvalue_field_access {$1}
341 ;
342
343lvalue_subscript:
344 | LBRACK exp RBRACK
345 {
346 let exp = $2 in
347 sprintf "subscript[%s]" exp
348 }
349 ;
350
351lvalue_field_access:
352 | DOT ID
353 {
354 let field = $2 in
355 sprintf "field_access[%s]" field
356 }
357 ;
358
359%%
This page took 0.020695 seconds and 4 git commands to generate.