%code requires{ #include "ast.hpp" extern ast_Top *g_root; // A way of getting the AST out //! This is to fix problems when generating C++ // We are declaring the functions provided by Flex, so // that Bison generated code can call them. int yylex(void); void yyerror(const char *); } // Represents the value associated with any kind of // AST node. %union{ const ast_Base *stmnt; double number; std::string *string; } %token T_TYPE_SPEC T_TYPE_QUAL T_STRG_SPEC T_IDENTIFIER %token T_SC T_CMA T_LRB T_RRB T_LCB T_RCB T_LSB T_RSB T_QU T_COL T_LOG_OR T_LOG_AND T_OR T_XOR T_AND T_EQUALITY_OP T_REL_OP T_SHIFT_OP T_MULT T_DIV T_REM T_TILDE T_NOT T_DOT T_ARROW T_INCDEC T_ADDSUB_OP T_ASSIGN_OPER T_EQ T_SIZEOF %token T_INT_CONST %token T_IF T_ELSE T_WHILE T_DO T_FOR T_RETURN %type EXT_DEF EXT_DECLARATION %type FUNC_DEF PARAMETER_LIST PARAMETER PARAM_DECLARATOR %type DECLARATION_LIST DECLARATION DECLARATION_SPEC DECLARATION_SPEC_T INIT_DECLARATOR INIT_DECLARATOR_LIST DECLARATOR INITIALIZER %type STATEMENT_LIST STATEMENT COMPOUND_STATEMENT COMPOUND_STATEMENT_2 SELECTION_STATEMENT SELECTION_STATEMENT_2 EXPRESSION_STATEMENT JUMP_STATEMENT JUMP_STATEMENT_2 ITERATION_STATEMENT %type EXPRESSION ASSIGNMENT_EXPRESSION CONDITIONAL_EXPRESSION LOGICAL_OR_EXPRESSION LOGICAL_AND_EXPRESSION INCLUSIVE_OR_EXPRESSION EXCLUSIVE_OR_EXPRESSION AND_EXPRESSION EQUALITY_EXPRESSION RELATIONAL_EXPRESSION SHIFT_EXPRESSION ADDITIVE_EXPRESSION MULTIPLICATIVE_EXPRESSION CAST_EXPRESSION UNARY_EXPRESSION POSTFIX_EXPRESSION POSTFIX_EXPRESSION_2 ARGUMENT_EXPRESSION_LIST PRIMARY_EXPRESSION %type CONSTANT T_INT_CONST %type T_IDENTIFIER MULTDIVREM_OP UNARY_OPERATOR T_AND T_ADDSUB_OP T_TILDE T_NOT T_MULT T_DIV T_REM //T_OPERATOR %start ROOT %% ROOT: EXT_DEF { ; } ; // EXTERNAL DEFINITION EXT_DEF: EXT_DECLARATION { g_root->push($1); } | EXT_DEF EXT_DECLARATION { g_root->push($2); } ; EXT_DECLARATION: DECLARATION { $$ = $1; } | FUNC_DEF { $$ = $1; } ; // FUNCTION DEFINITION FUNC_DEF: DECLARATION_SPEC T_IDENTIFIER T_LRB PARAMETER_LIST T_RRB COMPOUND_STATEMENT { $$ = new ast_Function(*$2, $4, $6); } ; PARAMETER_LIST: %empty { $$ = new ast_ParamList(); } | PARAMETER { $$ = new ast_ParamList($1); } | PARAMETER_LIST T_CMA PARAMETER { $$->push($3); } ; PARAMETER: DECLARATION_SPEC PARAM_DECLARATOR { $$ = $2; } ; PARAM_DECLARATOR: T_IDENTIFIER { $$ = new ast_Parameter(*$1);} ; // DECLARATION DECLARATION_LIST: DECLARATION { $$ = new ast_DeclarationList($1); } | DECLARATION_LIST DECLARATION { $$->push($2); } ; DECLARATION: DECLARATION_SPEC INIT_DECLARATOR_LIST T_SC { $$ = $2; } ; DECLARATION_SPEC: DECLARATION_SPEC_T { ; } | DECLARATION_SPEC_T DECLARATION_SPEC { ; } ; DECLARATION_SPEC_T: T_TYPE_SPEC { ; } | T_TYPE_QUAL { ; } | T_STRG_SPEC { ; } ; INIT_DECLARATOR_LIST: INIT_DECLARATOR { $$ = new ast_VariableDeclaration($1); } | INIT_DECLARATOR_LIST T_CMA INIT_DECLARATOR { $$->push($3); } ; INIT_DECLARATOR: DECLARATOR { ; } | DECLARATOR T_EQ INITIALIZER { ; } ; DECLARATOR: T_IDENTIFIER {$$ = new ast_Variable(*$1); } ; INITIALIZER: ASSIGNMENT_EXPRESSION { ; } ; // STATEMENT STATEMENT_LIST: STATEMENT { $$ = new ast_StatementList($1); } | STATEMENT_LIST STATEMENT { $$->push($2); } ; STATEMENT: COMPOUND_STATEMENT { $$ = $1; } | SELECTION_STATEMENT { $$ = $1; } | EXPRESSION_STATEMENT { $$ = $1; } | JUMP_STATEMENT { $$ = $1; } | ITERATION_STATEMENT { $$ = $1; } ; COMPOUND_STATEMENT: T_LCB COMPOUND_STATEMENT_2 { $$ = $2; } ; COMPOUND_STATEMENT_2: T_RCB { $$ = new ast_CompoundStatement; } | DECLARATION_LIST T_RCB { $$ = new ast_CompoundStatement($1); } | DECLARATION_LIST STATEMENT_LIST T_RCB { $$ = new ast_CompoundStatement($1, $2); } | STATEMENT_LIST T_RCB { $$ = new ast_CompoundStatement($1); } ; SELECTION_STATEMENT: T_IF T_LRB EXPRESSION T_RRB STATEMENT SELECTION_STATEMENT_2 { $$ = new ast_SelectionStatement($5, $6); } ; SELECTION_STATEMENT_2: %empty { $$ = new ast_SelectionStatement(); } | T_ELSE STATEMENT { $$ = $2; } ; EXPRESSION_STATEMENT: T_SC { $$ = new ast_ExpressionStatement(); } | EXPRESSION T_SC { $$ = $1; } ; JUMP_STATEMENT: T_RETURN JUMP_STATEMENT_2 { $$ = $2; } ; JUMP_STATEMENT_2: T_SC { $$ = new ast_JumpStatement(); } | EXPRESSION T_SC { $$ = $1; } ; ITERATION_STATEMENT: T_WHILE T_LRB EXPRESSION T_RRB STATEMENT { $$ = $5; } | T_DO STATEMENT T_WHILE T_LRB EXPRESSION T_RRB T_SC { $$ = $2; } | T_FOR T_LRB EXPRESSION T_SC EXPRESSION T_SC EXPRESSION T_RRB STATEMENT { $$ = $9; } ; // Expressions EXPRESSION: ASSIGNMENT_EXPRESSION { $$ = $1; } ; ASSIGNMENT_EXPRESSION: CONDITIONAL_EXPRESSION { $$ = $1; } | UNARY_EXPRESSION T_ASSIGN_OPER ASSIGNMENT_EXPRESSION { $$ = $1; } ; CONDITIONAL_EXPRESSION: LOGICAL_OR_EXPRESSION { $$ = $1; } | LOGICAL_OR_EXPRESSION T_QU EXPRESSION T_COL CONDITIONAL_EXPRESSION { $$ = $1; } ; LOGICAL_OR_EXPRESSION: LOGICAL_AND_EXPRESSION { $$ = $1; } | LOGICAL_OR_EXPRESSION T_LOG_OR LOGICAL_AND_EXPRESSION { $$ = $3; } ; LOGICAL_AND_EXPRESSION: INCLUSIVE_OR_EXPRESSION { $$ = $1; } | LOGICAL_AND_EXPRESSION T_LOG_AND INCLUSIVE_OR_EXPRESSION { $$ = $3; } ; INCLUSIVE_OR_EXPRESSION: EXCLUSIVE_OR_EXPRESSION { $$ = $1; } | INCLUSIVE_OR_EXPRESSION T_OR EXCLUSIVE_OR_EXPRESSION { $$ = $3; } ; EXCLUSIVE_OR_EXPRESSION: AND_EXPRESSION { $$ = $1; } | EXCLUSIVE_OR_EXPRESSION T_XOR AND_EXPRESSION { $$ = $3; } ; AND_EXPRESSION: EQUALITY_EXPRESSION { $$ = $1; } | AND_EXPRESSION T_AND EQUALITY_EXPRESSION { $$ = $3; } ; EQUALITY_EXPRESSION: RELATIONAL_EXPRESSION { $$ = $1; } | EQUALITY_EXPRESSION T_EQUALITY_OP RELATIONAL_EXPRESSION { $$ = $3; } ; RELATIONAL_EXPRESSION: SHIFT_EXPRESSION { $$ = $1; } | RELATIONAL_EXPRESSION T_REL_OP SHIFT_EXPRESSION { $$ = $3; } ; SHIFT_EXPRESSION: ADDITIVE_EXPRESSION { $$ = $1; } | SHIFT_EXPRESSION T_SHIFT_OP ADDITIVE_EXPRESSION { $$ = $3; } ; ADDITIVE_EXPRESSION: MULTIPLICATIVE_EXPRESSION { $$ = $1; } | ADDITIVE_EXPRESSION T_ADDSUB_OP MULTIPLICATIVE_EXPRESSION { $$ = $3; } ; MULTIPLICATIVE_EXPRESSION: CAST_EXPRESSION { $$ = $1; } | MULTIPLICATIVE_EXPRESSION MULTDIVREM_OP CAST_EXPRESSION { $$ = $3; } ; MULTDIVREM_OP: T_MULT { $$ = $1; } | T_DIV { $$ = $1; } | T_REM { $$ = $1; } ; CAST_EXPRESSION: UNARY_EXPRESSION { $$ = $1; } | T_LRB T_TYPE_SPEC T_RRB CAST_EXPRESSION { $$ = $4; } ; UNARY_EXPRESSION: POSTFIX_EXPRESSION { $$ = $1; } | T_INCDEC UNARY_EXPRESSION { $$ = $2; } | UNARY_OPERATOR CAST_EXPRESSION { $$ = $2; } | T_SIZEOF UNARY_EXPRESSION { $$ = $2; } | T_SIZEOF T_LRB T_TYPE_SPEC T_RRB { $$ = new ast_Expression(); } ; UNARY_OPERATOR: T_AND { $$ = $1; } | T_ADDSUB_OP { $$ = $1; } | T_MULT { $$ = $1; } | T_TILDE { $$ = $1; } | T_NOT { $$ = $1; } ; POSTFIX_EXPRESSION: PRIMARY_EXPRESSION { $$ = $1; } | POSTFIX_EXPRESSION T_LSB EXPRESSION T_RSB { $$ = $3; } | POSTFIX_EXPRESSION T_LRB POSTFIX_EXPRESSION_2 { $$ = $3; } | POSTFIX_EXPRESSION T_DOT T_IDENTIFIER { $$ = new ast_Expression(); } | POSTFIX_EXPRESSION T_ARROW T_IDENTIFIER { $$ = new ast_Expression(); } | POSTFIX_EXPRESSION T_INCDEC { $$ = new ast_Expression(); } ; POSTFIX_EXPRESSION_2: T_RRB { $$ = new ast_Expression(); } | ARGUMENT_EXPRESSION_LIST T_RRB { $$ = $1; } ; ARGUMENT_EXPRESSION_LIST: ASSIGNMENT_EXPRESSION { $$ = $1; } | ARGUMENT_EXPRESSION_LIST T_CMA ASSIGNMENT_EXPRESSION { $$ = $3; } ; PRIMARY_EXPRESSION: T_IDENTIFIER { $$ = new ast_Expression(); } | CONSTANT { $$ = new ast_Expression(); } | T_LRB EXPRESSION T_RRB { $$ = $2; } ; CONSTANT: T_INT_CONST { $$ = $1; } ; %% ast_Top *g_root; // Definition of variable (to match declaration earlier) ast_Top *parseAST() { g_root = new ast_Top; yyparse(); return g_root; }