From 6172cc802ea408e9050ec6e3b3f5b6959b07c87d Mon Sep 17 00:00:00 2001 From: Teddy Date: Mon, 24 Mar 2014 23:24:59 +0800 Subject: fancy AST output --- ast.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- ast.h | 5 +++- cibic.y | 27 ++++++++++++++-------- 3 files changed, 92 insertions(+), 21 deletions(-) diff --git a/ast.c b/ast.c index fa3f497..599b67d 100644 --- a/ast.c +++ b/ast.c @@ -11,6 +11,28 @@ CNode *ast_root; void cnode_init() { } +void cnode_reverse_chd(CNode *node) { + static CNode *chdn[MAX_CHDN]; + CNode *p; + int n = 0; + for (p = node->chd; p; p = p->next) + cnode_reverse_chd(p); + for (p = node->chd; p; p = p->next) + chdn[n++] = p; + if (n) + { + node->chd = chdn[--n]; + for (; n; n--) + chdn[n]->next = chdn[n - 1]; + chdn[0]->next = NULL; + } +} + +CNode *cnode_create_ast(CNode *wrapped) { + cnode_reverse_chd(wrapped); + return wrapped; +} + CNode *cnode_create_nop() { CNode *nop = NEW_CNODE; nop->type = NOP; @@ -203,8 +225,8 @@ CNode *cnode_list_wrap(int type, CNode *list) { } char *cnode_debug_type_repr(CNode *ast) { - static char buffer[1024]; - char *type; + static char buffer[1024], abuff[1024]; + char *type, *aptr = abuff; switch (ast->type) { case PROG: type = "prog"; break; @@ -222,10 +244,22 @@ char *cnode_debug_type_repr(CNode *ast) { case INIT_DECLRS: type = "i_declrs"; break; case ARGS: type = "args"; break; case PARAMS: type = "params"; break; - case ID: type = "id"; break; - case INT: type = "int"; break; - case CHAR: type = "char"; break; - case STR: type = "str"; break; + case ID: + type = "id"; + aptr += sprintf(abuff, "%s", ast->rec.strval); + break; + case INT: + type = "int"; + aptr += sprintf(abuff, "%d", ast->rec.intval); + break; + case CHAR: + type = "char"; + aptr += sprintf(abuff, "%c", ast->rec.intval); + break; + case STR: + type = "str"; + aptr += sprintf(abuff, "\"%s\"", ast->rec.strval); + break; case NOP: type = "nop"; break; case EXP: case INITR: @@ -328,21 +362,46 @@ char *cnode_debug_type_repr(CNode *ast) { } } else assert(type); - sprintf(buffer, "%s", type); + if (aptr == abuff) + sprintf(buffer, "%s", type); + else + { + *aptr = '\0'; + sprintf(buffer, "%s:%s", type, abuff); + } return buffer; } -void cnode_debug_print_(CNode *ast) { +void cnode_debug_print_plain(CNode *ast) { printf("(%s", cnode_debug_type_repr(ast)); for (ast = ast->chd; ast; ast = ast->next) { printf(" "); - cnode_debug_print_(ast); + cnode_debug_print_plain(ast); } printf(")"); } -void cnode_debug_print(CNode *ast) { - cnode_debug_print_(ast); +void cnode_debug_print_fancy(CNode *ast, int lvl) { + static int show[1024]; + int i; + show[lvl] = 1; + for (i = 0; i < lvl - 1; i++) + printf("%c ", show[i] ? '|' : ' '); + if (lvl) + printf("|____"); + printf("[%s]\n", cnode_debug_type_repr(ast)); + for (ast = ast->chd; ast; ast = ast->next) + { + if (!ast->next) show[lvl] = 0; + cnode_debug_print_fancy(ast, lvl + 1); + } +} + +void cnode_debug_print(CNode *ast, int fancy) { + if (fancy) + cnode_debug_print_fancy(ast, 0); + else + cnode_debug_print_plain(ast); puts(""); } diff --git a/ast.h b/ast.h index 41aad77..17b75d6 100644 --- a/ast.h +++ b/ast.h @@ -20,6 +20,8 @@ #define STMT_BREAK 1040 #define STMT_RET 1041 +#define MAX_CHDN 1024 + typedef struct CNode { enum { /* Top Level */ @@ -67,6 +69,7 @@ typedef struct CNode { } CNode; void cnode_init(); +CNode *cnode_create_ast(CNode *wrapped); CNode *cnode_create_nop(); CNode *cnode_create_general(int type, int subtype, int pnum, va_list ap); CNode *cnode_list_append(CNode *list, CNode *tail); @@ -89,7 +92,7 @@ CNode *cnode_create_int_const(int val); CNode *cnode_create_char_const(int val); CNode *cnode_create_str_const(char *val); -void cnode_debug_print(CNode *ast); +void cnode_debug_print(CNode *ast, int fancy); extern CNode *ast_root; extern CNode *null; diff --git a/cibic.y b/cibic.y index d054c56..a4f7eb2 100644 --- a/cibic.y +++ b/cibic.y @@ -24,7 +24,7 @@ %start program %% program - : prog_list { ast_root = cnode_list_wrap(PROG, $1); } + : prog_list { ast_root = cnode_create_ast(cnode_list_wrap(PROG, $1)); } prog_list : declaration @@ -33,7 +33,9 @@ prog_list | prog_list function_definition { $$ = cnode_list_append($1, $2); } declaration - : type_specifier ';' { $$ = cnode_create_decl($1, cnode_create_nop()); } + : type_specifier ';' { + $$ = cnode_create_decl($1, cnode_list_wrap(INIT_DECLRS, cnode_create_nop())); + } | type_specifier init_declarators ';' { $$ = cnode_create_decl($1, cnode_list_wrap(INIT_DECLRS, $2)); } @@ -43,7 +45,7 @@ function_definition $$ = 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); + $$ = cnode_create_func($1, $2, cnode_list_wrap(PARAMS, cnode_create_nop()), $5); } parameters @@ -94,8 +96,12 @@ 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);} + : plain_declarator '(' ')' { + $$ = cnode_create_declr(DECLR_FUNC, 2, $1, cnode_list_wrap(PARAMS, cnode_create_nop())); + } + | plain_declarator '(' parameters ')' { + $$ = cnode_create_declr(DECLR_FUNC, 2, $1, cnode_list_wrap(PARAMS, $3)); + } | declarator_array declarator_array @@ -293,9 +299,12 @@ postfix_expression postfix : '[' expression ']' { $$ = cnode_create_exp(POSTFIX_ARR, 1, $2); } - | '(' arguments ')' { $$ = cnode_create_exp(POSTFIX_CALL, 1, - cnode_list_wrap(ARGS, $2)); } - | '(' ')' { $$ = cnode_create_exp(POSTFIX_CALL, 1, cnode_create_nop()); } + | '(' arguments ')' { + $$ = cnode_create_exp(POSTFIX_CALL, 1, cnode_list_wrap(ARGS, $2)); + } + | '(' ')' { + $$ = cnode_create_exp(POSTFIX_CALL, 1, cnode_list_wrap(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); } @@ -327,7 +336,7 @@ void test_ast() { yyparse(); cnode_init(); if (ast_root) - cnode_debug_print(ast_root); + cnode_debug_print(ast_root, 1); else fprintf(stderr, "Syntax Error\n"); } -- cgit v1.2.3