Remove stand-alone fun_call grammar rule
[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 }
29de275c 112 | ID unit
543d3420 113 {
29de275c
SK
114 let id = $1 in
115 sprintf "fun_call[%s, []]" id
116 }
117 | ID LPAREN fun_args RPAREN
118 {
119 let id = $1 in
120 let fun_args = $3 in
121 sprintf "fun_call[%s, %s]" id fun_args
543d3420
SK
122 }
123 | exp op exp
124 {
125 sprintf "op[%s %s %s]" $1 $2 $3
126 }
127 | IF exp THEN exp ELSE exp
128 {
129 let e1 = $2 in
130 let e2 = $4 in
131 let e3 = $6 in
132 sprintf "if_then_else[%s, then[%s], else[%s]]" e1 e2 e3
133 }
134 | IF exp THEN exp
135 {
136 sprintf "if_then[%s, then[%s]]" $2 $4
137 }
138 | WHILE exp DO exp
139 {
140 sprintf "while[%s, do[%s]]" $2 $4
141 }
ffff6f35 142 | FOR ID ASSIGN exp TO exp DO exp
543d3420
SK
143 {
144 let id = $2 in
145 let e1 = $4 in
146 let e2 = $6 in
147 let e3 = $8 in
148 sprintf "for[%s := %s, to[%s], do[%s]]" id e1 e2 e3
149 }
150 | BREAK
151 {
152 "break[]"
153 }
154 | LPAREN seq RPAREN
155 {
156 sprintf "seq[%s]" $2
157 }
158 | LET decs IN seq END
159 {
160 let decs = $2 in
161 let seq = $4 in
162 sprintf "let[decs[%s], in[seq[%s]]]" decs seq
163 }
164 | unit
165 {
166 $1
167 }
168
169seq:
170 | exp
171 {
172 sprintf "%s" $1
173 }
174 | exp SEMICOLON seq
175 {
176 sprintf "%s; %s" $1 $3
177 }
178
179decs:
180 | dec
181 {
182 sprintf "%s" $1
183 }
184 | dec decs
185 {
186 sprintf "%s %s" $1 $2
187 }
188
189dec:
190 | tydec {$1}
191 | vardec {$1}
192 | fundec {$1}
193
194fundec:
ffff6f35 195 | FUNCTION ID unit EQ exp
ef945634
SK
196 {
197 let id = $2 in
198 let exp = $5 in
199 sprintf "fundec[%s, exp[%s]]" id exp
200 }
ffff6f35 201 | FUNCTION ID LPAREN tyfields RPAREN EQ exp
543d3420
SK
202 {
203 let id = $2 in
204 let tyfields = $4 in
205 let exp = $7 in
206 sprintf "fundec[%s, tyfields[%s], exp[%s]]" id tyfields exp
207 }
ffff6f35 208 | FUNCTION ID LPAREN tyfields RPAREN COLON ID EQ exp
543d3420
SK
209 {
210 let id = $2 in
211 let tyfields = $4 in
212 let type_id = $7 in
213 let exp = $9 in
214 sprintf
215 "fundec[%s, tyfields[%s], type_id[%s], exp[%s]]"
216 id tyfields type_id exp
217 }
218
219vardec:
ffff6f35 220 | VAR ID ASSIGN exp
543d3420
SK
221 {
222 let id = $2 in
223 let exp = $4 in
224 sprintf "vardec[%s, exp[%s]]" id exp
225 }
ffff6f35 226 | VAR ID COLON ID ASSIGN exp
543d3420
SK
227 {
228 let id = $2 in
ef945634 229 let type_id = $4 in
543d3420 230 let exp = $6 in
ef945634 231 sprintf "vardec[%s, type_id[%s], exp[%s]]" id type_id exp
543d3420
SK
232 }
233
234tydec:
ef945634 235 | TYPE ID EQ ty
543d3420 236 {
ef945634
SK
237 let type_id = $2 in
238 let ty = $4 in
239 sprintf "tydec[%s, %s]" type_id ty
543d3420
SK
240 }
241
242ty:
ef945634
SK
243 | ID
244 {
245 let type_id = $1 in
246 sprintf "type[type_id[%S]]" type_id
247 }
543d3420
SK
248 | LBRACE RBRACE
249 {
250 "record[]"
251 }
252 | LBRACE tyfields RBRACE
253 {
254 let tyfields = $2 in
255 sprintf "record[%s]" tyfields
256 }
ef945634 257 | ARRAY OF ID
543d3420
SK
258 {
259 let type_id = $3 in
260 sprintf "array_of_type[%s]" type_id
261 }
262
263tyfields:
264/*| epsilon */
265 | tyfield
266 {$1}
267 | tyfield COMMA tyfields
268 {
269 let tyfield = $1 in
270 let tyfields = $3 in
271 sprintf "%s, %s" tyfield tyfields
272 }
273
274tyfield:
ffff6f35 275 | ID COLON ID
543d3420
SK
276 {
277 let id = $1 in
278 let type_id = $3 in
279 sprintf "tyfield[%s, %s]" id type_id
280 }
281
543d3420
SK
282/* Perhaps "void"? */
283unit:
284 | LPAREN RPAREN
285 {
286 "unit[]"
287 }
288
543d3420 289rec_field_assignments:
ffff6f35 290 | ID EQ exp
543d3420 291 {
ffff6f35
SK
292 let id = $1 in
293 let exp = $3 in
294 sprintf "%S = %s" id exp
543d3420 295 }
ffff6f35 296 | ID EQ exp COMMA rec_field_assignments
543d3420 297 {
ffff6f35
SK
298 let id = $1 in
299 let exp = $3 in
300 let rec_field_assignments = $5 in
301 sprintf "%S = %s, %s" id exp rec_field_assignments
543d3420
SK
302 }
303
543d3420
SK
304fun_args:
305 | exp
306 {
307 $1
308 }
309 | exp COMMA fun_args
310 {
311 sprintf "%s, %s" $1 $3
312 }
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 {"|"}
327
328lvalue:
ffff6f35 329 | ID
543d3420 330 {
ffff6f35
SK
331 let id = $1 in
332 sprintf "lvalue[%s]" id
543d3420 333 }
ffff6f35 334 | lvalue DOT ID
543d3420 335 {
ffff6f35
SK
336 let record = $1 in
337 let field = $3 in
338 sprintf "get_record_field[%s, %s]" record field
543d3420
SK
339 }
340 | lvalue LBRACK exp RBRACK
341 {
ffff6f35
SK
342 let array = $1 in
343 let subscript = $3 in
344 sprintf "get_array_subscript[%s, %s]" array subscript
543d3420
SK
345 }
346
347%%
This page took 0.057721 seconds and 4 git commands to generate.