/* C Grammar: cgram.y 2/1/95 jeffery Non-terminals for C based roughly on Kernighan and Ritchie Appendix A. Tokens: The place to look to identify these is in K&R, p. 215. The precedence rules here match those given in K&R exactly, although yacc specifies high-low in the opposite direction. LOWEST precedence: */ %left COMMA %right EQ PLUSEQ MINUSEQ MUEQ DIVEQ MODEQ SREQ SLEQ ANEQ XOREQ OREQ %right IF_THEN COLON %left OROR %left ANDAND %left OR %left XOR %left AND %left EQEQ NOTEQ %left GT GE LT LE %left LTLT GTGT %left PLUS MINUS %left STAR DIV MOD %right NOT NEG %right INCOP SIZEOF DECOP %left LB LP DOT FOLLOW /* HIGHEST precedence */ /* miscellaneous lexemes */ %token IDENTIFIER STRUCT RB RC RP SWITCH WHILE SEMICOL %token INT_LITERAL FLOAT_LITERAL CHAR_LITERAL TYPE_NAME %token BREAK CASE CONTINUE DEFAULT DO ELSE FOR GOTO IF LC RETURN STRING_LITERAL %token AUTO EXTERN REGISTER STATIC TYPEDEF /* class specifiers */ %token VOID CHAR DOUBLE FLOAT INT LONG SHORT UNSIGNED /* type specifiers */ %token ENUM UNION CONST VOLATILE SIGNED ELLIPSIS %{ #include #include "y.tab.h" %} %union { nodeptr treenode; } %type < treenode > startsymbol translation_unit external_declaration %type < treenode > function_definition declaration declaration_list %type < treenode > declaration_specifiers storage_class_specifier %type < treenode > type_specifier type_qualifier struct_or_union_specifier %type < treenode > struct_declaration_list init_declarator_list %type < treenode > init_declarator struct_declaration assignment_expression %type < treenode > specifier_qualifier_list struct_declarator_list %type < treenode > struct_declarator enum_specifier enumerator_list %type < treenode > enumerator declarator direct_declarator pointer %type < treenode > type_qualifier_list parameter_type_list parameter_list %type < treenode > parameter_declaration identifier_list initializer %type < treenode > initializer_list type_name abstract_declarator x %type < treenode > direct_abstract_declarator statement labeled_statement %type < treenode > expression_statement compound_statement statement_list %type < treenode > selection_statement iteration_statement forcntrl %type < treenode > jump_statement assignment_operator struct_or_union %type < treenode > conditional_expression constant_expression %type < treenode > logical_or_expression logical_and_expression %type < treenode > inclusive_or_expression exclusive_or_expression %type < treenode > equality_expression relational_expression %type < treenode > shift_expression additive_expression %type < treenode > multiplicative_expression cast_expression unary_expression %type < treenode > postfix_expression primary_expression and_expression %type < treenode > argument_expression_list ident struct_or_union_ident %start startsymbol %% startsymbol: translation_unit ; translation_unit: external_declaration | translation_unit external_declaration ; external_declaration: function_definition | declaration | error { yyerror("external declaration error"); } ; function_definition: declarator compound_statement | declaration_specifiers declarator compound_statement | declarator declaration_list compound_statement | declaration_specifiers declarator declaration_list compound_statement ; declaration: declaration_specifiers SEMICOL | declaration_specifiers init_declarator_list SEMICOL ; declaration_list: declaration | declaration_list declaration ; declaration_specifiers: storage_class_specifier | type_specifier | type_qualifier | storage_class_specifier declaration_specifiers | type_specifier declaration_specifiers | type_qualifier declaration_specifiers ; storage_class_specifier: AUTO { ; } | EXTERN { ; } | REGISTER { ; } | STATIC { ; } | TYPEDEF { ; } ; type_specifier: CHAR { ; } | DOUBLE { ; } | VOID { ; } | FLOAT { ; } | INT { ; } | LONG { ; } | SHORT { ; } | SIGNED { ; } | UNSIGNED { ; } | struct_or_union_specifier | enum_specifier | TYPE_NAME { ; } ; type_qualifier: CONST { ; } | VOLATILE { ; } ; struct_or_union_specifier: struct_or_union_ident LC struct_declaration_list RC | struct_or_union_ident ; struct_or_union_ident: struct_or_union | struct_or_union ident ; struct_or_union: STRUCT { ; } | UNION { ; } ; struct_declaration_list: struct_declaration | struct_declaration_list struct_declaration ; init_declarator_list: init_declarator %prec COMMA | init_declarator_list COMMA init_declarator ; init_declarator: declarator | declarator EQ initializer | error { yyerror("init declarator error"); } ; struct_declaration: specifier_qualifier_list struct_declarator_list SEMICOL ; specifier_qualifier_list: type_specifier | type_qualifier | type_specifier specifier_qualifier_list | type_qualifier specifier_qualifier_list ; struct_declarator_list: struct_declarator | struct_declarator_list COMMA struct_declarator ; struct_declarator: declarator | COLON constant_expression { ; } | declarator COLON constant_expression ; enum_specifier: ENUM ident LC enumerator_list RC { ; } | ENUM LC enumerator_list RC { ; } | ENUM ident { ; } ; enumerator_list: enumerator | enumerator_list COMMA enumerator ; enumerator: ident | ident EQ constant_expression ; declarator: direct_declarator | pointer direct_declarator ; direct_declarator: ident | LP declarator RP { ; } | direct_declarator LB RB | direct_declarator LB constant_expression RB | LB constant_expression RB { ; } | direct_declarator LP parameter_type_list RP | direct_declarator LP RP | direct_declarator LP identifier_list RP ; pointer: STAR { ; } | STAR pointer { ; } | STAR type_qualifier_list { ; } | STAR type_qualifier_list pointer { ; } ; type_qualifier_list: type_qualifier | type_qualifier_list type_qualifier ; parameter_type_list: parameter_list | parameter_list COMMA ELLIPSIS ; parameter_list: parameter_declaration | parameter_list COMMA parameter_declaration ; parameter_declaration: declaration_specifiers declarator | declaration_specifiers | declaration_specifiers abstract_declarator ; identifier_list: ident | identifier_list COMMA ident | error { yyerror("identifier list error"); } ; initializer: assignment_expression %prec COMMA | LC initializer_list RC { ; } | LC initializer_list COMMA RC { ; } ; initializer_list: initializer %prec COMMA | initializer_list COMMA initializer ; type_name: specifier_qualifier_list | specifier_qualifier_list abstract_declarator ; abstract_declarator: pointer | direct_abstract_declarator | pointer direct_abstract_declarator ; direct_abstract_declarator: LP abstract_declarator RP { ; } | LC RC { ; } | direct_abstract_declarator LC RC | LC constant_expression RC { ; } | direct_abstract_declarator LC constant_expression RC | LP RP { ; } | direct_abstract_declarator LP RP | LP parameter_list RP { ; } | direct_abstract_declarator LP parameter_list RP ; statement: labeled_statement | expression_statement | compound_statement | selection_statement | iteration_statement | jump_statement | SEMICOL { ; } | error SEMICOL { yyerror("statement error"); } | error RC { yyerror("statement error"); } ; labeled_statement: ident COLON statement | CASE x COLON statement { ; } | DEFAULT COLON statement { ; } ; expression_statement: x SEMICOL ; compound_statement: LC RC { ; } | LC declaration_list RC { ; } | LC statement_list RC { ; } | LC declaration_list statement_list RC { ; } ; statement_list: statement | statement_list statement ; selection_statement: IF LP x RP statement { ; } | IF LP x RP statement ELSE statement { ; } | SWITCH LP x RP statement { ; } ; iteration_statement: WHILE LP x RP statement { ; } | DO statement WHILE LP x RP SEMICOL { ; } | FOR LP forcntrl RP statement { ; } ; forcntrl: SEMICOL SEMICOL { ; } | SEMICOL SEMICOL x { ; } | SEMICOL x SEMICOL { ; } | SEMICOL x SEMICOL x { ; } | x SEMICOL SEMICOL | x SEMICOL SEMICOL x | x SEMICOL x SEMICOL | x SEMICOL x SEMICOL x ; jump_statement: GOTO ident SEMICOL { ; } | CONTINUE SEMICOL { ; } | BREAK SEMICOL { ; } | RETURN SEMICOL { ; } | RETURN x SEMICOL { ; } ; x: assignment_expression | x COMMA assignment_expression ; assignment_expression: conditional_expression | unary_expression assignment_operator assignment_expression ; assignment_operator: EQ { ; } | PLUSEQ { ; } | MINUSEQ { ; } | MUEQ { ; } | DIVEQ { ; } | MODEQ { ; } | SLEQ { ; } | SREQ { ; } | ANEQ { ; } | OREQ { ; } | XOREQ { ; } ; conditional_expression: logical_or_expression | logical_or_expression IF_THEN x COLON conditional_expression ; constant_expression: conditional_expression ; logical_or_expression: logical_and_expression | logical_or_expression OROR logical_and_expression ; logical_and_expression: inclusive_or_expression | logical_and_expression ANDAND inclusive_or_expression ; inclusive_or_expression: exclusive_or_expression | inclusive_or_expression OR exclusive_or_expression ; exclusive_or_expression: and_expression | exclusive_or_expression XOR and_expression ; and_expression: equality_expression | and_expression AND equality_expression ; equality_expression: relational_expression | equality_expression EQEQ relational_expression | equality_expression NOTEQ relational_expression ; relational_expression: shift_expression | relational_expression LT shift_expression | relational_expression LE shift_expression | relational_expression GT shift_expression | relational_expression GE shift_expression ; shift_expression: additive_expression | shift_expression LTLT additive_expression | shift_expression GTGT additive_expression ; additive_expression: multiplicative_expression | additive_expression PLUS multiplicative_expression | additive_expression MINUS multiplicative_expression ; multiplicative_expression: cast_expression | multiplicative_expression STAR cast_expression | multiplicative_expression DIV cast_expression | multiplicative_expression MOD cast_expression ; cast_expression: unary_expression | LP type_name RP cast_expression { ; } ; unary_expression: postfix_expression | INCOP unary_expression { ; } | DECOP unary_expression { ; } | SIZEOF unary_expression { ; } | SIZEOF LP type_name RP %prec SIZEOF { ; } | STAR cast_expression { ; } | AND cast_expression { ; } | MINUS cast_expression { ; } | PLUS cast_expression { ; } | NEG cast_expression { ; } | NOT cast_expression { ; } ; postfix_expression: primary_expression | postfix_expression LB x RB | postfix_expression LP RP | postfix_expression LP argument_expression_list RP | postfix_expression FOLLOW ident | postfix_expression DOT ident | postfix_expression INCOP | postfix_expression DECOP ; primary_expression: ident | INT_LITERAL { ; } | CHAR_LITERAL { ; } | FLOAT_LITERAL { ; } | STRING_LITERAL { ; } | LP x RP { ; } ; argument_expression_list: assignment_expression | argument_expression_list COMMA assignment_expression ; ident: IDENTIFIER { ; } ; %%