From f218a80d6ca8a69ba0b22cb87f99e8b82162bbee Mon Sep 17 00:00:00 2001 From: Teddy Date: Mon, 24 Mar 2014 20:54:55 +0800 Subject: AST Construction: almost done --- cibic.y | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 171 insertions(+), 30 deletions(-) (limited to 'cibic.y') diff --git a/cibic.y b/cibic.y index daeb35a..6752883 100644 --- a/cibic.y +++ b/cibic.y @@ -12,17 +12,142 @@ %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 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 assignment_operator equality_operator relational_operator shift_operator additive_operator multiplicative_operator unary_operator struct_or_union +%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 +%type unary_expression postfix_expression identifier primary_expression arguments postfix type_specifier program declaration function_definition parameters declarators init_declarators init_declarator initializer array_initializer struct_fields struct_field plain_declaration declarator_array plain_declarator expression_statement compound_statement statement +%type comp_decls comp_stmts selection_statement iteration_statement jump_statement optional_exp declarator %% -debug_top - : expression { ast_root = $1; } +program + : declaration { ast_root = $1; } + | function_definition { ast_root = $1; } + | program declaration { ast_root = cnode_append(ast_root, $2); } + | program function_definition { ast_root = cnode_append(ast_root, $2); } + +declaration + : type_specifier ';' { $$ = cnode_create_decl($1, cnode_create_nop()); } + | type_specifier init_declarators ';' { $$ = cnode_create_decl($1, $2); } + +function_definition + : type_specifier plain_declarator '(' parameters ')' compound_statement { + $$ = cnode_create_func($1, $2, cnode_create_params($4), $6); + } + | type_specifier plain_declarator '(' ')' compound_statement { + $$ = cnode_create_func($1, $2, cnode_create_nop(), $5); + } + +parameters + : plain_declaration + | parameters ',' plain_declaration { $$ = cnode_append($1, $3); } + +declarators + : declarator + | declarators ',' declarator { $$ = cnode_append($1, $3); } + +init_declarators + : init_declarator + | init_declarators ',' init_declarator { $$ = cnode_append($1, $3); } + +init_declarator + : declarator { $$ = cnode_create_init_declr($1, cnode_create_nop()); } + | declarator '=' initializer { $$ = cnode_create_init_declr($1, $3); } + +initializer + : assignment_expression { $$ = cnode_create_initr(INITR_NORM, $1); } + | '{' array_initializer '}' { $$ = cnode_create_initr(INITR_ARR, $2); } + +array_initializer + : initializer + | array_initializer ',' initializer { $$ = cnode_append($1, $3); } + +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); } + | struct_or_union identifier '{' struct_fields '}' { $$ = cnode_create_type_spec($1, 2, $2, $4); } + | struct_or_union '{' struct_fields '}' { $$ = cnode_create_type_spec($1, 2, cnode_create_nop(), $3); } + | struct_or_union identifier { $$ = cnode_create_type_spec($1, 2, $2, cnode_create_nop()); } + +struct_fields + : struct_field + | struct_fields struct_field { $$ = cnode_append($1, $2); } +struct_field + : type_specifier declarators ';' { $$ = cnode_create_struct_field($1, $2); } + +struct_or_union + : KW_STRUCT { $$ = KW_STRUCT; } + | KW_UNION { $$ = KW_UNION; } + +plain_declaration + : type_specifier declarator { $$ = cnode_create_plain_decl($1, $2); } + +declarator + : plain_declarator '(' ')' { $$ = cnode_create_declr(DECLR_FUNC, 2, $1, cnode_create_nop());} + | plain_declarator '(' parameters ')' { $$ = cnode_create_declr(DECLR_FUNC, 2, $1, $3);} + | declarator_array + +declarator_array + : plain_declarator + | declarator_array '[' constant_expression ']' { $$ = cnode_create_declr(DECLR_ARR, 2, $1, $3); } + +plain_declarator + : identifier + | '*' plain_declarator { $$ = cnode_create_declr('*', 1, $2); } + +statement + : expression_statement + | compound_statement + | selection_statement + | iteration_statement + | jump_statement + +expression_statement + : ';' { $$ = cnode_create_stmt(STMT_EXP, 1, cnode_create_nop()); } + | expression ';' { $$ = cnode_create_stmt(STMT_EXP, 1, $1); } + +compound_statement + : '{' comp_decls comp_stmts '}' { + $$ = cnode_create_stmt(STMT_COMP, 2, cnode_create_comp_decls($2), + cnode_create_comp_stmts($3)); + } + +comp_decls + : { $$ = cnode_create_nop(); } + | comp_decls declaration { $$ = cnode_append($1, $2); } + +comp_stmts + : { $$ = cnode_create_nop(); } + | comp_stmts statement { $$ = cnode_append($1, $2); } + +selection_statement + : KW_IF '(' expression ')' statement { + $$ = cnode_create_stmt(STMT_IF, 3, $3, $5, cnode_create_nop()); + } + | KW_IF '(' expression ')' statement KW_ELSE statement { + $$ = cnode_create_stmt(STMT_IF, 3, $3, $5, $7); + } + +iteration_statement + : KW_WHILE '(' expression ')' statement { + $$ = cnode_create_stmt(STMT_WHILE, 2, $3, $5); + } + | KW_FOR '(' optional_exp ';' optional_exp ';' optional_exp ')' statement { + $$ = cnode_create_stmt(STMT_FOR, 4, $3, $5, $7, $9); + } + +optional_exp + : { $$ = cnode_create_nop(); } + | expression + +jump_statement + : KW_CONT ';' { $$ = cnode_create_stmt(STMT_CONT, 0); } + | KW_BREAK ';' { $$ = cnode_create_stmt(STMT_BREAK, 0); } + | KW_RET optional_exp ';' { $$ = cnode_create_stmt(STMT_RET, 1, $2); } + expression : assignment_expression | expression ',' assignment_expression { $$ = cnode_create_exp(',', 2, $1, $3); } @@ -47,27 +172,39 @@ assignment_operator 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_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); } + | 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); } + | 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); } + | 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); } + | 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); } + : relational_expression + | equality_expression equality_operator relational_expression { + $$ = cnode_create_exp($2, 2, $1, $3); + } equality_operator : OPT_EQ { $$ = OPT_EQ; } @@ -75,7 +212,9 @@ equality_operator relational_expression : shift_expression - | relational_expression relational_operator shift_expression { $$ = cnode_create_exp($2, 2, $1, $3); } + | relational_expression relational_operator shift_expression { + $$ = cnode_create_exp($2, 2, $1, $3); + } relational_operator : '<' { $$ = '<'; } @@ -85,7 +224,9 @@ relational_operator shift_expression : additive_expression - | shift_expression shift_operator additive_expression { $$ = cnode_create_exp($2, 2, $1, $3); } + | shift_expression shift_operator additive_expression { + $$ = cnode_create_exp($2, 2, $1, $3); + } shift_operator : OPT_SHL { $$ = OPT_SHL; } @@ -93,7 +234,9 @@ shift_operator additive_expression : multiplicative_expression - | additive_expression additive_operator multiplicative_expression { $$ = cnode_create_exp($2, 2, $1, $3); } + | additive_expression additive_operator multiplicative_expression { + $$ = cnode_create_exp($2, 2, $1, $3); + } additive_operator : '+' { $$ = '+'; } @@ -101,7 +244,9 @@ additive_operator multiplicative_expression : cast_expression - | multiplicative_expression multiplicative_operator cast_expression { $$ = cnode_create_exp($2, 2, $1, $3); } + | multiplicative_expression multiplicative_operator cast_expression { + $$ = cnode_create_exp($2, 2, $1, $3); + } multiplicative_operator : '*' { $$ = '*'; } @@ -110,7 +255,9 @@ multiplicative_operator cast_expression : unary_expression - | '(' type_name ')' cast_expression { $$ = cnode_create_exp(EXP_CAST, 2, $2, $4); } + | '(' type_name ')' cast_expression { + $$ = cnode_create_exp(EXP_CAST, 2, $2, $4); + } type_name : type_specifier @@ -138,8 +285,9 @@ postfix_expression postfix : '[' expression ']' { $$ = cnode_create_exp(POSTFIX_ARR, 1, $2); } - | '(' arguments ')' { $$ = cnode_create_exp(POSTFIX_CALL, 1, $2); } - | '(' ')' { $$ = cnode_create_exp(POSTFIX_CALL, 1, NULL); } + | '(' arguments ')' { $$ = cnode_create_exp(POSTFIX_CALL, 1, + cnode_create_args($2)); } + | '(' ')' { $$ = cnode_create_exp(POSTFIX_CALL, 1, cnode_create_nop()); } | '.' 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); } @@ -158,17 +306,9 @@ primary_expression 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 yywrap() { + return 1; } int yyerror(char *s) { @@ -177,6 +317,7 @@ int yyerror(char *s) { extern FILE *yyin; void test_ast() { yyparse(); + cnode_init(); if (ast_root) cnode_debug_print(ast_root); else -- cgit v1.2.3