1 # -----------------------------------------------------------------------------
4 # Simple parser for ANSI C. Based on the grammar in K&R, 2nd Ed.
5 # -----------------------------------------------------------------------------
9 import ply
.yacc
as yacc
16 def p_translation_unit_1(t
):
17 'translation_unit : external_declaration'
20 def p_translation_unit_2(t
):
21 'translation_unit : translation_unit external_declaration'
24 # external-declaration:
26 def p_external_declaration_1(t
):
27 'external_declaration : function_definition'
30 def p_external_declaration_2(t
):
31 'external_declaration : declaration'
34 # function-definition:
36 def p_function_definition_1(t
):
37 'function_definition : declaration_specifiers declarator declaration_list compound_statement'
40 def p_function_definition_2(t
):
41 'function_definition : declarator declaration_list compound_statement'
44 def p_function_definition_3(t
):
45 'function_definition : declarator compound_statement'
48 def p_function_definition_4(t
):
49 'function_definition : declaration_specifiers declarator compound_statement'
54 def p_declaration_1(t
):
55 'declaration : declaration_specifiers init_declarator_list SEMI'
58 def p_declaration_2(t
):
59 'declaration : declaration_specifiers SEMI'
64 def p_declaration_list_1(t
):
65 'declaration_list : declaration'
68 def p_declaration_list_2(t
):
69 'declaration_list : declaration_list declaration '
72 # declaration-specifiers
73 def p_declaration_specifiers_1(t
):
74 'declaration_specifiers : storage_class_specifier declaration_specifiers'
77 def p_declaration_specifiers_2(t
):
78 'declaration_specifiers : type_specifier declaration_specifiers'
81 def p_declaration_specifiers_3(t
):
82 'declaration_specifiers : type_qualifier declaration_specifiers'
85 def p_declaration_specifiers_4(t
):
86 'declaration_specifiers : storage_class_specifier'
89 def p_declaration_specifiers_5(t
):
90 'declaration_specifiers : type_specifier'
93 def p_declaration_specifiers_6(t
):
94 'declaration_specifiers : type_qualifier'
97 # storage-class-specifier
98 def p_storage_class_specifier(t
):
99 '''storage_class_specifier : AUTO
108 def p_type_specifier(t
):
109 '''type_specifier : VOID
118 | struct_or_union_specifier
125 def p_type_qualifier(t
):
126 '''type_qualifier : CONST
130 # struct-or-union-specifier
132 def p_struct_or_union_specifier_1(t
):
133 'struct_or_union_specifier : struct_or_union ID LBRACE struct_declaration_list RBRACE'
136 def p_struct_or_union_specifier_2(t
):
137 'struct_or_union_specifier : struct_or_union LBRACE struct_declaration_list RBRACE'
140 def p_struct_or_union_specifier_3(t
):
141 'struct_or_union_specifier : struct_or_union ID'
145 def p_struct_or_union(t
):
146 '''struct_or_union : STRUCT
151 # struct-declaration-list:
153 def p_struct_declaration_list_1(t
):
154 'struct_declaration_list : struct_declaration'
157 def p_struct_declaration_list_2(t
):
158 'struct_declaration_list : struct_declarator_list struct_declaration'
161 # init-declarator-list:
163 def p_init_declarator_list_1(t
):
164 'init_declarator_list : init_declarator'
167 def p_init_declarator_list_2(t
):
168 'init_declarator_list : init_declarator_list COMMA init_declarator'
173 def p_init_declarator_1(t
):
174 'init_declarator : declarator'
177 def p_init_declarator_2(t
):
178 'init_declarator : declarator EQUALS initializer'
181 # struct-declaration:
183 def p_struct_declaration(t
):
184 'struct_declaration : specifier_qualifier_list struct_declarator_list SEMI'
187 # specifier-qualifier-list:
189 def p_specifier_qualifier_list_1(t
):
190 'specifier_qualifier_list : type_specifier specifier_qualifier_list'
193 def p_specifier_qualifier_list_2(t
):
194 'specifier_qualifier_list : type_specifier'
197 def p_specifier_qualifier_list_3(t
):
198 'specifier_qualifier_list : type_qualifier specifier_qualifier_list'
201 def p_specifier_qualifier_list_4(t
):
202 'specifier_qualifier_list : type_qualifier'
205 # struct-declarator-list:
207 def p_struct_declarator_list_1(t
):
208 'struct_declarator_list : struct_declarator'
211 def p_struct_declarator_list_2(t
):
212 'struct_declarator_list : struct_declarator_list COMMA struct_declarator'
217 def p_struct_declarator_1(t
):
218 'struct_declarator : declarator'
221 def p_struct_declarator_2(t
):
222 'struct_declarator : declarator COLON constant_expression'
225 def p_struct_declarator_3(t
):
226 'struct_declarator : COLON constant_expression'
231 def p_enum_specifier_1(t
):
232 'enum_specifier : ENUM ID LBRACE enumerator_list RBRACE'
235 def p_enum_specifier_2(t
):
236 'enum_specifier : ENUM LBRACE enumerator_list RBRACE'
239 def p_enum_specifier_3(t
):
240 'enum_specifier : ENUM ID'
244 def p_enumerator_list_1(t
):
245 'enumerator_list : enumerator'
248 def p_enumerator_list_2(t
):
249 'enumerator_list : enumerator_list COMMA enumerator'
253 def p_enumerator_1(t
):
257 def p_enumerator_2(t
):
258 'enumerator : ID EQUALS constant_expression'
263 def p_declarator_1(t
):
264 'declarator : pointer direct_declarator'
267 def p_declarator_2(t
):
268 'declarator : direct_declarator'
273 def p_direct_declarator_1(t
):
274 'direct_declarator : ID'
277 def p_direct_declarator_2(t
):
278 'direct_declarator : LPAREN declarator RPAREN'
281 def p_direct_declarator_3(t
):
282 'direct_declarator : direct_declarator LBRACKET constant_expression_opt RBRACKET'
285 def p_direct_declarator_4(t
):
286 'direct_declarator : direct_declarator LPAREN parameter_type_list RPAREN '
289 def p_direct_declarator_5(t
):
290 'direct_declarator : direct_declarator LPAREN identifier_list RPAREN '
293 def p_direct_declarator_6(t
):
294 'direct_declarator : direct_declarator LPAREN RPAREN '
299 'pointer : TIMES type_qualifier_list'
307 'pointer : TIMES type_qualifier_list pointer'
311 'pointer : TIMES pointer'
314 # type-qualifier-list:
316 def p_type_qualifier_list_1(t
):
317 'type_qualifier_list : type_qualifier'
320 def p_type_qualifier_list_2(t
):
321 'type_qualifier_list : type_qualifier_list type_qualifier'
324 # parameter-type-list:
326 def p_parameter_type_list_1(t
):
327 'parameter_type_list : parameter_list'
330 def p_parameter_type_list_2(t
):
331 'parameter_type_list : parameter_list COMMA ELLIPSIS'
336 def p_parameter_list_1(t
):
337 'parameter_list : parameter_declaration'
340 def p_parameter_list_2(t
):
341 'parameter_list : parameter_list COMMA parameter_declaration'
344 # parameter-declaration:
345 def p_parameter_declaration_1(t
):
346 'parameter_declaration : declaration_specifiers declarator'
349 def p_parameter_declaration_2(t
):
350 'parameter_declaration : declaration_specifiers abstract_declarator_opt'
354 def p_identifier_list_1(t
):
355 'identifier_list : ID'
358 def p_identifier_list_2(t
):
359 'identifier_list : identifier_list COMMA ID'
364 def p_initializer_1(t
):
365 'initializer : assignment_expression'
368 def p_initializer_2(t
):
369 '''initializer : LBRACE initializer_list RBRACE
370 | LBRACE initializer_list COMMA RBRACE'''
375 def p_initializer_list_1(t
):
376 'initializer_list : initializer'
379 def p_initializer_list_2(t
):
380 'initializer_list : initializer_list COMMA initializer'
386 'type_name : specifier_qualifier_list abstract_declarator_opt'
389 def p_abstract_declarator_opt_1(t
):
390 'abstract_declarator_opt : empty'
393 def p_abstract_declarator_opt_2(t
):
394 'abstract_declarator_opt : abstract_declarator'
397 # abstract-declarator:
399 def p_abstract_declarator_1(t
):
400 'abstract_declarator : pointer '
403 def p_abstract_declarator_2(t
):
404 'abstract_declarator : pointer direct_abstract_declarator'
407 def p_abstract_declarator_3(t
):
408 'abstract_declarator : direct_abstract_declarator'
411 # direct-abstract-declarator:
413 def p_direct_abstract_declarator_1(t
):
414 'direct_abstract_declarator : LPAREN abstract_declarator RPAREN'
417 def p_direct_abstract_declarator_2(t
):
418 'direct_abstract_declarator : direct_abstract_declarator LBRACKET constant_expression_opt RBRACKET'
421 def p_direct_abstract_declarator_3(t
):
422 'direct_abstract_declarator : LBRACKET constant_expression_opt RBRACKET'
425 def p_direct_abstract_declarator_4(t
):
426 'direct_abstract_declarator : direct_abstract_declarator LPAREN parameter_type_list_opt RPAREN'
429 def p_direct_abstract_declarator_5(t
):
430 'direct_abstract_declarator : LPAREN parameter_type_list_opt RPAREN'
433 # Optional fields in abstract declarators
435 def p_constant_expression_opt_1(t
):
436 'constant_expression_opt : empty'
439 def p_constant_expression_opt_2(t
):
440 'constant_expression_opt : constant_expression'
443 def p_parameter_type_list_opt_1(t
):
444 'parameter_type_list_opt : empty'
447 def p_parameter_type_list_opt_2(t
):
448 'parameter_type_list_opt : parameter_type_list'
455 statement : labeled_statement
456 | expression_statement
458 | selection_statement
459 | iteration_statement
466 def p_labeled_statement_1(t
):
467 'labeled_statement : ID COLON statement'
470 def p_labeled_statement_2(t
):
471 'labeled_statement : CASE constant_expression COLON statement'
474 def p_labeled_statement_3(t
):
475 'labeled_statement : DEFAULT COLON statement'
478 # expression-statement:
479 def p_expression_statement(t
):
480 'expression_statement : expression_opt SEMI'
483 # compound-statement:
485 def p_compound_statement_1(t
):
486 'compound_statement : LBRACE declaration_list statement_list RBRACE'
489 def p_compound_statement_2(t
):
490 'compound_statement : LBRACE statement_list RBRACE'
493 def p_compound_statement_3(t
):
494 'compound_statement : LBRACE declaration_list RBRACE'
497 def p_compound_statement_4(t
):
498 'compound_statement : LBRACE RBRACE'
503 def p_statement_list_1(t
):
504 'statement_list : statement'
507 def p_statement_list_2(t
):
508 'statement_list : statement_list statement'
511 # selection-statement
513 def p_selection_statement_1(t
):
514 'selection_statement : IF LPAREN expression RPAREN statement'
517 def p_selection_statement_2(t
):
518 'selection_statement : IF LPAREN expression RPAREN statement ELSE statement '
521 def p_selection_statement_3(t
):
522 'selection_statement : SWITCH LPAREN expression RPAREN statement '
525 # iteration_statement:
527 def p_iteration_statement_1(t
):
528 'iteration_statement : WHILE LPAREN expression RPAREN statement'
531 def p_iteration_statement_2(t
):
532 'iteration_statement : FOR LPAREN expression_opt SEMI expression_opt SEMI expression_opt RPAREN statement '
535 def p_iteration_statement_3(t
):
536 'iteration_statement : DO statement WHILE LPAREN expression RPAREN SEMI'
541 def p_jump_statement_1(t
):
542 'jump_statement : GOTO ID SEMI'
545 def p_jump_statement_2(t
):
546 'jump_statement : CONTINUE SEMI'
549 def p_jump_statement_3(t
):
550 'jump_statement : BREAK SEMI'
553 def p_jump_statement_4(t
):
554 'jump_statement : RETURN expression_opt SEMI'
557 def p_expression_opt_1(t
):
558 'expression_opt : empty'
561 def p_expression_opt_2(t
):
562 'expression_opt : expression'
566 def p_expression_1(t
):
567 'expression : assignment_expression'
570 def p_expression_2(t
):
571 'expression : expression COMMA assignment_expression'
574 # assigment_expression:
575 def p_assignment_expression_1(t
):
576 'assignment_expression : conditional_expression'
579 def p_assignment_expression_2(t
):
580 'assignment_expression : unary_expression assignment_operator assignment_expression'
583 # assignment_operator:
584 def p_assignment_operator(t
):
586 assignment_operator : EQUALS
600 # conditional-expression
601 def p_conditional_expression_1(t
):
602 'conditional_expression : logical_or_expression'
605 def p_conditional_expression_2(t
):
606 'conditional_expression : logical_or_expression CONDOP expression COLON conditional_expression '
609 # constant-expression
611 def p_constant_expression(t
):
612 'constant_expression : conditional_expression'
615 # logical-or-expression
617 def p_logical_or_expression_1(t
):
618 'logical_or_expression : logical_and_expression'
621 def p_logical_or_expression_2(t
):
622 'logical_or_expression : logical_or_expression LOR logical_and_expression'
625 # logical-and-expression
627 def p_logical_and_expression_1(t
):
628 'logical_and_expression : inclusive_or_expression'
631 def p_logical_and_expression_2(t
):
632 'logical_and_expression : logical_and_expression LAND inclusive_or_expression'
635 # inclusive-or-expression:
637 def p_inclusive_or_expression_1(t
):
638 'inclusive_or_expression : exclusive_or_expression'
641 def p_inclusive_or_expression_2(t
):
642 'inclusive_or_expression : inclusive_or_expression OR exclusive_or_expression'
645 # exclusive-or-expression:
647 def p_exclusive_or_expression_1(t
):
648 'exclusive_or_expression : and_expression'
651 def p_exclusive_or_expression_2(t
):
652 'exclusive_or_expression : exclusive_or_expression XOR and_expression'
657 def p_and_expression_1(t
):
658 'and_expression : equality_expression'
661 def p_and_expression_2(t
):
662 'and_expression : and_expression AND equality_expression'
666 # equality-expression:
667 def p_equality_expression_1(t
):
668 'equality_expression : relational_expression'
671 def p_equality_expression_2(t
):
672 'equality_expression : equality_expression EQ relational_expression'
675 def p_equality_expression_3(t
):
676 'equality_expression : equality_expression NE relational_expression'
680 # relational-expression:
681 def p_relational_expression_1(t
):
682 'relational_expression : shift_expression'
685 def p_relational_expression_2(t
):
686 'relational_expression : relational_expression LT shift_expression'
689 def p_relational_expression_3(t
):
690 'relational_expression : relational_expression GT shift_expression'
693 def p_relational_expression_4(t
):
694 'relational_expression : relational_expression LE shift_expression'
697 def p_relational_expression_5(t
):
698 'relational_expression : relational_expression GE shift_expression'
703 def p_shift_expression_1(t
):
704 'shift_expression : additive_expression'
707 def p_shift_expression_2(t
):
708 'shift_expression : shift_expression LSHIFT additive_expression'
711 def p_shift_expression_3(t
):
712 'shift_expression : shift_expression RSHIFT additive_expression'
715 # additive-expression
717 def p_additive_expression_1(t
):
718 'additive_expression : multiplicative_expression'
721 def p_additive_expression_2(t
):
722 'additive_expression : additive_expression PLUS multiplicative_expression'
725 def p_additive_expression_3(t
):
726 'additive_expression : additive_expression MINUS multiplicative_expression'
729 # multiplicative-expression
731 def p_multiplicative_expression_1(t
):
732 'multiplicative_expression : cast_expression'
735 def p_multiplicative_expression_2(t
):
736 'multiplicative_expression : multiplicative_expression TIMES cast_expression'
739 def p_multiplicative_expression_3(t
):
740 'multiplicative_expression : multiplicative_expression DIVIDE cast_expression'
743 def p_multiplicative_expression_4(t
):
744 'multiplicative_expression : multiplicative_expression MOD cast_expression'
749 def p_cast_expression_1(t
):
750 'cast_expression : unary_expression'
753 def p_cast_expression_2(t
):
754 'cast_expression : LPAREN type_name RPAREN cast_expression'
758 def p_unary_expression_1(t
):
759 'unary_expression : postfix_expression'
762 def p_unary_expression_2(t
):
763 'unary_expression : PLUSPLUS unary_expression'
766 def p_unary_expression_3(t
):
767 'unary_expression : MINUSMINUS unary_expression'
770 def p_unary_expression_4(t
):
771 'unary_expression : unary_operator cast_expression'
774 def p_unary_expression_5(t
):
775 'unary_expression : SIZEOF unary_expression'
778 def p_unary_expression_6(t
):
779 'unary_expression : SIZEOF LPAREN type_name RPAREN'
783 def p_unary_operator(t
):
784 '''unary_operator : AND
792 # postfix-expression:
793 def p_postfix_expression_1(t
):
794 'postfix_expression : primary_expression'
797 def p_postfix_expression_2(t
):
798 'postfix_expression : postfix_expression LBRACKET expression RBRACKET'
801 def p_postfix_expression_3(t
):
802 'postfix_expression : postfix_expression LPAREN argument_expression_list RPAREN'
805 def p_postfix_expression_4(t
):
806 'postfix_expression : postfix_expression LPAREN RPAREN'
809 def p_postfix_expression_5(t
):
810 'postfix_expression : postfix_expression PERIOD ID'
813 def p_postfix_expression_6(t
):
814 'postfix_expression : postfix_expression ARROW ID'
817 def p_postfix_expression_7(t
):
818 'postfix_expression : postfix_expression PLUSPLUS'
821 def p_postfix_expression_8(t
):
822 'postfix_expression : postfix_expression MINUSMINUS'
825 # primary-expression:
826 def p_primary_expression(t
):
827 '''primary_expression : ID
830 | LPAREN expression RPAREN'''
833 # argument-expression-list:
834 def p_argument_expression_list(t
):
835 '''argument_expression_list : assignment_expression
836 | argument_expression_list COMMA assignment_expression'''
852 print "Whoa. We're hosed"
857 yacc
.yacc(method
='LALR')
859 #profile.run("yacc.yacc(method='LALR')")