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