Remove stand-alone tyfield 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 }
b9397ef5 112 | ID LPAREN RPAREN
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 }
e7dfac93 154 | LPAREN exps RPAREN
543d3420 155 {
e7dfac93 156 sprintf "exps[%s]" $2
543d3420 157 }
e7dfac93 158 | LET decs IN exps END
543d3420
SK
159 {
160 let decs = $2 in
e7dfac93
SK
161 let exps = $4 in
162 sprintf "let[decs[%s], in[exps[%s]]]" decs exps
543d3420 163 }
b9397ef5 164 | LPAREN RPAREN
543d3420 165 {
b9397ef5
SK
166 (* Perhaps "void"? *)
167 "unit[]"
543d3420
SK
168 }
169
e7dfac93 170exps:
543d3420
SK
171 | exp
172 {
173 sprintf "%s" $1
174 }
e7dfac93 175 | exp SEMICOLON exps
543d3420
SK
176 {
177 sprintf "%s; %s" $1 $3
178 }
179
180decs:
181 | dec
182 {
183 sprintf "%s" $1
184 }
185 | dec decs
186 {
187 sprintf "%s %s" $1 $2
188 }
189
190dec:
3fbeb7c1
SK
191 /* Tydec */
192 | TYPE ID EQ ID
ef945634 193 {
3fbeb7c1
SK
194 let type_id_new = $2 in
195 let type_id_orig = $4 in
196 sprintf "tydec_alias[from[%s], to[%s]]" type_id_new type_id_orig
ef945634 197 }
3fbeb7c1 198 | TYPE ID EQ LBRACE RBRACE
543d3420 199 {
3fbeb7c1
SK
200 let type_id = $2 in
201 sprintf "tydec_empty_record[%s]" type_id
543d3420 202 }
3fbeb7c1 203 | TYPE ID EQ LBRACE tyfields RBRACE
543d3420 204 {
3fbeb7c1
SK
205 let type_id = $2 in
206 let tyfields = $5 in
207 sprintf "tydec_record[%s, fields[%s]]" type_id tyfields
208 }
209 | TYPE ID EQ ARRAY OF ID
210 {
211 let type_id = $2 in
212 let element_type_id = $6 in
213 sprintf "tydec_array[%s, elements_of_type[%s]]" type_id element_type_id
543d3420
SK
214 }
215
3fbeb7c1 216 /* Vardec */
ffff6f35 217 | VAR ID ASSIGN exp
543d3420
SK
218 {
219 let id = $2 in
220 let exp = $4 in
221 sprintf "vardec[%s, exp[%s]]" id exp
222 }
ffff6f35 223 | VAR ID COLON ID ASSIGN exp
543d3420
SK
224 {
225 let id = $2 in
ef945634 226 let type_id = $4 in
543d3420 227 let exp = $6 in
ef945634 228 sprintf "vardec[%s, type_id[%s], exp[%s]]" id type_id exp
543d3420
SK
229 }
230
3fbeb7c1
SK
231 /* Fundec */
232 | FUNCTION ID LPAREN RPAREN EQ exp
543d3420 233 {
3fbeb7c1
SK
234 let id = $2 in
235 let exp = $6 in
236 sprintf "fundec[%s, arguments[], exp[%s]]" id exp
543d3420 237 }
3fbeb7c1 238 | FUNCTION ID LPAREN tyfields RPAREN EQ exp
543d3420 239 {
3fbeb7c1
SK
240 let id = $2 in
241 let tyfields = $4 in
242 let exp = $7 in
243 sprintf "fundec[%s, arguments[%s], exp[%s]]" id tyfields exp
543d3420 244 }
3fbeb7c1 245 | FUNCTION ID LPAREN tyfields RPAREN COLON ID EQ exp
543d3420 246 {
3fbeb7c1
SK
247 let id = $2 in
248 let tyfields = $4 in
249 let type_id = $7 in
250 let exp = $9 in
251 sprintf
252 "fundec[%s, tyfields[%s], type_id[%s], exp[%s]]"
253 id tyfields type_id exp
543d3420
SK
254 }
255
256tyfields:
a87678f0 257 | ID COLON ID
543d3420 258 {
a87678f0
SK
259 let id_1 = $1 in
260 let id_2 = $3 in
261 sprintf "%s : %s" id_1 id_2
543d3420 262 }
a87678f0 263 | ID COLON ID COMMA tyfields
543d3420 264 {
a87678f0
SK
265 let id_1 = $1 in
266 let id_2 = $3 in
267 let tyfield = sprintf "%s : %s" id_1 id_2 in
268 let tyfields = $5 in
269 sprintf "%s, %s" tyfield tyfields
543d3420
SK
270 }
271
543d3420 272rec_field_assignments:
ffff6f35 273 | ID EQ exp
543d3420 274 {
ffff6f35
SK
275 let id = $1 in
276 let exp = $3 in
277 sprintf "%S = %s" id exp
543d3420 278 }
ffff6f35 279 | ID EQ exp COMMA rec_field_assignments
543d3420 280 {
ffff6f35
SK
281 let id = $1 in
282 let exp = $3 in
283 let rec_field_assignments = $5 in
284 sprintf "%S = %s, %s" id exp rec_field_assignments
543d3420
SK
285 }
286
543d3420
SK
287fun_args:
288 | exp
289 {
290 $1
291 }
292 | exp COMMA fun_args
293 {
294 sprintf "%s, %s" $1 $3
295 }
296
297op:
298 | PLUS {"+"}
299 | MINUS {"-"}
300 | TIMES {"*"}
301 | DIVIDE {"/"}
302 | EQ {"="}
303 | NEQ {"<>"}
304 | GT {">"}
305 | LT {"<"}
306 | GE {">="}
307 | LE {"<="}
308 | AND {"&"}
309 | OR {"|"}
310
311lvalue:
ffff6f35 312 | ID
543d3420 313 {
ffff6f35
SK
314 let id = $1 in
315 sprintf "lvalue[%s]" id
543d3420 316 }
ffff6f35 317 | lvalue DOT ID
543d3420 318 {
ffff6f35
SK
319 let record = $1 in
320 let field = $3 in
321 sprintf "get_record_field[%s, %s]" record field
543d3420
SK
322 }
323 | lvalue LBRACK exp RBRACK
324 {
ffff6f35
SK
325 let array = $1 in
326 let subscript = $3 in
327 sprintf "get_array_subscript[%s, %s]" array subscript
543d3420
SK
328 }
329
330%%
This page took 0.048013 seconds and 4 git commands to generate.