diff options
-rw-r--r-- | src/include/tree.h | 4 | ||||
-rw-r--r-- | src/parser.c | 57 | ||||
-rw-r--r-- | src/tree.c | 2 | ||||
-rw-r--r-- | test/include/test.h | 4 | ||||
-rw-r--r-- | test/parser.c | 66 |
5 files changed, 81 insertions, 52 deletions
diff --git a/src/include/tree.h b/src/include/tree.h index 8b8e14a..31b8f3f 100644 --- a/src/include/tree.h +++ b/src/include/tree.h @@ -82,8 +82,8 @@ typedef struct TREE { } tree_t; /* Create a new AST. */ -tree_t* tree_init(int type); -/* Destroy the AST. */ +tree_t* tree_init(tree_type_t type); +/* Destroy the AST (if it exists). */ void tree_destroy(tree_t* tree); /* diff --git a/src/parser.c b/src/parser.c index bb945db..344ca89 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,4 +1,5 @@ #include "include/parser.h" +#include "include/token.h" parser_t* parser_init(token_t* token) { parser_t* parser; @@ -11,18 +12,16 @@ parser_t* parser_init(token_t* token) { } void parser_destroy(parser_t* parser) { - free(parser); + if (parser) { free(parser); } } int parser_nxt_token(parser_t* parser) { - if (parser->token->nxt) { - token_t* nxt = parser->token->nxt; - free(parser->token); - parser->token = nxt; - return 1; - } else { - return 0; + /* Preserve original token list, to be cleaned up by lexer. */ + parser->token = parser->token->nxt; + if (parser->token && parser->token->type == TOKEN_TYPE_EXPR_END) { + return parser_nxt_token(parser); } + return parser->token ? 1 : 0; } int parser_match(parser_t* parser, token_type_t type) { @@ -39,6 +38,7 @@ tree_t* parser_parse_lint(parser_t* parser) { lint = tree_init(TREE_TYPE_LINT); lint->data.lint.val = atoi(parser->token->val); + parser_nxt_token(parser); return lint; } @@ -57,52 +57,33 @@ tree_t* parser_parse_lstr(parser_t* parser) { } tree_t* parser_parse_expr(parser_t* parser) { - tree_t* expr; - - expr = tree_init(TREE_TYPE_EXPR); + tree_t* expr = NULL; switch (parser->token->type) { case TOKEN_TYPE_INT: - expr->data.expr.val = parser_parse_lint(parser); - break; - case TOKEN_TYPE_STR: - expr->data.expr.val = parser_parse_lstr(parser); + expr = parser_parse_lint(parser); break; - case TOKEN_TYPE_KWD: - expr->data.expr.val = parser_parse_call(parser); - break; - case TOKEN_TYPE_TAG: - expr->data.expr.val = parser_parse_def(parser); - break; - case TOKEN_TYPE_LBLOCK: + case TOKEN_TYPE_EXPR_END: parser_nxt_token(parser); - expr->data.expr.val = parser_parse_block(parser); break; default: - expr->data.lstr.val = "???"; /* TODO: Add an "unknown" token type. */ - return expr; + log_war("%s: Unknown token type: %d", __func__, parser->token->type); + parser_nxt_token(parser); } return expr; } tree_t* parser_parse_block(parser_t* parser) { + /* There is nothing to do. */ + if (!parser->token || parser->token->type == TOKEN_TYPE_RBLOCK) { + return NULL; + } tree_t* block; - block = tree_init(TREE_TYPE_BLOCK); - if (!parser->token) { - block->data.block.val = NULL; - block->data.block.nxt = NULL; - } else { - switch (parser->token->type) { - case TOKEN_TYPE_INT: - block->data.block.val = parser_parse_lint(parser); - break; - } - } - - block->data.block.nxt = NULL; + block->data.block.val = parser_parse_expr(parser); + block->data.block.nxt = parser_parse_block(parser); return block; } @@ -1,6 +1,6 @@ #include "include/tree.h" -tree_t* tree_init(int type) { +tree_t* tree_init(tree_type_t type) { tree_t* tree; tree = emalloc(sizeof(tree_t)); diff --git a/test/include/test.h b/test/include/test.h index c5fd97e..02c3d18 100644 --- a/test/include/test.h +++ b/test/include/test.h @@ -11,8 +11,8 @@ extern unsigned int TESTS_PASSED; #define ASSERT(EXPR) \ TESTS_RUN++; \ (EXPR && ++TESTS_PASSED) ? \ - log_inf("%s:%d: Assertion passed!", __FILE__, __LINE__) : \ - log_err("%s:%d: Assertion failed:\n\t%s", __FILE__, __LINE__, #EXPR); + log_inf("%s:%s:%d: Assertion passed!", __func__, __FILE__, __LINE__) : \ + log_err("%s:%s:%d: Assertion failed:\n\t%s", __func__, __FILE__, __LINE__, #EXPR); #define TEST_REPORT \ (TESTS_RUN == TESTS_PASSED) ? \ diff --git a/test/parser.c b/test/parser.c index db296e6..2007e93 100644 --- a/test/parser.c +++ b/test/parser.c @@ -16,16 +16,52 @@ void test_simple_empty() { /* + NULL + + */ + + tree = NULL; + pp = pp_init(src); + pp_run(pp); + + lexer = lexer_init(pp->psrc); + lexer_run(lexer); + + parser = parser_init(lexer->tokenl); + parser_run(parser); + + ASSERT(tree_cmp(parser->tree, tree) == 1); + + token_destroy(lexer->tokenl); + lexer_destroy(lexer); + pp_destroy(pp); + tree_destroy(parser->tree); + parser_destroy(parser); +} + +void test_single_lint() { + tree_t* tree; + pp_t* pp; + lexer_t* lexer; + parser_t* parser; + + char src[] = "1"; + + /* + [block] val: - NULL + [lint] + val: + 1 nxt: NULL */ tree = tree_init(TREE_TYPE_BLOCK); - tree->data.block.val = NULL; + tree->data.block.val = tree_init(TREE_TYPE_LINT); + tree->data.block.val->data.lint.val = 1; tree->data.block.nxt = NULL; pp = pp_init(src); @@ -39,18 +75,20 @@ void test_simple_empty() { ASSERT(tree_cmp(parser->tree, tree) == 1); + token_destroy(lexer->tokenl); + lexer_destroy(lexer); pp_destroy(pp); + tree_destroy(parser->tree); parser_destroy(parser); - lexer_destroy(lexer); } -void test_single_lint() { +void test_double_lint() { tree_t* tree; pp_t* pp; lexer_t* lexer; parser_t* parser; - char src[] = "1"; + char src[] = "1;1"; /* @@ -60,14 +98,23 @@ void test_single_lint() { val: 1 nxt: - NULL + [block] + val: + [lint] + val: + 1 + nxt: + NULL */ tree = tree_init(TREE_TYPE_BLOCK); - tree->data.block.val = tree_init(TREE_TYPE_LINT); - tree->data.block.val->data.lint.val = 1; - tree->data.block.nxt = NULL; + tree_t* tree0lint = tree->data.block.val = tree_init(TREE_TYPE_LINT); + tree0lint->data.lint.val = 1; + tree_t* tree1block = tree->data.block.nxt = tree_init(TREE_TYPE_BLOCK); + tree_t* tree2lint = tree1block->data.block.val = tree_init(TREE_TYPE_LINT); + tree2lint->data.lint.val = 1; + tree1block->data.block.nxt = NULL; pp = pp_init(src); pp_run(pp); @@ -90,6 +137,7 @@ void test_single_lint() { int main(int argc, char** argv) { test_simple_empty(); test_single_lint(); + test_double_lint(); TEST_REPORT; |