a | b/c99.y | ||
---|---|---|---|
1 | %token IDENTIFIER CONSTANT STRING_LITERAL SIZEOF |
||
2 | %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP |
||
3 | %token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN |
||
4 | %token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN |
||
5 | %token XOR_ASSIGN OR_ASSIGN TYPE_NAME |
||
6 | |||
7 | %token TYPEDEF EXTERN STATIC AUTO REGISTER INLINE RESTRICT |
||
8 | %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID |
||
9 | %token BOOL COMPLEX IMAGINARY |
||
10 | %token STRUCT UNION ENUM ELLIPSIS |
||
11 | |||
12 | %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN |
||
13 | |||
14 | %union { char str[128]; } |
||
15 | |||
16 | %start translation_unit |
||
17 | |||
18 | %{ |
||
19 | /* fifo to store expression strings */ |
||
20 | #define NULL 0 |
||
21 | |||
22 | #define STMT_SIZE 128 |
||
23 | #define FIFO_SIZE 20 |
||
24 | |||
25 | static char *s_fifo[FIFO_SIZE][STMT_SIZE]; |
||
26 | static unsigned int s_fifor, s_fifow; |
||
27 | |||
28 | void yyerror(char const *s); |
||
29 | void push(const char *psz); |
||
30 | char *pop(void); |
||
31 | |||
32 | %} |
||
33 | |||
34 | %% |
||
35 | |||
36 | primary_expression |
||
37 | : IDENTIFIER |
||
38 | | CONSTANT |
||
39 | | STRING_LITERAL |
||
40 | | '(' expression ')' |
||
41 | { sprintf($<str>$, "( %s )",$<str>2); } |
||
42 | ; |
||
43 | |||
44 | postfix_expression |
||
45 | : primary_expression |
||
46 | { sprintf($<str>$, "%s",$<str>1); } |
||
47 | | postfix_expression '[' expression ']' |
||
48 | { sprintf($<str>$, "[%s]",$<str>2); } |
||
49 | | postfix_expression '(' ')' |
||
50 | { sprintf($<str>$, "%s()",$<str>1); } |
||
51 | | postfix_expression '(' argument_expression_list ')' |
||
52 | { sprintf($<str>$, "%s(%s)",$<str>1, $<str>3); } |
||
53 | | postfix_expression '.' IDENTIFIER |
||
54 | { sprintf($<str>$, "%s.%s",$<str>1,$<str>3); } |
||
55 | | postfix_expression PTR_OP IDENTIFIER |
||
56 | { sprintf($<str>$, "%s %s %s",$<str>1, $<str>2, $<str>3);} |
||
57 | | postfix_expression INC_OP |
||
58 | { sprintf($<str>$, "(%s:=%s+1)",$<str>1, $<str>1); } |
||
59 | | postfix_expression DEC_OP |
||
60 | { sprintf($<str>$, "(%s:=%s-1)",$<str>1, $<str>1); } |
||
61 | | '(' type_name ')' '{' initializer_list '}' |
||
62 | | '(' type_name ')' '{' initializer_list ',' '}' |
||
63 | ; |
||
64 | |||
65 | argument_expression_list |
||
66 | : assignment_expression |
||
67 | | argument_expression_list ',' assignment_expression |
||
68 | { sprintf($<str>$, "%s, %s",$<str>1, $<str>3); } |
||
69 | ; |
||
70 | |||
71 | unary_expression |
||
72 | : postfix_expression |
||
73 | | INC_OP unary_expression |
||
74 | { sprintf($<str>$, "%s %s",$<str>1, $<str>2); } |
||
75 | | DEC_OP unary_expression |
||
76 | { sprintf($<str>$, "%s %s",$<str>1, $<str>2); } |
||
77 | | unary_operator cast_expression |
||
78 | { sprintf($<str>$, "%s^",$<str>2); } |
||
79 | | SIZEOF unary_expression |
||
80 | { sprintf($<str>$, "%s %s",$<str>1, $<str>2); } |
||
81 | | SIZEOF '(' type_name ')' |
||
82 | { sprintf($<str>$, "%s (%s)",$<str>1, $<str>3); } |
||
83 | ; |
||
84 | |||
85 | unary_operator |
||
86 | : '&' |
||
87 | | '*' |
||
88 | | '+' |
||
89 | | '-' |
||
90 | | '~' |
||
91 | | '!' |
||
92 | ; |
||
93 | |||
94 | cast_expression |
||
95 | : unary_expression |
||
96 | | '(' type_name ')' cast_expression |
||
97 | { sprintf($<str>$, "ANY_TO_%s(%s)",$<str>2, $<str>4); } |
||
98 | ; |
||
99 | |||
100 | multiplicative_expression |
||
101 | : cast_expression |
||
102 | | multiplicative_expression '*' cast_expression |
||
103 | { sprintf($<str>$, "%s * %s",$<str>1, $<str>3); } |
||
104 | | multiplicative_expression '/' cast_expression |
||
105 | { sprintf($<str>$, "%s / %s",$<str>1, $<str>3); } |
||
106 | | multiplicative_expression '%' cast_expression |
||
107 | { sprintf($<str>$, "%s % %s",$<str>1, $<str>3); } |
||
108 | ; |
||
109 | |||
110 | additive_expression |
||
111 | : multiplicative_expression |
||
112 | | additive_expression '+' multiplicative_expression |
||
113 | { sprintf($<str>$, "%s + %s",$<str>1, $<str>3); } |
||
114 | | additive_expression '-' multiplicative_expression |
||
115 | { sprintf($<str>$, "%s - %s",$<str>1, $<str>3); } |
||
116 | ; |
||
117 | |||
118 | shift_expression |
||
119 | : additive_expression |
||
120 | | shift_expression LEFT_OP additive_expression |
||
121 | { sprintf($<str>$, "SHL(%s, %s)",$<str>1, $<str>3); } |
||
122 | | shift_expression RIGHT_OP additive_expression |
||
123 | { sprintf($<str>$, "SHR(%s, %s)",$<str>1, $<str>3); } |
||
124 | ; |
||
125 | |||
126 | relational_expression : shift_expression |
||
127 | | relational_expression '<' shift_expression |
||
128 | { sprintf($<str>$, "%s < %s",$<str>1, $<str>3); } |
||
129 | | relational_expression '>' shift_expression |
||
130 | { sprintf($<str>$, "%s > %s",$<str>1, $<str>3); } |
||
131 | | relational_expression LE_OP shift_expression |
||
132 | { sprintf($<str>$, "%s <= %s",$<str>1, $<str>3); } |
||
133 | | relational_expression GE_OP shift_expression |
||
134 | { sprintf($<str>$, "%s >= %s",$<str>1, $<str>3); } |
||
135 | ; |
||
136 | |||
137 | equality_expression |
||
138 | : relational_expression |
||
139 | | equality_expression EQ_OP relational_expression |
||
140 | { sprintf($<str>$, "%s = %s",$<str>1, $<str>3); } |
||
141 | | equality_expression NE_OP relational_expression |
||
142 | { sprintf($<str>$, "%s <> %s",$<str>1, $<str>3); } |
||
143 | ; |
||
144 | |||
145 | and_expression |
||
146 | : equality_expression |
||
147 | | and_expression '&' equality_expression |
||
148 | { sprintf($<str>$, "%s AND %s",$<str>1, $<str>3); } |
||
149 | ; |
||
150 | |||
151 | exclusive_or_expression |
||
152 | : and_expression |
||
153 | | exclusive_or_expression '^' and_expression |
||
154 | { sprintf($<str>$, "%s XOR %s",$<str>1, $<str>3); } |
||
155 | ; |
||
156 | |||
157 | inclusive_or_expression |
||
158 | : exclusive_or_expression |
||
159 | | inclusive_or_expression '|' exclusive_or_expression |
||
160 | { sprintf($<str>$, "%s OR %s",$<str>1, $<str>3); } |
||
161 | ; |
||
162 | |||
163 | logical_and_expression |
||
164 | : inclusive_or_expression |
||
165 | | logical_and_expression AND_OP inclusive_or_expression |
||
166 | { sprintf($<str>$, "%s AND %s",$<str>1, $<str>3); } |
||
167 | ; |
||
168 | |||
169 | logical_or_expression |
||
170 | : logical_and_expression |
||
171 | | logical_or_expression OR_OP logical_and_expression |
||
172 | { sprintf($<str>$, "%s OR %s",$<str>1, $<str>3); } |
||
173 | ; |
||
174 | |||
175 | conditional_expression |
||
176 | : logical_or_expression |
||
177 | | logical_or_expression '?' expression ':' conditional_expression |
||
178 | ; |
||
179 | |||
180 | assignment_expression |
||
181 | : conditional_expression |
||
182 | | unary_expression assignment_operator assignment_expression |
||
183 | { sprintf($<str>$, "%s %s %s",$<str>1, $<str>2, $<str>3); } |
||
184 | ; |
||
185 | |||
186 | assignment_operator |
||
187 | : '=' |
||
188 | { sprintf($<str>$, ":="); } |
||
189 | | MUL_ASSIGN |
||
190 | | DIV_ASSIGN |
||
191 | | MOD_ASSIGN |
||
192 | | ADD_ASSIGN |
||
193 | | SUB_ASSIGN |
||
194 | | LEFT_ASSIGN |
||
195 | | RIGHT_ASSIGN |
||
196 | | AND_ASSIGN |
||
197 | | XOR_ASSIGN |
||
198 | | OR_ASSIGN |
||
199 | ; |
||
200 | |||
201 | expression |
||
202 | : assignment_expression |
||
203 | | expression ',' assignment_expression |
||
204 | ; |
||
205 | |||
206 | constant_expression |
||
207 | : conditional_expression |
||
208 | ; |
||
209 | |||
210 | declaration |
||
211 | : declaration_specifiers ';' |
||
212 | { sprintf($<str>$, "%s %s",$<str>1, $<str>2); } |
||
213 | | declaration_specifiers init_declarator_list ';' |
||
214 | { char *p; while( (p=pop()) != NULL) { printf(p, $<str>1); strcpy($<str>$, ""); } } |
||
215 | ; |
||
216 | |||
217 | declaration_specifiers |
||
218 | : storage_class_specifier |
||
219 | | storage_class_specifier declaration_specifiers |
||
220 | { sprintf($<str>$, "%s %s",$<str>1, $<str>2); } |
||
221 | | type_specifier |
||
222 | | type_specifier declaration_specifiers |
||
223 | { sprintf($<str>$, "%s %s",$<str>1, $<str>2); } |
||
224 | | type_qualifier |
||
225 | | type_qualifier declaration_specifiers |
||
226 | { sprintf($<str>$, "%s %s",$<str>1, $<str>2); } |
||
227 | | function_specifier |
||
228 | | function_specifier declaration_specifiers |
||
229 | { sprintf($<str>$, "%s %s",$<str>1, $<str>2); } |
||
230 | ; |
||
231 | |||
232 | init_declarator_list |
||
233 | : init_declarator |
||
234 | | init_declarator_list ',' init_declarator |
||
235 | { sprintf($<str>$, "%s, %s",$<str>1, $<str>3); } |
||
236 | ; |
||
237 | |||
238 | init_declarator |
||
239 | : declarator |
||
240 | | declarator '=' initializer |
||
241 | { sprintf($<str>$, "%s = %s",$<str>1, $<str>3); } |
||
242 | ; |
||
243 | |||
244 | storage_class_specifier |
||
245 | : TYPEDEF |
||
246 | | EXTERN |
||
247 | | STATIC |
||
248 | | AUTO |
||
249 | | REGISTER |
||
250 | ; |
||
251 | |||
252 | type_specifier |
||
253 | : VOID |
||
254 | | CHAR |
||
255 | | SHORT |
||
256 | | INT |
||
257 | | LONG |
||
258 | | FLOAT |
||
259 | | DOUBLE |
||
260 | | SIGNED |
||
261 | | UNSIGNED |
||
262 | | BOOL |
||
263 | | COMPLEX |
||
264 | | IMAGINARY |
||
265 | | struct_or_union_specifier |
||
266 | | enum_specifier |
||
267 | | TYPE_NAME |
||
268 | ; |
||
269 | |||
270 | struct_or_union_specifier |
||
271 | : struct_or_union IDENTIFIER '{' struct_declaration_list '}' |
||
272 | | struct_or_union '{' struct_declaration_list '}' |
||
273 | | struct_or_union IDENTIFIER |
||
274 | ; |
||
275 | |||
276 | struct_or_union |
||
277 | : STRUCT |
||
278 | | UNION |
||
279 | ; |
||
280 | |||
281 | struct_declaration_list |
||
282 | : struct_declaration |
||
283 | | struct_declaration_list struct_declaration |
||
284 | { sprintf($<str>$, "%s %s",$<str>1, $<str>2); } |
||
285 | ; |
||
286 | |||
287 | struct_declaration |
||
288 | : specifier_qualifier_list struct_declarator_list ';' |
||
289 | { sprintf($<str>$, "%s %s",$<str>1, $<str>2); } |
||
290 | ; |
||
291 | |||
292 | specifier_qualifier_list |
||
293 | : type_specifier specifier_qualifier_list |
||
294 | { sprintf($<str>$, "%s %s",$<str>1, $<str>2); } |
||
295 | | type_specifier |
||
296 | | type_qualifier specifier_qualifier_list |
||
297 | { sprintf($<str>$, "%s %s",$<str>1, $<str>2); } |
||
298 | | type_qualifier |
||
299 | ; |
||
300 | |||
301 | struct_declarator_list |
||
302 | : struct_declarator |
||
303 | | struct_declarator_list ',' struct_declarator |
||
304 | { sprintf($<str>$, "%s, %s",$<str>1, $<str>3); } |
||
305 | ; |
||
306 | |||
307 | struct_declarator |
||
308 | : declarator |
||
309 | | ':' constant_expression |
||
310 | | declarator ':' constant_expression |
||
311 | ; |
||
312 | |||
313 | enum_specifier |
||
314 | : ENUM '{' enumerator_list '}' |
||
315 | | ENUM IDENTIFIER '{' enumerator_list '}' |
||
316 | | ENUM '{' enumerator_list ',' '}' |
||
317 | | ENUM IDENTIFIER '{' enumerator_list ',' '}' |
||
318 | | ENUM IDENTIFIER |
||
319 | ; |
||
320 | |||
321 | enumerator_list |
||
322 | : enumerator |
||
323 | | enumerator_list ',' enumerator |
||
324 | ; |
||
325 | |||
326 | enumerator |
||
327 | : IDENTIFIER |
||
328 | | IDENTIFIER '=' constant_expression |
||
329 | ; |
||
330 | |||
331 | type_qualifier |
||
332 | : CONST |
||
333 | | RESTRICT |
||
334 | | VOLATILE |
||
335 | ; |
||
336 | |||
337 | function_specifier : INLINE |
||
338 | ; |
||
339 | |||
340 | declarator |
||
341 | : pointer direct_declarator |
||
342 | { |
||
343 | sprintf($<str>$, "%s POINTER TO %%s;\n",$<str>2); |
||
344 | push($<str>$); |
||
345 | } |
||
346 | | direct_declarator |
||
347 | { |
||
348 | if (strlen($<str>1) > 0) |
||
349 | { |
||
350 | sprintf($<str>$, "%s %%s;\n",$<str>1); |
||
351 | push($<str>$); |
||
352 | } |
||
353 | } |
||
354 | ; |
||
355 | |||
356 | direct_declarator |
||
357 | : IDENTIFIER |
||
358 | // { sprintf($<str>$, "%s: %%s;\n",$<str>1); push($<str>$);} |
||
359 | | '(' declarator ')' |
||
360 | | direct_declarator '[' type_qualifier_list assignment_expression ']' |
||
361 | | direct_declarator '[' type_qualifier_list ']' |
||
362 | | direct_declarator '[' assignment_expression ']' |
||
363 | { |
||
364 | sprintf($<str>$, "%s: ARRAY[ %s ] OF %%s;\n",$<str>1, $<str>3); |
||
365 | push($<str>$); |
||
366 | strcpy($<str>$, ""); |
||
367 | } |
||
368 | | direct_declarator '[' STATIC type_qualifier_list assignment_expression ']' |
||
369 | | direct_declarator '[' type_qualifier_list STATIC assignment_expression ']' |
||
370 | | direct_declarator '[' type_qualifier_list '*' ']' |
||
371 | | direct_declarator '[' '*' ']' |
||
372 | | direct_declarator '[' ']' |
||
373 | | direct_declarator '(' parameter_type_list ')' |
||
374 | { sprintf($<str>$, "FUNCTION %s:",$<str>1); } |
||
375 | | direct_declarator '(' identifier_list ')' |
||
376 | { sprintf($<str>$, "FUNCTION %s:",$<str>1); } |
||
377 | | direct_declarator '(' ')' |
||
378 | { sprintf($<str>$, "FUNCTION %s:",$<str>1); } |
||
379 | ; |
||
380 | |||
381 | pointer |
||
382 | : '*' |
||
383 | | '*' type_qualifier_list |
||
384 | | '*' pointer |
||
385 | | '*' type_qualifier_list pointer |
||
386 | ; |
||
387 | |||
388 | type_qualifier_list |
||
389 | : type_qualifier |
||
390 | | type_qualifier_list type_qualifier |
||
391 | ; |
||
392 | |||
393 | |||
394 | parameter_type_list |
||
395 | : parameter_list |
||
396 | | parameter_list ',' ELLIPSIS |
||
397 | ; |
||
398 | |||
399 | parameter_list |
||
400 | : parameter_declaration |
||
401 | | parameter_list ',' parameter_declaration |
||
402 | ; |
||
403 | |||
404 | parameter_declaration |
||
405 | : declaration_specifiers declarator |
||
406 | | declaration_specifiers abstract_declarator |
||
407 | | declaration_specifiers |
||
408 | ; |
||
409 | |||
410 | identifier_list |
||
411 | : IDENTIFIER |
||
412 | | identifier_list ',' IDENTIFIER |
||
413 | ; |
||
414 | |||
415 | type_name |
||
416 | : specifier_qualifier_list |
||
417 | | specifier_qualifier_list abstract_declarator |
||
418 | ; |
||
419 | |||
420 | abstract_declarator |
||
421 | : pointer |
||
422 | | direct_abstract_declarator |
||
423 | | pointer direct_abstract_declarator |
||
424 | ; |
||
425 | |||
426 | direct_abstract_declarator |
||
427 | : '(' abstract_declarator ')' |
||
428 | | '[' ']' |
||
429 | | '[' assignment_expression ']' |
||
430 | | direct_abstract_declarator '[' ']' |
||
431 | | direct_abstract_declarator '[' assignment_expression ']' |
||
432 | | '[' '*' ']' |
||
433 | | direct_abstract_declarator '[' '*' ']' |
||
434 | | '(' ')' |
||
435 | | '(' parameter_type_list ')' |
||
436 | | direct_abstract_declarator '(' ')' |
||
437 | | direct_abstract_declarator '(' parameter_type_list ')' |
||
438 | ; |
||
439 | |||
440 | initializer |
||
441 | : assignment_expression |
||
442 | | '{' initializer_list '}' |
||
443 | | '{' initializer_list ',' '}' |
||
444 | ; |
||
445 | |||
446 | initializer_list |
||
447 | : initializer |
||
448 | | designation initializer |
||
449 | | initializer_list ',' initializer |
||
450 | | initializer_list ',' designation initializer |
||
451 | ; |
||
452 | |||
453 | designation |
||
454 | : designator_list '=' |
||
455 | ; |
||
456 | |||
457 | designator_list |
||
458 | : designator |
||
459 | | designator_list designator |
||
460 | ; |
||
461 | |||
462 | designator |
||
463 | : '[' constant_expression ']' |
||
464 | | '.' IDENTIFIER |
||
465 | ; |
||
466 | |||
467 | statement |
||
468 | : labeled_statement |
||
469 | | compound_statement |
||
470 | | expression_statement |
||
471 | | selection_statement |
||
472 | | iteration_statement |
||
473 | | jump_statement |
||
474 | ; |
||
475 | |||
476 | labeled_statement |
||
477 | : IDENTIFIER ':' statement |
||
478 | | CASE constant_expression ':' statement |
||
479 | | DEFAULT ':' statement |
||
480 | ; |
||
481 | |||
482 | compound_statement |
||
483 | : '{' '}' |
||
484 | | '{' block_item_list '}' |
||
485 | ; |
||
486 | |||
487 | block_item_list |
||
488 | : block_item |
||
489 | | block_item_list block_item |
||
490 | ; |
||
491 | |||
492 | block_item |
||
493 | : declaration |
||
494 | | statement |
||
495 | { printf("%s\n",$<str>1); } |
||
496 | ; |
||
497 | |||
498 | expression_statement |
||
499 | : ';' |
||
500 | | expression ';' |
||
501 | { sprintf($<str>$, "%s;",$<str>1); } |
||
502 | ; |
||
503 | |||
504 | selection_statement |
||
505 | : IF '(' expression ')' statement |
||
506 | | IF '(' expression ')' statement ELSE statement |
||
507 | | SWITCH '(' expression ')' statement |
||
508 | ; |
||
509 | |||
510 | iteration_statement |
||
511 | : WHILE '(' expression ')' statement |
||
512 | | DO statement WHILE '(' expression ')' ';' |
||
513 | | FOR '(' expression_statement expression_statement ')' statement |
||
514 | | FOR '(' expression_statement expression_statement expression ')' statement |
||
515 | | FOR '(' declaration expression_statement ')' statement |
||
516 | | FOR '(' declaration expression_statement expression ')' statement |
||
517 | ; |
||
518 | |||
519 | jump_statement |
||
520 | : GOTO IDENTIFIER ';' |
||
521 | | CONTINUE ';' |
||
522 | | BREAK ';' |
||
523 | | RETURN ';' |
||
524 | | RETURN expression ';' |
||
525 | ; |
||
526 | |||
527 | translation_unit |
||
528 | : external_declaration |
||
529 | | translation_unit external_declaration |
||
530 | ; |
||
531 | |||
532 | external_declaration |
||
533 | : function_definition |
||
534 | | declaration |
||
535 | ; |
||
536 | |||
537 | function_definition |
||
538 | : declaration_specifiers declarator declaration_list compound_statement |
||
539 | | declaration_specifiers declarator compound_statement |
||
540 | ; |
||
541 | |||
542 | declaration_list |
||
543 | : declaration |
||
544 | | declaration_list declaration |
||
545 | { printf("| %s %s\n",$<str>1, $<str>2); } |
||
546 | ; |
||
547 | |||
548 | |||
549 | %% |
||
550 | #include <stdio.h> |
||
551 | |||
552 | extern char yytext[]; |
||
553 | extern int column; |
||
554 | |||
555 | void yyerror(char const *s) |
||
556 | { |
||
557 | fflush(stdout); |
||
558 | printf("\n%*s\n%*s\n", column, "^", column, s); |
||
559 | } |
||
560 | |||
561 | int main(void) |
||
562 | { |
||
563 | yyparse(); |
||
564 | return 0; |
||
565 | } |
||
566 | |||
567 | |||
568 | /* fifo implementation */ |
||
569 | void push(const char *psz) |
||
570 | { |
||
571 | unsigned int fifow_next = (s_fifow + 1) % FIFO_SIZE; |
||
572 | if (fifow_next != s_fifor) |
||
573 | { |
||
574 | //s_fifo[s_fifow] = psz; |
||
575 | strcpy(s_fifo[s_fifow], psz); |
||
576 | s_fifow = fifow_next; |
||
577 | } |
||
578 | } |
||
579 | |||
580 | char *pop(void) |
||
581 | { |
||
582 | unsigned int fifor_prev; |
||
583 | if (s_fifor != s_fifow) |
||
584 | { |
||
585 | fifor_prev = s_fifor; |
||
586 | s_fifor = (s_fifor + 1) % FIFO_SIZE; |
||
587 | return s_fifo[fifor_prev]; |
||
588 | } |
||
589 | return NULL; |
||
590 | } |
||
591 |