aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ast.c81
-rw-r--r--ast.h5
-rw-r--r--cibic.y27
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");
}