diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | ast.c | 102 | ||||
-rw-r--r-- | ast.h | 11 | ||||
-rw-r--r-- | cibic.l | 10 | ||||
-rw-r--r-- | cibic.y | 48 |
5 files changed, 103 insertions, 74 deletions
@@ -9,11 +9,11 @@ debug: cibic: lex.yy.o cibic.tab.o ast.o gcc -o cibic lex.yy.o cibic.tab.o ast.o lex.yy.o: lex.yy.c - gcc -c lex.yy.c -Wall -Wextra + gcc -c lex.yy.c cibic.tab.o: cibic.tab.c - gcc -c cibic.tab.c -Wall -Wextra + gcc -c cibic.tab.c ast.o: ast.c - gcc -c ast.c -g -Wall -Wextra + gcc -c ast.c -g -Wall -Wextra -DCNODE_DEBUG lex.yy.c: cibic.l flex cibic.l cibic.tab.c: cibic.y @@ -23,28 +23,26 @@ CNode *cnode_create_general(int type, int subtype, int pnum, va_list ap) { CNode *exp = NEW_CNODE; exp->type = type; exp->rec.subtype = subtype; - exp->next = NULL; + exp->next = exp->chd = NULL; for (i = 0; i < pnum; i++) { CNode *subexp = va_arg(ap, CNode*); - if (subexp->next) - { - puts("asdf"); - } +#ifdef CNODE_DEBUG assert(subexp->next == NULL); +#endif subexp->next = exp->chd; exp->chd = subexp; } return exp; } -CNode *cnode_append(CNode *node, CNode *tail) { - if (node->type == NOP) +CNode *cnode_list_append(CNode *list, CNode *tail) { + if (list->type == NOP) { - free(node); + free(list); return tail; } - tail->next = node; + tail->next = list; return tail; } @@ -123,22 +121,34 @@ CNode *cnode_create_initr(int initr_type, CNode *body) { initr->type = INITR; initr->rec.subtype = initr_type; initr->chd = body; + initr->next = NULL; return initr; } CNode *cnode_create_decl(CNode *type, CNode *init_declrs) { CNode *decl = NEW_CNODE; +#ifdef CNODE_DEBUG + assert(type->next == NULL); + assert(init_declrs->next == NULL); +#endif decl->type = DECL; - decl->chd = type; - type->next = init_declrs; + decl->next = NULL; + decl->chd = init_declrs; + init_declrs->next = type; return decl; } CNode *cnode_create_func(CNode *type, CNode *plain_decl, CNode *params, CNode *stmt) { CNode *func = NEW_CNODE; +#ifdef CNODE_DEBUG + assert(type->next == NULL); + assert(plain_decl->next == NULL); + assert(params->next == NULL); + assert(stmt->next == NULL); +#endif func->type = FUNC_DEF; - func->chd = stmt; func->next = NULL; + func->chd = stmt; stmt->next = params; params->next = plain_decl; plain_decl->next = type; @@ -147,7 +157,12 @@ CNode *cnode_create_func(CNode *type, CNode *plain_decl, CNode *params, CNode *s CNode *cnode_create_init_declr(CNode *declr, CNode *initr) { CNode *init_declr = NEW_CNODE; +#ifdef CNODE_DEBUG + assert(declr->next == NULL); + assert(initr->next == NULL); +#endif init_declr->type = INIT_DECLR; + init_declr->next = NULL; init_declr->chd = initr; initr->next = declr; return init_declr; @@ -155,7 +170,12 @@ CNode *cnode_create_init_declr(CNode *declr, CNode *initr) { CNode *cnode_create_struct_field(CNode *type_spec, CNode *declrs) { CNode *field = NEW_CNODE; +#ifdef CNODE_DEBUG + assert(type_spec->next == NULL); + assert(declrs->next == NULL); +#endif field->type = FIELD; + field->next = NULL; field->chd = declrs; declrs->next = type_spec; return field; @@ -163,57 +183,43 @@ CNode *cnode_create_struct_field(CNode *type_spec, CNode *declrs) { CNode *cnode_create_plain_decl(CNode *type_spec, CNode *declr) { CNode *pdecl = NEW_CNODE; +#ifdef CNODE_DEBUG + assert(type_spec->next == NULL); + assert(declr->next == NULL); +#endif pdecl->type = PLAIN_DECL; + pdecl->next = NULL; pdecl->chd = declr; declr->next = type_spec; return pdecl; } -CNode *cnode_create_comp_decls(CNode *decls) { - CNode *comp_decls = NEW_CNODE; - comp_decls->type = COMP_DECLS; - comp_decls->chd = decls; - return comp_decls; -} - -CNode *cnode_create_comp_stmts(CNode *stmts) { - CNode *comp_stmts = NEW_CNODE; - comp_stmts->type = COMP_STMTS; - comp_stmts->chd = stmts; - comp_stmts->next = NULL; - return comp_stmts; -} - -CNode *cnode_create_args(CNode *arg_list) { - CNode *args = NEW_CNODE; - args->type = ARGS; - args->chd = arg_list; - args->next = NULL; - return args; -} - -CNode *cnode_create_params(CNode *plist) { - CNode *params = NEW_CNODE; - params->type = PARAMS; - params->chd = plist; - params->next = NULL; - return params; +CNode *cnode_list_wrap(int type, CNode *list) { + CNode *wlist = NEW_CNODE; + wlist->type = type; + wlist->next = NULL; + wlist->chd = list; + return wlist; } char *cnode_debug_type_repr(CNode *ast) { - static buffer[1024]; - char *type = NULL; + static char buffer[1024]; + char *type; switch (ast->type) { case PROG: type = "prog"; break; case FUNC_DEF: type = "func"; break; + case DECLS: type = "prg_decls"; break; + case FUNCS: type = "prg_funcs"; break; case DECL: type = "decl"; break; case DECLR: type = "declr"; break; case INIT_DECLR: type = "init_declr"; break; case PLAIN_DECL: type = "p_decl"; break; case TYPE_NAME: type = "type_name"; break; - case COMP_STMTS: type = "stmts"; break; - case COMP_DECLS: type = "decls"; break; + case COMP_STMTS: type = "blk_stmts"; break; + case COMP_DECLS: type = "blk_decls"; break; + case DECLRS: type = "declrs"; break; + case INIT_DECLRS: type = "i_declrs"; break; case ARGS: type = "args"; break; case PARAMS: type = "params"; break; case ID: type = "id"; break; @@ -221,6 +227,12 @@ char *cnode_debug_type_repr(CNode *ast) { case CHAR: type = "char"; break; case STR: type = "str"; break; case NOP: type = "nop"; break; + case EXP: + case INITR: + case TYPE_SPEC: + case FIELD: + case STMT: + type = NULL; break; } if (ast->type == EXP) { @@ -27,11 +27,15 @@ typedef struct CNode { FUNC_DEF, DECL, /* declaration */ DECLR, /* declarator */ + DECLRS, INIT_DECLR, + INIT_DECLRS, INITR, /* initializer */ TYPE_SPEC, FIELD, /* struct-or-union field */ PLAIN_DECL, + DECLS, + FUNCS, /* Statments */ STMT, @@ -65,7 +69,8 @@ typedef struct CNode { void cnode_init(); CNode *cnode_create_nop(); CNode *cnode_create_general(int type, int subtype, int pnum, va_list ap); -CNode *cnode_append(CNode *node, CNode *tail); +CNode *cnode_list_append(CNode *list, CNode *tail); +CNode *cnode_list_wrap(int type, CNode *list); CNode *cnode_create_exp(int exp_type, int pnum, ...); CNode *cnode_create_type_spec(int spec_type, int pnum, ...); @@ -78,10 +83,6 @@ CNode *cnode_create_func(CNode *type, CNode *plain_decl, CNode *params, CNode *s CNode *cnode_create_init_declr(CNode *declr, CNode *initr); CNode *cnode_create_struct_field(CNode *type_spec, CNode *declrs); CNode *cnode_create_plain_decl(CNode *type_spec, CNode *declr); -CNode *cnode_create_comp_decls(CNode *decls); -CNode *cnode_create_comp_stmts(CNode *stmts); -CNode *cnode_create_args(CNode *arg_list); -CNode *cnode_create_params(CNode *plist); CNode *cnode_create_identifier(char *val); CNode *cnode_create_int_const(int val); @@ -4,7 +4,7 @@ letter [a-zA-Z_$] digit [0-9] -%s IN_BLOCK_COMMENT IN_INLINE_COMMENT +%s IN_BLOCK_COMMENT IN_INLINE_COMMENT IN_DIRECTIVE %% <INITIAL>{ @@ -25,6 +25,14 @@ digit [0-9] [^\n]+ } +<INITIAL>{ +"#" BEGIN(IN_INLINE_COMMENT); +} +<IN_DIRECTIVE>{ +\n BEGIN(INITIAL); +[^\n]+ +} + "void" { return KW_VOID; } "char" { return KW_CHAR; } "int" { return KW_INT; } @@ -20,21 +20,27 @@ %type<cnode> expression assignment_expression constant_expression %type<cnode> 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 %type<cnode> 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<cnode> comp_decls comp_stmts selection_statement iteration_statement jump_statement optional_exp declarator +%type<cnode> comp_decls comp_stmts selection_statement iteration_statement jump_statement optional_exp declarator prog_list +%start program %% 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); } + : prog_list { ast_root = cnode_list_wrap(PROG, $1); } + +prog_list + : declaration + | function_definition + | prog_list declaration { $$ = cnode_list_append($1, $2); } + | prog_list function_definition { $$ = cnode_list_append($1, $2); } declaration : type_specifier ';' { $$ = cnode_create_decl($1, cnode_create_nop()); } - | type_specifier init_declarators ';' { $$ = cnode_create_decl($1, $2); } + | type_specifier init_declarators ';' { + $$ = cnode_create_decl($1, cnode_list_wrap(INIT_DECLRS, $2)); + } function_definition : type_specifier plain_declarator '(' parameters ')' compound_statement { - $$ = cnode_create_func($1, $2, cnode_create_params($4), $6); + $$ = cnode_create_func($1, $2, cnode_list_wrap(PARAMS, $4), $6); } | type_specifier plain_declarator '(' ')' compound_statement { $$ = cnode_create_func($1, $2, cnode_create_nop(), $5); @@ -42,15 +48,15 @@ function_definition parameters : plain_declaration - | parameters ',' plain_declaration { $$ = cnode_append($1, $3); } + | parameters ',' plain_declaration { $$ = cnode_list_append($1, $3); } declarators : declarator - | declarators ',' declarator { $$ = cnode_append($1, $3); } + | declarators ',' declarator { $$ = cnode_list_append($1, $3); } init_declarators : init_declarator - | init_declarators ',' init_declarator { $$ = cnode_append($1, $3); } + | init_declarators ',' init_declarator { $$ = cnode_list_append($1, $3); } init_declarator : declarator { $$ = cnode_create_init_declr($1, cnode_create_nop()); } @@ -62,7 +68,7 @@ initializer array_initializer : initializer - | array_initializer ',' initializer { $$ = cnode_append($1, $3); } + | array_initializer ',' initializer { $$ = cnode_list_append($1, $3); } type_specifier : KW_VOID { $$ = cnode_create_type_spec(KW_VOID, 0); } @@ -74,9 +80,11 @@ type_specifier struct_fields : struct_field - | struct_fields struct_field { $$ = cnode_append($1, $2); } + | struct_fields struct_field { $$ = cnode_list_append($1, $2); } struct_field - : type_specifier declarators ';' { $$ = cnode_create_struct_field($1, $2); } + : type_specifier declarators ';' { + $$ = cnode_create_struct_field($1, cnode_list_wrap(DECLRS, $2)); + } struct_or_union : KW_STRUCT { $$ = KW_STRUCT; } @@ -111,17 +119,17 @@ expression_statement compound_statement : '{' comp_decls comp_stmts '}' { - $$ = cnode_create_stmt(STMT_COMP, 2, cnode_create_comp_decls($2), - cnode_create_comp_stmts($3)); + $$ = cnode_create_stmt(STMT_COMP, 2, cnode_list_wrap(COMP_DECLS, $2), + cnode_list_wrap(COMP_STMTS, $3)); } comp_decls : { $$ = cnode_create_nop(); } - | comp_decls declaration { $$ = cnode_append($1, $2); } + | comp_decls declaration { $$ = cnode_list_append($1, $2); } comp_stmts : { $$ = cnode_create_nop(); } - | comp_stmts statement { $$ = cnode_append($1, $2); } + | comp_stmts statement { $$ = cnode_list_append($1, $2); } selection_statement : KW_IF '(' expression ')' statement { @@ -286,7 +294,7 @@ postfix_expression postfix : '[' expression ']' { $$ = cnode_create_exp(POSTFIX_ARR, 1, $2); } | '(' arguments ')' { $$ = cnode_create_exp(POSTFIX_CALL, 1, - cnode_create_args($2)); } + cnode_list_wrap(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); } @@ -295,7 +303,7 @@ postfix arguments : assignment_expression - | arguments ',' assignment_expression { $$ = cnode_append($1, $3); } + | arguments ',' assignment_expression { $$ = cnode_list_append($1, $3); } primary_expression : identifier @@ -326,7 +334,7 @@ void test_ast() { int main() { int ret; - yyin = fopen("in", "r"); + yyin = fopen("in.c", "r"); test_ast(); return 0; } |