• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# -----------------------------------------------------------------------------
2# cparse.py
3#
4# Simple parser for ANSI C.  Based on the grammar in K&R, 2nd Ed.
5# -----------------------------------------------------------------------------
6
7import sys
8import clex
9import ply.yacc as yacc
10
11# Get the token map
12tokens = clex.tokens
13
14# translation-unit:
15
16
17def p_translation_unit_1(t):
18    'translation_unit : external_declaration'
19    pass
20
21
22def p_translation_unit_2(t):
23    'translation_unit : translation_unit external_declaration'
24    pass
25
26# external-declaration:
27
28
29def p_external_declaration_1(t):
30    'external_declaration : function_definition'
31    pass
32
33
34def p_external_declaration_2(t):
35    'external_declaration : declaration'
36    pass
37
38# function-definition:
39
40
41def p_function_definition_1(t):
42    'function_definition : declaration_specifiers declarator declaration_list compound_statement'
43    pass
44
45
46def p_function_definition_2(t):
47    'function_definition : declarator declaration_list compound_statement'
48    pass
49
50
51def p_function_definition_3(t):
52    'function_definition : declarator compound_statement'
53    pass
54
55
56def p_function_definition_4(t):
57    'function_definition : declaration_specifiers declarator compound_statement'
58    pass
59
60# declaration:
61
62
63def p_declaration_1(t):
64    'declaration : declaration_specifiers init_declarator_list SEMI'
65    pass
66
67
68def p_declaration_2(t):
69    'declaration : declaration_specifiers SEMI'
70    pass
71
72# declaration-list:
73
74
75def p_declaration_list_1(t):
76    'declaration_list : declaration'
77    pass
78
79
80def p_declaration_list_2(t):
81    'declaration_list : declaration_list declaration '
82    pass
83
84# declaration-specifiers
85
86
87def p_declaration_specifiers_1(t):
88    'declaration_specifiers : storage_class_specifier declaration_specifiers'
89    pass
90
91
92def p_declaration_specifiers_2(t):
93    'declaration_specifiers : type_specifier declaration_specifiers'
94    pass
95
96
97def p_declaration_specifiers_3(t):
98    'declaration_specifiers : type_qualifier declaration_specifiers'
99    pass
100
101
102def p_declaration_specifiers_4(t):
103    'declaration_specifiers : storage_class_specifier'
104    pass
105
106
107def p_declaration_specifiers_5(t):
108    'declaration_specifiers : type_specifier'
109    pass
110
111
112def p_declaration_specifiers_6(t):
113    'declaration_specifiers : type_qualifier'
114    pass
115
116# storage-class-specifier
117
118
119def p_storage_class_specifier(t):
120    '''storage_class_specifier : AUTO
121                               | REGISTER
122                               | STATIC
123                               | EXTERN
124                               | TYPEDEF
125                               '''
126    pass
127
128# type-specifier:
129
130
131def p_type_specifier(t):
132    '''type_specifier : VOID
133                      | CHAR
134                      | SHORT
135                      | INT
136                      | LONG
137                      | FLOAT
138                      | DOUBLE
139                      | SIGNED
140                      | UNSIGNED
141                      | struct_or_union_specifier
142                      | enum_specifier
143                      | TYPEID
144                      '''
145    pass
146
147# type-qualifier:
148
149
150def p_type_qualifier(t):
151    '''type_qualifier : CONST
152                      | VOLATILE'''
153    pass
154
155# struct-or-union-specifier
156
157
158def p_struct_or_union_specifier_1(t):
159    'struct_or_union_specifier : struct_or_union ID LBRACE struct_declaration_list RBRACE'
160    pass
161
162
163def p_struct_or_union_specifier_2(t):
164    'struct_or_union_specifier : struct_or_union LBRACE struct_declaration_list RBRACE'
165    pass
166
167
168def p_struct_or_union_specifier_3(t):
169    'struct_or_union_specifier : struct_or_union ID'
170    pass
171
172# struct-or-union:
173
174
175def p_struct_or_union(t):
176    '''struct_or_union : STRUCT
177                       | UNION
178                       '''
179    pass
180
181# struct-declaration-list:
182
183
184def p_struct_declaration_list_1(t):
185    'struct_declaration_list : struct_declaration'
186    pass
187
188
189def p_struct_declaration_list_2(t):
190    'struct_declaration_list : struct_declaration_list struct_declaration'
191    pass
192
193# init-declarator-list:
194
195
196def p_init_declarator_list_1(t):
197    'init_declarator_list : init_declarator'
198    pass
199
200
201def p_init_declarator_list_2(t):
202    'init_declarator_list : init_declarator_list COMMA init_declarator'
203    pass
204
205# init-declarator
206
207
208def p_init_declarator_1(t):
209    'init_declarator : declarator'
210    pass
211
212
213def p_init_declarator_2(t):
214    'init_declarator : declarator EQUALS initializer'
215    pass
216
217# struct-declaration:
218
219
220def p_struct_declaration(t):
221    'struct_declaration : specifier_qualifier_list struct_declarator_list SEMI'
222    pass
223
224# specifier-qualifier-list:
225
226
227def p_specifier_qualifier_list_1(t):
228    'specifier_qualifier_list : type_specifier specifier_qualifier_list'
229    pass
230
231
232def p_specifier_qualifier_list_2(t):
233    'specifier_qualifier_list : type_specifier'
234    pass
235
236
237def p_specifier_qualifier_list_3(t):
238    'specifier_qualifier_list : type_qualifier specifier_qualifier_list'
239    pass
240
241
242def p_specifier_qualifier_list_4(t):
243    'specifier_qualifier_list : type_qualifier'
244    pass
245
246# struct-declarator-list:
247
248
249def p_struct_declarator_list_1(t):
250    'struct_declarator_list : struct_declarator'
251    pass
252
253
254def p_struct_declarator_list_2(t):
255    'struct_declarator_list : struct_declarator_list COMMA struct_declarator'
256    pass
257
258# struct-declarator:
259
260
261def p_struct_declarator_1(t):
262    'struct_declarator : declarator'
263    pass
264
265
266def p_struct_declarator_2(t):
267    'struct_declarator : declarator COLON constant_expression'
268    pass
269
270
271def p_struct_declarator_3(t):
272    'struct_declarator : COLON constant_expression'
273    pass
274
275# enum-specifier:
276
277
278def p_enum_specifier_1(t):
279    'enum_specifier : ENUM ID LBRACE enumerator_list RBRACE'
280    pass
281
282
283def p_enum_specifier_2(t):
284    'enum_specifier : ENUM LBRACE enumerator_list RBRACE'
285    pass
286
287
288def p_enum_specifier_3(t):
289    'enum_specifier : ENUM ID'
290    pass
291
292# enumerator_list:
293
294
295def p_enumerator_list_1(t):
296    'enumerator_list : enumerator'
297    pass
298
299
300def p_enumerator_list_2(t):
301    'enumerator_list : enumerator_list COMMA enumerator'
302    pass
303
304# enumerator:
305
306
307def p_enumerator_1(t):
308    'enumerator : ID'
309    pass
310
311
312def p_enumerator_2(t):
313    'enumerator : ID EQUALS constant_expression'
314    pass
315
316# declarator:
317
318
319def p_declarator_1(t):
320    'declarator : pointer direct_declarator'
321    pass
322
323
324def p_declarator_2(t):
325    'declarator : direct_declarator'
326    pass
327
328# direct-declarator:
329
330
331def p_direct_declarator_1(t):
332    'direct_declarator : ID'
333    pass
334
335
336def p_direct_declarator_2(t):
337    'direct_declarator : LPAREN declarator RPAREN'
338    pass
339
340
341def p_direct_declarator_3(t):
342    'direct_declarator : direct_declarator LBRACKET constant_expression_opt RBRACKET'
343    pass
344
345
346def p_direct_declarator_4(t):
347    'direct_declarator : direct_declarator LPAREN parameter_type_list RPAREN '
348    pass
349
350
351def p_direct_declarator_5(t):
352    'direct_declarator : direct_declarator LPAREN identifier_list RPAREN '
353    pass
354
355
356def p_direct_declarator_6(t):
357    'direct_declarator : direct_declarator LPAREN RPAREN '
358    pass
359
360# pointer:
361
362
363def p_pointer_1(t):
364    'pointer : TIMES type_qualifier_list'
365    pass
366
367
368def p_pointer_2(t):
369    'pointer : TIMES'
370    pass
371
372
373def p_pointer_3(t):
374    'pointer : TIMES type_qualifier_list pointer'
375    pass
376
377
378def p_pointer_4(t):
379    'pointer : TIMES pointer'
380    pass
381
382# type-qualifier-list:
383
384
385def p_type_qualifier_list_1(t):
386    'type_qualifier_list : type_qualifier'
387    pass
388
389
390def p_type_qualifier_list_2(t):
391    'type_qualifier_list : type_qualifier_list type_qualifier'
392    pass
393
394# parameter-type-list:
395
396
397def p_parameter_type_list_1(t):
398    'parameter_type_list : parameter_list'
399    pass
400
401
402def p_parameter_type_list_2(t):
403    'parameter_type_list : parameter_list COMMA ELLIPSIS'
404    pass
405
406# parameter-list:
407
408
409def p_parameter_list_1(t):
410    'parameter_list : parameter_declaration'
411    pass
412
413
414def p_parameter_list_2(t):
415    'parameter_list : parameter_list COMMA parameter_declaration'
416    pass
417
418# parameter-declaration:
419
420
421def p_parameter_declaration_1(t):
422    'parameter_declaration : declaration_specifiers declarator'
423    pass
424
425
426def p_parameter_declaration_2(t):
427    'parameter_declaration : declaration_specifiers abstract_declarator_opt'
428    pass
429
430# identifier-list:
431
432
433def p_identifier_list_1(t):
434    'identifier_list : ID'
435    pass
436
437
438def p_identifier_list_2(t):
439    'identifier_list : identifier_list COMMA ID'
440    pass
441
442# initializer:
443
444
445def p_initializer_1(t):
446    'initializer : assignment_expression'
447    pass
448
449
450def p_initializer_2(t):
451    '''initializer : LBRACE initializer_list RBRACE
452                   | LBRACE initializer_list COMMA RBRACE'''
453    pass
454
455# initializer-list:
456
457
458def p_initializer_list_1(t):
459    'initializer_list : initializer'
460    pass
461
462
463def p_initializer_list_2(t):
464    'initializer_list : initializer_list COMMA initializer'
465    pass
466
467# type-name:
468
469
470def p_type_name(t):
471    'type_name : specifier_qualifier_list abstract_declarator_opt'
472    pass
473
474
475def p_abstract_declarator_opt_1(t):
476    'abstract_declarator_opt : empty'
477    pass
478
479
480def p_abstract_declarator_opt_2(t):
481    'abstract_declarator_opt : abstract_declarator'
482    pass
483
484# abstract-declarator:
485
486
487def p_abstract_declarator_1(t):
488    'abstract_declarator : pointer '
489    pass
490
491
492def p_abstract_declarator_2(t):
493    'abstract_declarator : pointer direct_abstract_declarator'
494    pass
495
496
497def p_abstract_declarator_3(t):
498    'abstract_declarator : direct_abstract_declarator'
499    pass
500
501# direct-abstract-declarator:
502
503
504def p_direct_abstract_declarator_1(t):
505    'direct_abstract_declarator : LPAREN abstract_declarator RPAREN'
506    pass
507
508
509def p_direct_abstract_declarator_2(t):
510    'direct_abstract_declarator : direct_abstract_declarator LBRACKET constant_expression_opt RBRACKET'
511    pass
512
513
514def p_direct_abstract_declarator_3(t):
515    'direct_abstract_declarator : LBRACKET constant_expression_opt RBRACKET'
516    pass
517
518
519def p_direct_abstract_declarator_4(t):
520    'direct_abstract_declarator : direct_abstract_declarator LPAREN parameter_type_list_opt RPAREN'
521    pass
522
523
524def p_direct_abstract_declarator_5(t):
525    'direct_abstract_declarator : LPAREN parameter_type_list_opt RPAREN'
526    pass
527
528# Optional fields in abstract declarators
529
530
531def p_constant_expression_opt_1(t):
532    'constant_expression_opt : empty'
533    pass
534
535
536def p_constant_expression_opt_2(t):
537    'constant_expression_opt : constant_expression'
538    pass
539
540
541def p_parameter_type_list_opt_1(t):
542    'parameter_type_list_opt : empty'
543    pass
544
545
546def p_parameter_type_list_opt_2(t):
547    'parameter_type_list_opt : parameter_type_list'
548    pass
549
550# statement:
551
552
553def p_statement(t):
554    '''
555    statement : labeled_statement
556              | expression_statement
557              | compound_statement
558              | selection_statement
559              | iteration_statement
560              | jump_statement
561              '''
562    pass
563
564# labeled-statement:
565
566
567def p_labeled_statement_1(t):
568    'labeled_statement : ID COLON statement'
569    pass
570
571
572def p_labeled_statement_2(t):
573    'labeled_statement : CASE constant_expression COLON statement'
574    pass
575
576
577def p_labeled_statement_3(t):
578    'labeled_statement : DEFAULT COLON statement'
579    pass
580
581# expression-statement:
582
583
584def p_expression_statement(t):
585    'expression_statement : expression_opt SEMI'
586    pass
587
588# compound-statement:
589
590
591def p_compound_statement_1(t):
592    'compound_statement : LBRACE declaration_list statement_list RBRACE'
593    pass
594
595
596def p_compound_statement_2(t):
597    'compound_statement : LBRACE statement_list RBRACE'
598    pass
599
600
601def p_compound_statement_3(t):
602    'compound_statement : LBRACE declaration_list RBRACE'
603    pass
604
605
606def p_compound_statement_4(t):
607    'compound_statement : LBRACE RBRACE'
608    pass
609
610# statement-list:
611
612
613def p_statement_list_1(t):
614    'statement_list : statement'
615    pass
616
617
618def p_statement_list_2(t):
619    'statement_list : statement_list statement'
620    pass
621
622# selection-statement
623
624
625def p_selection_statement_1(t):
626    'selection_statement : IF LPAREN expression RPAREN statement'
627    pass
628
629
630def p_selection_statement_2(t):
631    'selection_statement : IF LPAREN expression RPAREN statement ELSE statement '
632    pass
633
634
635def p_selection_statement_3(t):
636    'selection_statement : SWITCH LPAREN expression RPAREN statement '
637    pass
638
639# iteration_statement:
640
641
642def p_iteration_statement_1(t):
643    'iteration_statement : WHILE LPAREN expression RPAREN statement'
644    pass
645
646
647def p_iteration_statement_2(t):
648    'iteration_statement : FOR LPAREN expression_opt SEMI expression_opt SEMI expression_opt RPAREN statement '
649    pass
650
651
652def p_iteration_statement_3(t):
653    'iteration_statement : DO statement WHILE LPAREN expression RPAREN SEMI'
654    pass
655
656# jump_statement:
657
658
659def p_jump_statement_1(t):
660    'jump_statement : GOTO ID SEMI'
661    pass
662
663
664def p_jump_statement_2(t):
665    'jump_statement : CONTINUE SEMI'
666    pass
667
668
669def p_jump_statement_3(t):
670    'jump_statement : BREAK SEMI'
671    pass
672
673
674def p_jump_statement_4(t):
675    'jump_statement : RETURN expression_opt SEMI'
676    pass
677
678
679def p_expression_opt_1(t):
680    'expression_opt : empty'
681    pass
682
683
684def p_expression_opt_2(t):
685    'expression_opt : expression'
686    pass
687
688# expression:
689
690
691def p_expression_1(t):
692    'expression : assignment_expression'
693    pass
694
695
696def p_expression_2(t):
697    'expression : expression COMMA assignment_expression'
698    pass
699
700# assigment_expression:
701
702
703def p_assignment_expression_1(t):
704    'assignment_expression : conditional_expression'
705    pass
706
707
708def p_assignment_expression_2(t):
709    'assignment_expression : unary_expression assignment_operator assignment_expression'
710    pass
711
712# assignment_operator:
713
714
715def p_assignment_operator(t):
716    '''
717    assignment_operator : EQUALS
718                        | TIMESEQUAL
719                        | DIVEQUAL
720                        | MODEQUAL
721                        | PLUSEQUAL
722                        | MINUSEQUAL
723                        | LSHIFTEQUAL
724                        | RSHIFTEQUAL
725                        | ANDEQUAL
726                        | OREQUAL
727                        | XOREQUAL
728                        '''
729    pass
730
731# conditional-expression
732
733
734def p_conditional_expression_1(t):
735    'conditional_expression : logical_or_expression'
736    pass
737
738
739def p_conditional_expression_2(t):
740    'conditional_expression : logical_or_expression CONDOP expression COLON conditional_expression '
741    pass
742
743# constant-expression
744
745
746def p_constant_expression(t):
747    'constant_expression : conditional_expression'
748    pass
749
750# logical-or-expression
751
752
753def p_logical_or_expression_1(t):
754    'logical_or_expression : logical_and_expression'
755    pass
756
757
758def p_logical_or_expression_2(t):
759    'logical_or_expression : logical_or_expression LOR logical_and_expression'
760    pass
761
762# logical-and-expression
763
764
765def p_logical_and_expression_1(t):
766    'logical_and_expression : inclusive_or_expression'
767    pass
768
769
770def p_logical_and_expression_2(t):
771    'logical_and_expression : logical_and_expression LAND inclusive_or_expression'
772    pass
773
774# inclusive-or-expression:
775
776
777def p_inclusive_or_expression_1(t):
778    'inclusive_or_expression : exclusive_or_expression'
779    pass
780
781
782def p_inclusive_or_expression_2(t):
783    'inclusive_or_expression : inclusive_or_expression OR exclusive_or_expression'
784    pass
785
786# exclusive-or-expression:
787
788
789def p_exclusive_or_expression_1(t):
790    'exclusive_or_expression :  and_expression'
791    pass
792
793
794def p_exclusive_or_expression_2(t):
795    'exclusive_or_expression :  exclusive_or_expression XOR and_expression'
796    pass
797
798# AND-expression
799
800
801def p_and_expression_1(t):
802    'and_expression : equality_expression'
803    pass
804
805
806def p_and_expression_2(t):
807    'and_expression : and_expression AND equality_expression'
808    pass
809
810
811# equality-expression:
812def p_equality_expression_1(t):
813    'equality_expression : relational_expression'
814    pass
815
816
817def p_equality_expression_2(t):
818    'equality_expression : equality_expression EQ relational_expression'
819    pass
820
821
822def p_equality_expression_3(t):
823    'equality_expression : equality_expression NE relational_expression'
824    pass
825
826
827# relational-expression:
828def p_relational_expression_1(t):
829    'relational_expression : shift_expression'
830    pass
831
832
833def p_relational_expression_2(t):
834    'relational_expression : relational_expression LT shift_expression'
835    pass
836
837
838def p_relational_expression_3(t):
839    'relational_expression : relational_expression GT shift_expression'
840    pass
841
842
843def p_relational_expression_4(t):
844    'relational_expression : relational_expression LE shift_expression'
845    pass
846
847
848def p_relational_expression_5(t):
849    'relational_expression : relational_expression GE shift_expression'
850    pass
851
852# shift-expression
853
854
855def p_shift_expression_1(t):
856    'shift_expression : additive_expression'
857    pass
858
859
860def p_shift_expression_2(t):
861    'shift_expression : shift_expression LSHIFT additive_expression'
862    pass
863
864
865def p_shift_expression_3(t):
866    'shift_expression : shift_expression RSHIFT additive_expression'
867    pass
868
869# additive-expression
870
871
872def p_additive_expression_1(t):
873    'additive_expression : multiplicative_expression'
874    pass
875
876
877def p_additive_expression_2(t):
878    'additive_expression : additive_expression PLUS multiplicative_expression'
879    pass
880
881
882def p_additive_expression_3(t):
883    'additive_expression : additive_expression MINUS multiplicative_expression'
884    pass
885
886# multiplicative-expression
887
888
889def p_multiplicative_expression_1(t):
890    'multiplicative_expression : cast_expression'
891    pass
892
893
894def p_multiplicative_expression_2(t):
895    'multiplicative_expression : multiplicative_expression TIMES cast_expression'
896    pass
897
898
899def p_multiplicative_expression_3(t):
900    'multiplicative_expression : multiplicative_expression DIVIDE cast_expression'
901    pass
902
903
904def p_multiplicative_expression_4(t):
905    'multiplicative_expression : multiplicative_expression MOD cast_expression'
906    pass
907
908# cast-expression:
909
910
911def p_cast_expression_1(t):
912    'cast_expression : unary_expression'
913    pass
914
915
916def p_cast_expression_2(t):
917    'cast_expression : LPAREN type_name RPAREN cast_expression'
918    pass
919
920# unary-expression:
921
922
923def p_unary_expression_1(t):
924    'unary_expression : postfix_expression'
925    pass
926
927
928def p_unary_expression_2(t):
929    'unary_expression : PLUSPLUS unary_expression'
930    pass
931
932
933def p_unary_expression_3(t):
934    'unary_expression : MINUSMINUS unary_expression'
935    pass
936
937
938def p_unary_expression_4(t):
939    'unary_expression : unary_operator cast_expression'
940    pass
941
942
943def p_unary_expression_5(t):
944    'unary_expression : SIZEOF unary_expression'
945    pass
946
947
948def p_unary_expression_6(t):
949    'unary_expression : SIZEOF LPAREN type_name RPAREN'
950    pass
951
952# unary-operator
953
954
955def p_unary_operator(t):
956    '''unary_operator : AND
957                    | TIMES
958                    | PLUS
959                    | MINUS
960                    | NOT
961                    | LNOT '''
962    pass
963
964# postfix-expression:
965
966
967def p_postfix_expression_1(t):
968    'postfix_expression : primary_expression'
969    pass
970
971
972def p_postfix_expression_2(t):
973    'postfix_expression : postfix_expression LBRACKET expression RBRACKET'
974    pass
975
976
977def p_postfix_expression_3(t):
978    'postfix_expression : postfix_expression LPAREN argument_expression_list RPAREN'
979    pass
980
981
982def p_postfix_expression_4(t):
983    'postfix_expression : postfix_expression LPAREN RPAREN'
984    pass
985
986
987def p_postfix_expression_5(t):
988    'postfix_expression : postfix_expression PERIOD ID'
989    pass
990
991
992def p_postfix_expression_6(t):
993    'postfix_expression : postfix_expression ARROW ID'
994    pass
995
996
997def p_postfix_expression_7(t):
998    'postfix_expression : postfix_expression PLUSPLUS'
999    pass
1000
1001
1002def p_postfix_expression_8(t):
1003    'postfix_expression : postfix_expression MINUSMINUS'
1004    pass
1005
1006# primary-expression:
1007
1008
1009def p_primary_expression(t):
1010    '''primary_expression :  ID
1011                        |  constant
1012                        |  SCONST
1013                        |  LPAREN expression RPAREN'''
1014    pass
1015
1016# argument-expression-list:
1017
1018
1019def p_argument_expression_list(t):
1020    '''argument_expression_list :  assignment_expression
1021                              |  argument_expression_list COMMA assignment_expression'''
1022    pass
1023
1024# constant:
1025
1026
1027def p_constant(t):
1028    '''constant : ICONST
1029               | FCONST
1030               | CCONST'''
1031    pass
1032
1033
1034def p_empty(t):
1035    'empty : '
1036    pass
1037
1038
1039def p_error(t):
1040    print("Whoa. We're hosed")
1041
1042import profile
1043# Build the grammar
1044
1045yacc.yacc()
1046#yacc.yacc(method='LALR',write_tables=False,debug=False)
1047
1048#profile.run("yacc.yacc(method='LALR')")
1049