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