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