block: don't put spaces around :
[ironout.git] / c.y
blob3dc23b58f6f6f00aaeab662e259e29d70429f009
1 %{
2 #include <stdio.h>
3 #include "ast.h"
4 #include "parse.h"
6 %}
7 %token IDENTIFIER CONSTANT STRING_LITERAL MACRO SIZEOF
8 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
9 %token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
10 %token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
11 %token XOR_ASSIGN OR_ASSIGN TYPE_NAME
13 %token TYPEDEF EXTERN INLINE STATIC AUTO REGISTER RESTRICT
14 %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID
15 %token BOOL COMPLEX IMAGINARY
16 %token STRUCT UNION ENUM ELIPSIS RANGE
18 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
20 %start translation_unit
23 primary_expr
24 : identifier
25 | CONSTANT
26 { push_node(AST_INTEGER, @$.start, @$.end, 0); }
27 | joined_string
28 { push_node(AST_STRING, @$.start, @$.end, 0); }
29 | '(' expr ')'
32 joined_string
33 : joined_string STRING_LITERAL
34 | STRING_LITERAL
37 postfix_expr
38 : primary_expr
39 | postfix_expr '[' expr ']'
40 { push_node(AST_GETINDEX, @$.start, @$.end, 2); }
41 | postfix_expr '(' ')'
42 { push_node(AST_CALL, @$.start, @$.end, 1); }
43 | postfix_expr '(' argument_expr_list ')'
44 { push_node(AST_CALL, @$.start, @$.end, 2); }
45 | postfix_expr '.' identifier
46 { push_node(AST_GETATTR, @$.start, @$.end, 2); }
47 | postfix_expr PTR_OP identifier
48 { push_node(AST_DEREF, @$.start, @$.end, 2); }
49 | postfix_expr INC_OP
50 { push_node(AST_UNARY, @$.start, @$.end, 1); }
51 | postfix_expr DEC_OP
52 { push_node(AST_UNARY, @$.start, @$.end, 1); }
53 | '(' type_name ')' '{' initializer_list '}'
54 { push_node(AST_C99INIT, @$.start, @$.end, 2); }
55 | '(' type_name ')' '{' initializer_list ',' '}'
56 { push_node(AST_C99INIT, @$.start, @$.end, 2); }
59 argument_expr_list
60 : assignment_expr
61 { push_node(AST_ARGLIST, @$.start, @$.end, 1); }
62 | argument_expr_list ',' assignment_expr
63 { push_node(AST_ARGLIST, @$.start, @$.end, 2); }
66 unary_expr
67 : postfix_expr
68 | INC_OP unary_expr
69 { push_node(AST_UNARY, @$.start, @$.end, 1); }
70 | DEC_OP unary_expr
71 { push_node(AST_UNARY, @$.start, @$.end, 1); }
72 | unary_operator cast_expr
73 { push_node(AST_UNARY, @$.start, @$.end, 2); }
74 | SIZEOF unary_expr
75 { push_node(AST_SIZEOF, @$.start, @$.end, 1); }
76 | SIZEOF '(' type_name ')'
77 { push_node(AST_SIZEOF, @$.start, @$.end, 1); }
80 unary_operator
81 : '&'
82 { push_node(AST_UNARYOP, @$.start, @$.end, 0); }
83 | '*'
84 { push_node(AST_UNARYOP, @$.start, @$.end, 0); }
85 | '+'
86 { push_node(AST_UNARYOP, @$.start, @$.end, 0); }
87 | '-'
88 { push_node(AST_UNARYOP, @$.start, @$.end, 0); }
89 | '~'
90 { push_node(AST_UNARYOP, @$.start, @$.end, 0); }
91 | '!'
92 { push_node(AST_UNARYOP, @$.start, @$.end, 0); }
95 cast_expr
96 : unary_expr
97 | '(' type_name ')' cast_expr
98 { push_node(AST_CAST, @$.start, @$.end, 2); }
101 multiplicative_expr
102 : cast_expr
103 | multiplicative_expr '*' cast_expr
104 { push_node(AST_BINARY, @$.start, @$.end, 2); }
105 | multiplicative_expr '/' cast_expr
106 { push_node(AST_BINARY, @$.start, @$.end, 2); }
107 | multiplicative_expr '%' cast_expr
108 { push_node(AST_BINARY, @$.start, @$.end, 2); }
111 additive_expr
112 : multiplicative_expr
113 | additive_expr '+' multiplicative_expr
114 { push_node(AST_BINARY, @$.start, @$.end, 2); }
115 | additive_expr '-' multiplicative_expr
116 { push_node(AST_BINARY, @$.start, @$.end, 2); }
119 shift_expr
120 : additive_expr
121 | shift_expr LEFT_OP additive_expr
122 { push_node(AST_BINARY, @$.start, @$.end, 2); }
123 | shift_expr RIGHT_OP additive_expr
124 { push_node(AST_BINARY, @$.start, @$.end, 2); }
127 relational_expr
128 : shift_expr
129 | relational_expr '<' shift_expr
130 { push_node(AST_BINARY, @$.start, @$.end, 2); }
131 | relational_expr '>' shift_expr
132 { push_node(AST_BINARY, @$.start, @$.end, 2); }
133 | relational_expr LE_OP shift_expr
134 { push_node(AST_BINARY, @$.start, @$.end, 2); }
135 | relational_expr GE_OP shift_expr
136 { push_node(AST_BINARY, @$.start, @$.end, 2); }
139 equality_expr
140 : relational_expr
141 | equality_expr EQ_OP relational_expr
142 { push_node(AST_BINARY, @$.start, @$.end, 2); }
143 | equality_expr NE_OP relational_expr
144 { push_node(AST_BINARY, @$.start, @$.end, 2); }
147 and_expr
148 : equality_expr
149 | and_expr '&' equality_expr
150 { push_node(AST_BINARY, @$.start, @$.end, 2); }
153 exclusive_or_expr
154 : and_expr
155 | exclusive_or_expr '^' and_expr
156 { push_node(AST_BINARY, @$.start, @$.end, 2); }
159 inclusive_or_expr
160 : exclusive_or_expr
161 | inclusive_or_expr '|' exclusive_or_expr
162 { push_node(AST_BINARY, @$.start, @$.end, 2); }
165 logical_and_expr
166 : inclusive_or_expr
167 | logical_and_expr AND_OP inclusive_or_expr
168 { push_node(AST_BINARY, @$.start, @$.end, 2); }
171 logical_or_expr
172 : logical_and_expr
173 | logical_or_expr OR_OP logical_and_expr
174 { push_node(AST_BINARY, @$.start, @$.end, 2); }
177 conditional_expr
178 : logical_or_expr
179 | logical_or_expr '?' logical_or_expr ':' conditional_expr
180 { push_node(AST_CONDITIONAL, @$.start, @$.end, 3); }
183 assignment_expr
184 : conditional_expr
185 | unary_expr assignment_operator assignment_expr
186 { push_node(AST_ASSIGN, @$.start, @$.end, 2); }
189 assignment_operator
190 : '='
191 | MUL_ASSIGN
192 | DIV_ASSIGN
193 | MOD_ASSIGN
194 | ADD_ASSIGN
195 | SUB_ASSIGN
196 | LEFT_ASSIGN
197 | RIGHT_ASSIGN
198 | AND_ASSIGN
199 | XOR_ASSIGN
200 | OR_ASSIGN
203 expr
204 : assignment_expr
205 { push_node(AST_EXPRLIST, @$.start, @$.end, 1); }
206 | expr ',' assignment_expr
207 { push_node(AST_EXPRLIST, @$.start, @$.end, 2); }
210 constant_expr
211 : conditional_expr
214 declaration
215 : declaration_specifiers ';'
216 { push_node(AST_DECLSTMT, @$.start, @$.end, 1); }
217 | declaration_specifiers init_declarator_list ';'
218 { push_node(AST_DECLSTMT, @$.start, @$.end, 2); }
221 declaration_specifiers
222 : storage_class_specifier
223 { push_node(AST_DECLSPEC, @$.start, @$.end, 1); }
224 | storage_class_specifier declaration_specifiers
225 { push_node(AST_DECLSPEC, @$.start, @$.end, 2); }
226 | type_specifier
227 { push_node(AST_DECLSPEC, @$.start, @$.end, 1); }
228 | type_specifier declaration_specifiers
229 { push_node(AST_DECLSPEC, @$.start, @$.end, 2); }
230 | type_qualifier
231 { push_node(AST_DECLSPEC, @$.start, @$.end, 1); }
232 | type_qualifier declaration_specifiers
233 { push_node(AST_DECLSPEC, @$.start, @$.end, 2); }
234 | function_specifier
235 { push_node(AST_DECLSPEC, @$.start, @$.end, 1); }
236 | function_specifier declaration_specifiers
237 { push_node(AST_DECLSPEC, @$.start, @$.end, 2); }
240 init_declarator_list
241 : init_declarator
242 { push_node(AST_INITLIST, @$.start, @$.end, 1); }
243 | init_declarator_list ',' init_declarator
244 { push_node(AST_INITLIST, @$.start, @$.end, 2); }
247 init_declarator
248 : declarator
249 | declarator '=' initializer
250 { push_node(AST_INIT, @$.start, @$.end, 2); }
253 storage_class_specifier
254 : TYPEDEF
255 { push_node(AST_TYPEDEFKW, @$.start, @$.end, 0); }
256 | EXTERN
257 { push_node(AST_EXTERNKW, @$.start, @$.end, 0); }
258 | STATIC
259 { push_node(AST_STATICKW, @$.start, @$.end, 0); }
260 | AUTO
261 { push_node(AST_AUTOKW, @$.start, @$.end, 0); }
262 | REGISTER
263 { push_node(AST_REGISTERKW, @$.start, @$.end, 0); }
266 type_specifier
267 : VOID
268 { push_node(AST_TYPE, @$.start, @$.end, 0); }
269 | CHAR
270 { push_node(AST_TYPE, @$.start, @$.end, 0); }
271 | SHORT
272 { push_node(AST_TYPE, @$.start, @$.end, 0); }
273 | INT
274 { push_node(AST_TYPE, @$.start, @$.end, 0); }
275 | LONG
276 { push_node(AST_TYPE, @$.start, @$.end, 0); }
277 | FLOAT
278 { push_node(AST_TYPE, @$.start, @$.end, 0); }
279 | DOUBLE
280 { push_node(AST_TYPE, @$.start, @$.end, 0); }
281 | SIGNED
282 { push_node(AST_TYPE, @$.start, @$.end, 0); }
283 | UNSIGNED
284 { push_node(AST_TYPE, @$.start, @$.end, 0); }
285 | BOOL
286 { push_node(AST_TYPE, @$.start, @$.end, 0); }
287 | COMPLEX
288 { push_node(AST_TYPE, @$.start, @$.end, 0); }
289 | struct_or_union_specifier
290 { push_node(AST_TYPE, @$.start, @$.end, 1); }
291 | enum_specifier
292 { push_node(AST_TYPE, @$.start, @$.end, 1); }
293 | TYPE_NAME
294 { push_node_name(AST_TYPENAME, @$.start, @$.end, $1); }
297 struct_or_union_specifier
298 : struct_or_union identifier '{' struct_declaration_list '}'
299 { push_node(AST_STRUCT, @$.start, @$.end, 3); }
300 | struct_or_union '{' struct_declaration_list '}'
301 { push_node(AST_STRUCT, @$.start, @$.end, 2); }
302 | struct_or_union identifier
303 { push_node(AST_STRUCT, @$.start, @$.end, 2); }
306 struct_or_union
307 : STRUCT
308 { push_node(AST_STRUCTKW, @$.start, @$.end, 0); }
309 | UNION
310 { push_node(AST_UNIONKW, @$.start, @$.end, 0); }
313 struct_declaration_list
314 : struct_declaration
315 { push_node(AST_STRUCTLIST, @$.start, @$.end, 1); }
316 | struct_declaration_list struct_declaration
317 { push_node(AST_STRUCTLIST, @$.start, @$.end, 2); }
320 struct_declaration
321 : specifier_qualifier_list struct_declarator_list ';'
322 { push_node(AST_STRUCTDECL, @$.start, @$.end, 2); }
325 specifier_qualifier_list
326 : type_specifier
327 { push_node(AST_STRUCTQUALLIST, @$.start, @$.end, 1); }
328 | type_specifier specifier_qualifier_list
329 { push_node(AST_STRUCTQUALLIST, @$.start, @$.end, 2); }
330 | type_qualifier
331 { push_node(AST_STRUCTQUALLIST, @$.start, @$.end, 1); }
332 | type_qualifier specifier_qualifier_list
333 { push_node(AST_STRUCTQUALLIST, @$.start, @$.end, 2); }
336 struct_declarator_list
337 : struct_declarator
338 { push_node(AST_STRUCTDECLLIST, @$.start, @$.end, 1); }
339 | struct_declarator_list ',' struct_declarator
340 { push_node(AST_STRUCTDECLLIST, @$.start, @$.end, 2); }
343 struct_declarator
344 : declarator
345 | ':' constant_expr
346 { push_node(AST_STRUCTBITS, @$.start, @$.end, 2); }
347 | declarator ':' constant_expr
348 { push_node(AST_STRUCTBITS, @$.start, @$.end, 2); }
351 enum_specifier
352 : ENUM '{' enumerator_list '}'
353 { push_node(AST_ENUM, @$.start, @$.end, 1); }
354 | ENUM identifier '{' enumerator_list '}'
355 { push_node(AST_ENUM, @$.start, @$.end, 2); }
356 | ENUM '{' enumerator_list ',' '}'
357 { push_node(AST_ENUM, @$.start, @$.end, 1); }
358 | ENUM identifier '{' enumerator_list ',' '}'
359 { push_node(AST_ENUM, @$.start, @$.end, 2); }
360 | ENUM identifier
361 { push_node(AST_ENUM, @$.start, @$.end, 1); }
364 enumerator_list
365 : enumerator
366 { push_node(AST_ENUMLIST, @$.start, @$.end, 1); }
367 | enumerator_list ',' enumerator
368 { push_node(AST_ENUMLIST, @$.start, @$.end, 2); }
371 enumerator
372 : identifier
373 { push_node(AST_ENUMVAL, @$.start, @$.end, 1); }
374 | identifier '=' constant_expr
375 { push_node(AST_ENUMVAL, @$.start, @$.end, 2); }
378 type_qualifier
379 : CONST
380 { push_node(AST_TYPEQUAL, @$.start, @$.end, 0); }
381 | RESTRICT
382 { push_node(AST_TYPEQUAL, @$.start, @$.end, 0); }
383 | VOLATILE
384 { push_node(AST_TYPEQUAL, @$.start, @$.end, 0); }
387 function_specifier
388 : INLINE
389 { push_node(AST_FUNCSPEC, @$.start, @$.end, 0); }
392 declarator
393 : direct_declarator
394 { push_node(AST_DECL, @$.start, @$.end, 1); }
395 | pointer direct_declarator
396 { push_node(AST_DECL, @$.start, @$.end, 2); }
399 direct_declarator
400 : identifier
401 { push_decl(AST_DIRDECL, @$.start, @$.end, 1, DECL_ID); }
402 | '(' declarator ')'
403 { push_decl(AST_DIRDECL, @$.start, @$.end, 1, DECL_INPARENS); }
405 | direct_declarator '[' ']'
406 { push_decl(AST_DIRDECL, @$.start, @$.end, 1, DECL_BRACS); }
407 | direct_declarator '[' type_qualifier_list ']'
408 { push_decl(AST_DIRDECL, @$.start, @$.end, 2, DECL_BRACS_TYPE); }
409 | direct_declarator '[' assignment_expr ']'
410 { push_decl(AST_DIRDECL, @$.start, @$.end, 2, DECL_BRACS_ASSIGN); }
411 | direct_declarator '[' type_qualifier_list assignment_expr ']'
412 { push_decl(AST_DIRDECL, @$.start, @$.end, 3, DECL_BRACS_BOTH); }
414 | direct_declarator '[' STATIC assignment_expr ']'
415 { push_decl(AST_DIRDECL, @$.start, @$.end, 2, DECL_BRACS_STATIC_ASSIGN); }
416 | direct_declarator '[' STATIC type_qualifier_list assignment_expr ']'
417 { push_decl(AST_DIRDECL, @$.start, @$.end, 3, DECL_BRACS_STATIC_BOTH); }
419 | direct_declarator '[' '*' ']'
420 { push_decl(AST_DIRDECL, @$.start, @$.end, 1, DECL_BRACS_STAR); }
421 | direct_declarator '[' type_qualifier_list '*' ']'
422 { push_decl(AST_DIRDECL, @$.start, @$.end, 2, DECL_BRACS_TYPE_STAR); }
424 | direct_declarator '[' type_qualifier_list STATIC assignment_expr ']'
425 { push_decl(AST_DIRDECL, @$.start, @$.end, 3, DECL_BRACS_BOTH_STATIC); }
427 | direct_declarator '(' ')'
428 { push_decl(AST_DIRDECL, @$.start, @$.end, 1, DECL_PARENS); }
429 | direct_declarator '(' parameter_type_list ')'
430 { push_decl(AST_DIRDECL, @$.start, @$.end, 2, DECL_PARENS_TYPE); }
431 | direct_declarator '(' identifier_list ')'
432 { push_decl(AST_DIRDECL, @$.start, @$.end, 2, DECL_PARENS_ID); }
435 pointer
436 : '*'
437 { push_node(AST_PTR, @$.start, @$.end, 0); }
438 | '*' type_qualifier_list
439 { push_node(AST_PTR, @$.start, @$.end, 1); }
440 | '*' pointer
441 { push_node(AST_PTR, @$.start, @$.end, 1); }
442 | '*' type_qualifier_list pointer
443 { push_node(AST_PTR, @$.start, @$.end, 2); }
446 type_qualifier_list
447 : type_qualifier
448 { push_node(AST_TYPEQUALLIST, @$.start, @$.end, 1); }
449 | type_qualifier_list type_qualifier
450 { push_node(AST_TYPEQUALLIST, @$.start, @$.end, 2); }
453 parameter_type_list
454 : parameter_list
455 | parameter_list ',' ELIPSIS
458 parameter_list
459 : parameter_declaration
460 { push_node(AST_PARAMLIST, @$.start, @$.end, 1); }
461 | parameter_list ',' parameter_declaration
462 { push_node(AST_PARAMLIST, @$.start, @$.end, 2); }
465 parameter_declaration
466 : declaration_specifiers
467 { push_node(AST_PARAMDECL, @$.start, @$.end, 1); }
468 | declaration_specifiers declarator
469 { push_node(AST_PARAMDECL, @$.start, @$.end, 2); }
470 | declaration_specifiers abstract_declarator
471 { push_node(AST_PARAMDECL, @$.start, @$.end, 2); }
474 identifier_list
475 : identifier
476 { push_node(AST_IDLIST, @$.start, @$.end, 1); }
477 | identifier_list ',' identifier
478 { push_node(AST_IDLIST, @$.start, @$.end, 2); }
481 type_name
482 : specifier_qualifier_list
483 | specifier_qualifier_list abstract_declarator
484 { push_node(AST_ATYPE, @$.start, @$.end, 2); }
487 abstract_declarator
488 : pointer
489 | direct_abstract_declarator
490 | pointer direct_abstract_declarator
491 { push_node(AST_ADECL, @$.start, @$.end, 2); }
494 direct_abstract_declarator
495 : '(' abstract_declarator ')'
496 { push_node(AST_ADIRDECL, @$.start, @$.end, 1); }
498 | '[' ']'
499 { push_node(AST_ADIRDECL, @$.start, @$.end, 0); }
500 | '[' assignment_expr ']'
501 { push_node(AST_ADIRDECL, @$.start, @$.end, 1); }
502 | '[' type_qualifier_list ']'
503 { push_node(AST_ADIRDECL, @$.start, @$.end, 1); }
504 | '[' type_qualifier_list assignment_expr ']'
505 { push_node(AST_ADIRDECL, @$.start, @$.end, 2); }
506 | direct_abstract_declarator '[' ']'
507 { push_node(AST_ADIRDECL, @$.start, @$.end, 1); }
508 | direct_abstract_declarator '[' assignment_expr ']'
509 { push_node(AST_ADIRDECL, @$.start, @$.end, 2); }
510 | direct_abstract_declarator '[' type_qualifier_list ']'
511 { push_node(AST_ADIRDECL, @$.start, @$.end, 2); }
512 | direct_abstract_declarator '[' type_qualifier_list assignment_expr ']'
513 { push_node(AST_ADIRDECL, @$.start, @$.end, 3); }
515 | '[' type_qualifier_list STATIC assignment_expr ']'
516 { push_node(AST_ADIRDECL, @$.start, @$.end, 2); }
517 | direct_abstract_declarator '[' type_qualifier_list STATIC assignment_expr ']'
518 { push_node(AST_ADIRDECL, @$.start, @$.end, 3); }
520 | '[' '*' ']'
521 { push_node(AST_ADIRDECL, @$.start, @$.end, 0); }
522 | direct_abstract_declarator '[' '*' ']'
523 { push_node(AST_ADIRDECL, @$.start, @$.end, 1); }
525 | '(' ')'
526 { push_node(AST_ADIRDECL, @$.start, @$.end, 0); }
527 | '(' parameter_type_list ')'
528 { push_node(AST_ADIRDECL, @$.start, @$.end, 1); }
529 | direct_abstract_declarator '(' ')'
530 { push_node(AST_ADIRDECL, @$.start, @$.end, 1); }
531 | direct_abstract_declarator '(' parameter_type_list ')'
532 { push_node(AST_ADIRDECL, @$.start, @$.end, 2); }
535 initializer
536 : assignment_expr
537 | '{' initializer_list '}'
538 { push_node(AST_INITIALIZER, @$.start, @$.end, 1); }
539 | '{' initializer_list ',' '}'
540 { push_node(AST_INITIALIZER, @$.start, @$.end, 1); }
543 initializer_list
544 : initializer
545 { push_node(AST_INITIALIZERLIST, @$.start, @$.end, 1); }
546 | designation initializer
547 { push_node(AST_INITIALIZERLIST, @$.start, @$.end, 2); }
549 | initializer_list ',' initializer
550 { push_node(AST_INITIALIZERLIST, @$.start, @$.end, 2); }
551 | initializer_list ',' designation initializer
552 { push_node(AST_INITIALIZERLIST, @$.start, @$.end, 3); }
555 designation
556 : designator_list '='
557 { push_node(AST_DESIGNATION, @$.start, @$.end, 1); }
560 designator_list
561 : designator
562 { push_node(AST_DESIGLIST, @$.start, @$.end, 1); }
563 | designator_list designator
564 { push_node(AST_DESIGLIST, @$.start, @$.end, 2); }
567 designator
568 : '[' constant_expr ']'
569 { push_node(AST_DESIGNATOR, @$.start, @$.end, 1); }
570 | '.' identifier
571 { push_node(AST_DESIGNATOR, @$.start, @$.end, 1); }
573 statement
574 : labeled_statement
575 | compound_statement
576 | expression_statement
577 | selection_statement
578 | iteration_statement
579 | jump_statement
580 | macro
583 labeled_statement
584 : identifier ':' statement
585 { push_node(AST_LABELED, @$.start, @$.end, 2); }
586 | CASE constant_expr ':' statement
587 { push_node(AST_CASED, @$.start, @$.end, 2); }
588 | DEFAULT ':' statement
589 { push_node(AST_DEFAULTED, @$.start, @$.end, 1); }
592 compound_statement
593 : '{' '}'
594 { push_node(AST_BLOCK, @$.start, @$.end, 0); }
595 | '{' block_item_list '}'
596 { push_node(AST_BLOCK, @$.start, @$.end, 1); }
599 block_item_list
600 : block_item
601 { push_node(AST_BLOCKLIST, @$.start, @$.end, 1); }
602 | block_item_list block_item
603 { push_node(AST_BLOCKLIST, @$.start, @$.end, 2); }
606 block_item
607 : declaration
608 | statement
611 expression_statement
612 : ';'
613 { push_node(AST_STMT, @$.start, @$.end, 0); }
614 | expr ';'
615 { push_node(AST_STMT, @$.start, @$.end, 1); }
618 selection_statement
619 : IF '(' expr ')' statement
620 { push_node(AST_IF, @$.start, @$.end, 2); }
621 | IF '(' expr ')' statement ELSE statement
622 { push_node(AST_IF, @$.start, @$.end, 3); }
623 | SWITCH '(' expr ')' statement
624 { push_node(AST_SWITCH, @$.start, @$.end, 2); }
627 iteration_statement
628 : WHILE '(' expr ')' statement
629 { push_node(AST_WHILE, @$.start, @$.end, 2); }
630 | DO statement WHILE '(' expr ')' ';'
631 { push_node(AST_DO, @$.start, @$.end, 2); }
632 | FOR '(' ';' ';' ')' statement
633 { push_node(AST_FOR, @$.start, @$.end, 1); }
634 | FOR '(' ';' ';' expr ')' statement
635 { push_node(AST_FOR, @$.start, @$.end, 2); }
636 | FOR '(' ';' expr ';' ')' statement
637 { push_node(AST_FOR, @$.start, @$.end, 2); }
638 | FOR '(' ';' expr ';' expr ')' statement
639 { push_node(AST_FOR, @$.start, @$.end, 3); }
640 | FOR '(' expr ';' ';' ')' statement
641 { push_node(AST_FOR, @$.start, @$.end, 2); }
642 | FOR '(' expr ';' ';' expr ')' statement
643 { push_node(AST_FOR, @$.start, @$.end, 3); }
644 | FOR '(' expr ';' expr ';' ')' statement
645 { push_node(AST_FOR, @$.start, @$.end, 3); }
646 | FOR '(' expr ';' expr ';' expr ')' statement
647 { push_node(AST_FOR, @$.start, @$.end, 4); }
649 | FOR '(' declaration ';' ';' ')' statement
650 { push_node(AST_FOR, @$.start, @$.end, 2); }
651 | FOR '(' declaration ';' ';' expr ')' statement
652 { push_node(AST_FOR, @$.start, @$.end, 3); }
653 | FOR '(' declaration ';' expr ';' ')' statement
654 { push_node(AST_FOR, @$.start, @$.end, 3); }
655 | FOR '(' declaration ';' expr ';' expr ')' statement
656 { push_node(AST_FOR, @$.start, @$.end, 4); }
659 jump_statement
660 : GOTO identifier ';'
661 { push_node(AST_GOTO, @$.start, @$.end, 1); }
662 | CONTINUE ';'
663 { push_node(AST_CONTINUE, @$.start, @$.end, 0); }
664 | BREAK ';'
665 { push_node(AST_BREAK, @$.start, @$.end, 0); }
666 | RETURN ';'
667 { push_node(AST_RETURN, @$.start, @$.end, 0); }
668 | RETURN expr ';'
669 { push_node(AST_RETURN, @$.start, @$.end, 1); }
672 translation_unit
673 : external_declaration
674 { push_node(AST_FILE, @$.start, @$.end, 1); }
675 | translation_unit external_declaration
676 { push_node(AST_FILE, @$.start, @$.end, 2); }
679 external_declaration
680 : function_definition
681 | declaration
682 | macro
685 function_definition
686 : declaration_specifiers declarator compound_statement
687 { push_node(AST_FUNCTION, @$.start, @$.end, 3); }
688 | declaration_specifiers declarator declaration_list compound_statement
689 { push_node(AST_FUNCTION, @$.start, @$.end, 4); }
692 declaration_list
693 : declaration
694 { push_node(AST_DECLLIST, @$.start, @$.end, 1); }
695 | declaration_list declaration
696 { push_node(AST_DECLLIST, @$.start, @$.end, 2); }
699 macro
700 : MACRO
701 { push_node(AST_MACRO, @$.start, @$.end, 0); }
704 identifier
705 : IDENTIFIER
706 { push_node_name(AST_IDENTIFIER, @$.start, @$.end, $1); }
710 void yyerror(char *s)
712 extern long token_offset;
713 fprintf(stderr, "parsing error on %ld: %s\n", token_offset, s);