%{ #include #include "ast.h" %} %union { int intval; char *strval; struct CNode *cnode; } %token IDENTIFIER INT_CONST CHAR_CONST STR_CONST %token KW_VOID KW_CHAR KW_INT KW_STRUCT KW_UNION KW_IF KW_ELSE KW_WHILE %token KW_FOR KW_CONT KW_BREAK KW_RET KW_SIZEOF %token OPT_OR OPT_AND OPT_EQ OPT_NE OPT_LE OPT_GE OPT_SHL OPT_SHR OPT_INC OPT_DEC OPT_PTR %token ASS_MUL ASS_DIV ASS_MOD ASS_ADD ASS_SUB ASS_SHL ASS_SHR ASS_AND ASS_XOR ASS_OR %token UNKNOWN %type INT_CONST CHAR_CONST %type IDENTIFIER STR_CONST %type assignment_operator equality_operator relational_operator shift_operator additive_operator multiplicative_operator unary_operator %type expression assignment_expression constant_expression %type 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 type_name %typeunary_expression postfix_expression identifier primary_expression arguments postfix type_specifier %% debug_top : expression { ast_root = $1; } expression : assignment_expression | expression ',' assignment_expression { $$ = cnode_create_exp(',', 2, $1, $3); } assignment_expression : logical_or_expression | unary_expression assignment_operator assignment_expression { $$ = cnode_create_exp($2, 2, $1, $3); } assignment_operator : '=' { $$ = '='; } | ASS_MUL { $$ = ASS_MUL; } | ASS_DIV { $$ = ASS_DIV; } | ASS_MOD { $$ = ASS_MOD; } | ASS_ADD { $$ = ASS_ADD; } | ASS_SUB { $$ = ASS_SUB; } | ASS_SHL { $$ = ASS_SHL; } | ASS_SHR { $$ = ASS_SHR; } | ASS_AND { $$ = ASS_AND; } | ASS_XOR { $$ = ASS_XOR; } | ASS_OR { $$ = ASS_OR; } constant_expression: logical_or_expression logical_or_expression : logical_and_expression | logical_or_expression OPT_OR logical_and_expression { $$ = cnode_create_exp(OPT_OR, 2, $1, $3); } logical_and_expression : inclusive_or_expression | logical_and_expression OPT_AND inclusive_or_expression { $$ = cnode_create_exp(OPT_AND, 2, $1, $3); } inclusive_or_expression : exclusive_or_expression | inclusive_or_expression '|' exclusive_or_expression { $$ = cnode_create_exp('|', 2, $1, $3); } exclusive_or_expression : and_expression | exclusive_or_expression '^' and_expression { $$ = cnode_create_exp('^', 2, $1, $3); } and_expression : equality_expression | and_expression '&' equality_expression { $$ = cnode_create_exp('&', 2, $1, $3); } equality_expression : relational_expression | equality_expression equality_operator relational_expression { $$ = cnode_create_exp($2, 2, $1, $3); } equality_operator : OPT_EQ { $$ = OPT_EQ; } | OPT_NE { $$ = OPT_NE; } relational_expression : shift_expression | relational_expression relational_operator shift_expression { $$ = cnode_create_exp($2, 2, $1, $3); } relational_operator : '<' { $$ = '<'; } | '>' { $$ = '>'; } | OPT_LE { $$ = OPT_LE; } | OPT_GE { $$ = OPT_GE; } shift_expression : additive_expression | shift_expression shift_operator additive_expression { $$ = cnode_create_exp($2, 2, $1, $3); } shift_operator : OPT_SHL { $$ = OPT_SHL; } | OPT_SHR { $$ = OPT_SHR; } additive_expression : multiplicative_expression | additive_expression additive_operator multiplicative_expression { $$ = cnode_create_exp($2, 2, $1, $3); } additive_operator : '+' { $$ = '+'; } | '-' { $$ = '-'; } multiplicative_expression : cast_expression | multiplicative_expression multiplicative_operator cast_expression { $$ = cnode_create_exp($2, 2, $1, $3); } multiplicative_operator : '*' { $$ = '*'; } | '/' { $$ = '/'; } | '%' { $$ = '%'; } cast_expression : unary_expression | '(' type_name ')' cast_expression { $$ = cnode_create_exp(EXP_CAST, 2, $2, $4); } type_name : type_specifier | type_name '*' { $$ = cnode_create_exp('*', 1, $1); } unary_expression : postfix_expression | OPT_INC unary_expression { $$ = cnode_create_exp(OPT_INC, 1, $2); } | OPT_DEC unary_expression { $$ = cnode_create_exp(OPT_DEC, 1, $2); } | unary_operator cast_expression { $$ = cnode_create_exp($1, 1, $2); } | KW_SIZEOF unary_expression { $$ = cnode_create_exp(KW_SIZEOF, 1, $2); } | KW_SIZEOF '(' type_name ')' { $$ = cnode_create_exp(KW_SIZEOF, 1, $3); } unary_operator : '&' { $$ = '&'; } | '*' { $$ = '*'; } | '+' { $$ = '+'; } | '-' { $$ = '-'; } | '~' { $$ = '~'; } | '!' { $$ = '!'; } postfix_expression : primary_expression | postfix_expression postfix { $$ = cnode_create_exp(EXP_POSTFIX, 2, $1, $2); } postfix : '[' expression ']' { $$ = cnode_create_exp(POSTFIX_ARR, 1, $2); } | '(' arguments ')' { $$ = cnode_create_exp(POSTFIX_CALL, 1, $2); } | '(' ')' { $$ = cnode_create_exp(POSTFIX_CALL, 1, NULL); } | '.' identifier { $$ = cnode_create_exp(POSTFIX_DOT, 1, $2); } | OPT_PTR identifier { $$ = cnode_create_exp(POSTFIX_PTR, 1, $2); } | OPT_INC { $$ = cnode_create_exp(OPT_INC, 0); } | OPT_DEC { $$ = cnode_create_exp(OPT_DEC, 0); } arguments : assignment_expression | arguments ',' assignment_expression { $$ = cnode_append($1, $3); } primary_expression : identifier | INT_CONST { $$ = cnode_create_int_const($1); } | CHAR_CONST { $$ = cnode_create_char_const($1); } | STR_CONST { $$ = cnode_create_str_const($1); } | '(' expression ')' { $$ = $2; } identifier : IDENTIFIER { $$ = cnode_create_identifier($1); } type_specifier : KW_VOID { $$ = cnode_create_type_spec(KW_VOID, 0); } | KW_CHAR { $$ = cnode_create_type_spec(KW_CHAR, 0); } | KW_INT { $$ = cnode_create_type_spec(KW_INT, 0); } /* to be continue */ %% int yywrap() { return 1; } int yyerror(char *s) { } extern FILE *yyin; void test_ast() { yyparse(); if (ast_root) cnode_debug_print(ast_root); else fprintf(stderr, "Syntax Error\n"); } int main() { int ret; yyin = fopen("in", "r"); test_ast(); return 0; }