diff options
author | Teddy <[email protected]> | 2014-03-24 20:54:55 +0800 |
---|---|---|
committer | Teddy <[email protected]> | 2014-03-24 20:54:55 +0800 |
commit | f218a80d6ca8a69ba0b22cb87f99e8b82162bbee (patch) | |
tree | 796058d507c602ce76b91b862acb6fdf9912863f | |
parent | ccab148f1310b3cadffb99005941e39fa932d295 (diff) |
AST Construction: almost done
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | ast.c | 336 | ||||
-rw-r--r-- | ast.h | 61 | ||||
-rw-r--r-- | cibic.y | 201 |
4 files changed, 561 insertions, 46 deletions
@@ -3,14 +3,17 @@ all: cibic run: ./cibic +debug: + gdb cibic + 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 + gcc -c lex.yy.c -Wall -Wextra cibic.tab.o: cibic.tab.c - gcc -c cibic.tab.c + gcc -c cibic.tab.c -Wall -Wextra ast.o: ast.c - gcc -c ast.c -g + gcc -c ast.c -g -Wall -Wextra lex.yy.c: cibic.l flex cibic.l cibic.tab.c: cibic.y @@ -0,0 +1,336 @@ +#include <stdlib.h> +#include <assert.h> +#include <stdarg.h> +#include <stdio.h> +#include "ast.h" +#include "cibic.tab.h" +#define NEW_CNODE ((CNode *)malloc(sizeof(CNode))) + +CNode *ast_root; + +void cnode_init() { +} + +CNode *cnode_create_nop() { + CNode *nop = NEW_CNODE; + nop->type = NOP; + nop->next = nop->chd = NULL; + return nop; +} + +CNode *cnode_create_general(int type, int subtype, int pnum, va_list ap) { + int i; + CNode *exp = NEW_CNODE; + exp->type = type; + exp->rec.subtype = subtype; + exp->next = NULL; + for (i = 0; i < pnum; i++) + { + CNode *subexp = va_arg(ap, CNode*); + if (subexp->next) + { + puts("asdf"); + } + assert(subexp->next == NULL); + subexp->next = exp->chd; + exp->chd = subexp; + } + return exp; +} + +CNode *cnode_append(CNode *node, CNode *tail) { + if (node->type == NOP) + { + free(node); + return tail; + } + tail->next = node; + return tail; +} + +CNode *cnode_create_identifier(char *val) { + CNode *exp = NEW_CNODE; + exp->type = ID; + exp->chd = exp->next = NULL; + exp->rec.strval = val; + return exp; +} + +CNode *cnode_create_int_const(int val) { + /* TODO: overflow checking */ + CNode *exp = NEW_CNODE; + exp->type = INT; + exp->chd = exp->next = NULL; + exp->rec.intval = val; + return exp; +} + +CNode *cnode_create_char_const(int val) { + /* TODO: overflow checking */ + CNode *exp = NEW_CNODE; + exp->type = CHAR; + exp->chd = exp->next = NULL; + exp->rec.intval = val; + return exp; +} + +CNode *cnode_create_str_const(char *val) { + CNode *exp = NEW_CNODE; + exp->type = STR; + exp->chd = exp->next = NULL; + exp->rec.strval = val; + return exp; +} + +CNode *cnode_create_exp(int exp_type, int pnum, ...) { + CNode *ret; + va_list ap; + va_start(ap, pnum); + ret = cnode_create_general(EXP, exp_type, pnum, ap); + va_end(ap); + return ret; +} + +CNode *cnode_create_type_spec(int spec_type, int pnum, ...) { + CNode *ret; + va_list ap; + va_start(ap, pnum); + ret = cnode_create_general(TYPE_SPEC, spec_type, pnum, ap); + va_end(ap); + return ret; +} + +CNode *cnode_create_declr(int declr_type, int pnum, ...) { + CNode *ret; + va_list ap; + va_start(ap, pnum); + ret = cnode_create_general(DECLR, declr_type, pnum, ap); + va_end(ap); + return ret; +} + +CNode *cnode_create_stmt(int stmt_type, int pnum, ...) { + CNode *ret; + va_list ap; + va_start(ap, pnum); + ret = cnode_create_general(STMT, stmt_type, pnum, ap); + va_end(ap); + return ret; +} + +CNode *cnode_create_initr(int initr_type, CNode *body) { + CNode *initr = NEW_CNODE; + initr->type = INITR; + initr->rec.subtype = initr_type; + initr->chd = body; + return initr; +} + +CNode *cnode_create_decl(CNode *type, CNode *init_declrs) { + CNode *decl = NEW_CNODE; + decl->type = DECL; + decl->chd = type; + type->next = init_declrs; + return decl; +} + +CNode *cnode_create_func(CNode *type, CNode *plain_decl, CNode *params, CNode *stmt) { + CNode *func = NEW_CNODE; + func->type = FUNC_DEF; + func->chd = stmt; + func->next = NULL; + stmt->next = params; + params->next = plain_decl; + plain_decl->next = type; + return func; +} + +CNode *cnode_create_init_declr(CNode *declr, CNode *initr) { + CNode *init_declr = NEW_CNODE; + init_declr->type = INIT_DECLR; + init_declr->chd = initr; + initr->next = declr; + return init_declr; +} + +CNode *cnode_create_struct_field(CNode *type_spec, CNode *declrs) { + CNode *field = NEW_CNODE; + field->type = FIELD; + field->chd = declrs; + declrs->next = type_spec; + return field; +} + +CNode *cnode_create_plain_decl(CNode *type_spec, CNode *declr) { + CNode *pdecl = NEW_CNODE; + pdecl->type = PLAIN_DECL; + 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; +} + +char *cnode_debug_type_repr(CNode *ast) { + static buffer[1024]; + char *type = NULL; + switch (ast->type) + { + case PROG: type = "prog"; break; + case FUNC_DEF: type = "func"; 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 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 NOP: type = "nop"; break; + } + if (ast->type == EXP) + { + switch (ast->rec.subtype) + { + case ',': type = ","; break; + case '=': type = "="; break; + case ASS_MUL: type = "*="; break; + case ASS_DIV: type = "/="; break; + case ASS_MOD: type = "%="; break; + case ASS_ADD: type = "+="; break; + case ASS_SUB: type = "-="; break; + case ASS_SHL: type = "<<="; break; + case ASS_SHR: type = ">>="; break; + case ASS_AND: type = "&="; break; + case ASS_XOR: type = "^="; break; + case ASS_OR: type = "|="; break; + case OPT_OR: type = "||"; break; + case OPT_AND: type = "&&"; break; + case '|': type = "|"; break; + case '^': type = "^"; break; + case '&': type = "&"; break; + case OPT_EQ: type = "=="; break; + case OPT_NE: type = "!="; break; + case '<': type = "<"; break; + case '>': type = ">"; break; + case OPT_LE: type = "<="; break; + case OPT_GE: type = ">="; break; + case OPT_SHL: type = "<<"; break; + case OPT_SHR: type = ">>"; break; + case '+': type = "+"; break; + case '-': type = "-"; break; + case '*': type = "*"; break; + case '/': type = "/"; break; + case '%': type = "%"; break; + case EXP_CAST: type = "cast"; break; + case OPT_INC: type = "++"; break; + case OPT_DEC: type = "--"; break; + case '~': type = "~"; break; + case '!': type = "!"; break; + case KW_SIZEOF: type = "sizeof"; break; + case EXP_POSTFIX: type = "pofix"; break; + case POSTFIX_ARR: type = "arr"; break; + case POSTFIX_CALL: type = "call"; break; + case POSTFIX_DOT: type = "dot"; break; + case POSTFIX_PTR: type = "ptr"; break; + default: assert(0); + } + } + else if (ast->type == TYPE_SPEC) + { + switch (ast->rec.subtype) + { + case KW_VOID: type = "void"; break; + case KW_CHAR: type = "char"; break; + case KW_INT: type = "int"; break; + case KW_STRUCT: type = "struct"; break; + case KW_UNION: type = "union"; break; + default: assert(0); + } + } + else if (ast->type == DECLR) + { + switch (ast->rec.subtype) + { + case DECLR_FUNC: type = "func"; break; + case DECLR_ARR: type = "arr"; break; + default: assert(0); + } + } + else if (ast->type == STMT) + { + switch (ast->rec.subtype) + { + case STMT_EXP: type = "exp"; break; + case STMT_COMP: type = "blk"; break; + case STMT_IF: type = "if"; break; + case STMT_WHILE: type = "while"; break; + case STMT_FOR: type = "for"; break; + case STMT_CONT: type = "cont"; break; + case STMT_BREAK: type = "break"; break; + case STMT_RET: type = "ret"; break; + default: assert(0); + } + } + else if (ast->type == INITR) + { + switch (ast->rec.subtype) + { + case INITR_NORM: type = "initr_n"; break; + case INITR_ARR: type = "initr_a"; break; + default: assert(0); + } + } + else assert(type); + sprintf(buffer, "%s", type); + return buffer; +} + +void cnode_debug_print_(CNode *ast) { + printf("(%s", cnode_debug_type_repr(ast)); + for (ast = ast->chd; ast; ast = ast->next) + { + printf(" "); + cnode_debug_print_(ast); + } + printf(")"); +} + +void cnode_debug_print(CNode *ast) { + cnode_debug_print_(ast); + puts(""); +} @@ -7,33 +7,48 @@ #define POSTFIX_DOT 1027 #define POSTFIX_PTR 1028 #define EXP_CAST 1029 +#define INITR_NORM 1030 +#define INITR_ARR 1031 +#define DECLR_FUNC 1032 +#define DECLR_ARR 1033 +#define STMT_EXP 1034 +#define STMT_COMP 1035 +#define STMT_IF 1036 +#define STMT_WHILE 1037 +#define STMT_FOR 1038 +#define STMT_CONT 1039 +#define STMT_BREAK 1040 +#define STMT_RET 1041 typedef struct CNode { enum { /* Top Level */ - PROG, FUNC_DEF, PARAMS, + PROG, + FUNC_DEF, DECL, /* declaration */ DECLR, /* declarator */ - DECLRS, - INIT_DECLRS, INIT_DECLR, + INIT_DECLR, INITR, /* initializer */ TYPE_SPEC, - STRUCT, UNION, - PLAIN_DECL, PLAIN_DECLR, + FIELD, /* struct-or-union field */ + PLAIN_DECL, /* Statments */ - EXP_STMT, /* expression-statment */ - COMP_STMT, IF_STMT, /* selection-statment */ - WHILE_STMT, FOR_STMT, - CONT_STMT , BREAK_STMT, RET_STMT, /* 'continue', 'break', 'return' */ + STMT, - /* Expressions (expressions use their token ID to denote their types */ + /* Expressions */ EXP, TYPE_NAME, ID, /* identifier */ INT, /* INT_CONST */ CHAR, - STR + STR, + NOP, + + COMP_STMTS, + COMP_DECLS, + ARGS, + PARAMS } type; union { int intval; @@ -47,15 +62,35 @@ typedef struct CNode { } loc; } 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_create_exp(int exp_type, int pnum, ...); CNode *cnode_create_type_spec(int spec_type, int pnum, ...); -CNode *cnode_append(CNode *node, CNode *tail); +CNode *cnode_create_declr(int declr_type, int pnum, ...); +CNode *cnode_create_stmt(int stmt_type, int pnum, ...); +CNode *cnode_create_initr(int initr_type, CNode *body); + +CNode *cnode_create_decl(CNode *type, CNode *init_declrs); +CNode *cnode_create_func(CNode *type, CNode *plain_decl, CNode *params, CNode *stmt); +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); CNode *cnode_create_char_const(int val); CNode *cnode_create_str_const(char *val); -CNode *cnode_debug_print(CNode *ast); + +void cnode_debug_print(CNode *ast); extern CNode *ast_root; +extern CNode *null; #endif @@ -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<intval> INT_CONST CHAR_CONST %type<strval> IDENTIFIER STR_CONST -%type<intval> assignment_operator equality_operator relational_operator shift_operator additive_operator multiplicative_operator unary_operator -%type<cnode> expression assignment_expression constant_expression +%type<intval> assignment_operator equality_operator relational_operator shift_operator additive_operator multiplicative_operator unary_operator struct_or_union +%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 +%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 %% -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 |