aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--ast.c102
-rw-r--r--ast.h11
-rw-r--r--cibic.l10
-rw-r--r--cibic.y48
5 files changed, 103 insertions, 74 deletions
diff --git a/Makefile b/Makefile
index 9abe133..04edd68 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/ast.c b/ast.c
index e36bb30..fa3f497 100644
--- a/ast.c
+++ b/ast.c
@@ -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)
{
diff --git a/ast.h b/ast.h
index 0b0264a..41aad77 100644
--- a/ast.h
+++ b/ast.h
@@ -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);
diff --git a/cibic.l b/cibic.l
index 37de015..666069e 100644
--- a/cibic.l
+++ b/cibic.l
@@ -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; }
diff --git a/cibic.y b/cibic.y
index 6752883..d054c56 100644
--- a/cibic.y
+++ b/cibic.y
@@ -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;
}