diff --git a/src/ast.h b/src/ast.h index 424a2620..319be166 100644 --- a/src/ast.h +++ b/src/ast.h @@ -2,7 +2,9 @@ #define KMC_C90_COMPILER_AST_H enum AstTag { - AST_IDENTIFIER + AST_IDENTIFIER, + AST_FUNCTION_DEFINITION, + AST_EXTERNAL_DECLARATION }; #endif /* KMC_C90_COMPILER_AST_H */ diff --git a/src/parser.y b/src/parser.y index a655abc5..a7736ede 100644 --- a/src/parser.y +++ b/src/parser.y @@ -259,26 +259,47 @@ jump-statement ; translation-unit.opt -: %empty -| translation-unit +: %empty { + $$ = NULL; +} +| translation-unit { + $$ = $[translation-unit]; +} ; translation-unit -: external-declaration translation-unit.opt +: external-declaration translation-unit.opt { + $$ = cons($[external-declaration], $[translation-unit.opt]); +} ; external-declaration -: linkage-specifier.opt function-definition -| linkage-specifier.opt init-declaration -| typedef-specifier declaration +: linkage-specifier.opt function-definition { + $$ = cons(sexpr_make_ast(AST_FUNCTION_DEFINITION), + cons($[linkage-specifier.opt], $[function-definition])); +} +| linkage-specifier.opt init-declaration { + $$ = cons(sexpr_make_ast(AST_EXTERNAL_DECLARATION), + cons($[linkage-specifier.opt], $[init-declaration])); +} +| typedef-specifier declaration { + $$ = cons(sexpr_make_ast(AST_EXTERNAL_DECLARATION), + cons($[typedef-specifier], $[declaration])); +} ; function-definition-declarator -: identifier '(' parameter-declaration-list ')' +: identifier '(' parameter-declaration-list ')' { + $$ = cons($[identifier], $[parameter-declaration-list]); +} ; function-definition -: declaration-specifiers function-definition-declarator compound-statement +: declaration-specifiers function-definition-declarator compound-statement { + $$ = cons($[declaration-specifiers], + cons($[function-definition-declarator], + $[compound-statement])); +} ; %%