diff --git a/src/ast.h b/src/ast.h index 424a2620..cb2b003f 100644 --- a/src/ast.h +++ b/src/ast.h @@ -2,7 +2,12 @@ #define KMC_C90_COMPILER_AST_H enum AstTag { - AST_IDENTIFIER + AST_IDENTIFIER, + AST_COMPOUND_STATEMENT, + AST_GOTO_STATEMENT, + AST_CONTINUE_STATEMENT, + AST_BREAK_STATEMENT, + AST_RETURN_STATEMENT }; #endif /* KMC_C90_COMPILER_AST_H */ diff --git a/src/parser.y b/src/parser.y index a655abc5..a85d28bc 100644 --- a/src/parser.y +++ b/src/parser.y @@ -214,17 +214,27 @@ parameter-declaration ; statement-list.opt -: %empty -| statement-list +: %empty { + $$ = NULL; +} +| statement-list { + $$ = $[statement-list]; +} ; statement-list -: statement statement-list.opt +: statement statement-list.opt { + $$ = cons($[statement], $[statement-list.opt]); +} ; statement -: compound-statement -| jump-statement +: compound-statement { + $$ = $[compound-statement]; +} +| jump-statement { + $$ = $[jump-statement]; +} /* : labeled-statement */ /* | compound-statement */ /* | expression-statement */ @@ -234,28 +244,50 @@ statement ; compound-statement -: '{' declaration-statement-list.opt statement-list.opt '}' +: '{' declaration-statement-list.opt statement-list.opt '}' { + $$ = cons(sexpr_make_ast(AST_COMPOUND_STATEMENT), + cons($[declaration-statement-list.opt], + $[statement-list.opt])); +} ; declaration-statement-list.opt -: %empty -| declaration-statement-list +: %empty { + $$ = NULL; +} +| declaration-statement-list { + $$ = $[declaration-statement-list]; +} ; declaration-statement-list -: declaration-statement declaration-statement-list.opt +: declaration-statement declaration-statement-list.opt { + $$ = cons($[declaration-statement], $[declaration-statement-list.opt]); +} ; declaration-statement -: storage-class-specifier.opt init-declaration -| typedef-specifier declaration +: storage-class-specifier.opt init-declaration { + $$ = cons($[storage-class-specifier.opt], $[init-declaration]); +} +| typedef-specifier declaration { + $$ = cons($[typedef-specifier], $[declaration]); +} ; jump-statement -: GOTO identifier ';' -| CONTINUE ';' -| BREAK ';' -| RETURN expression.opt ';' +: GOTO identifier ';' { + $$ = cons(sexpr_make_ast(AST_GOTO_STATEMENT), $[identifier]); +} +| CONTINUE ';' { + $$ = cons(sexpr_make_ast(AST_CONTINUE_STATEMENT), NULL); +} +| BREAK ';' { + $$ = cons(sexpr_make_ast(AST_BREAK_STATEMENT), NULL); +} +| RETURN expression.opt ';' { + $$ = cons(sexpr_make_ast(AST_RETURN_STATEMENT), $[expression.opt]); +} ; translation-unit.opt