diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/include/parser.h | 34 | ||||
-rw-r--r-- | src/lexer.c | 4 | ||||
-rw-r--r-- | src/parser.c | 116 | ||||
-rw-r--r-- | test/parser.c | 166 |
5 files changed, 248 insertions, 74 deletions
@@ -39,7 +39,7 @@ test: $(TEST_OUTS) $(CC) -c $< -o $@ $(CFLAGS) %.out: %.c - $(CC) $< $(filter-out %main.o,$(OBJS)) -o $@ $(DBG_CFLAGS) + $(CC) $< $(filter-out %main.o,$(OBJS)) -o $@ $(CFLAGS) install: all mkdir -p $(PREFIX) diff --git a/src/include/parser.h b/src/include/parser.h index 257189d..839e372 100644 --- a/src/include/parser.h +++ b/src/include/parser.h @@ -47,37 +47,41 @@ tree_t* parser_parse_init(parser_t* parser); /* Get tree for a block. */ tree_t* parser_parse_block(parser_t* parser); +/* Get tree for a keyword. */ tree_t* parser_parse_kwd(parser_t* parser); /* Get tree for an expression.*/ tree_t* parser_parse_expr(parser_t* parser); -/* - Check whether the current token matches the given type. - - If it doesn't, return 0 and throw error. -*/ -int parser_match(parser_t* parser, token_type_t type); - -/* Steps the parser forward by one token, then check whether the new token matches the given type. */ -int parser_nxt_token_match(parser_t* parser, token_type_t type); - /* Return the tree for an integer. */ tree_t* parser_parse_lint(parser_t* parser); /* Return the tree for a string. */ tree_t* parser_parse_lstr(parser_t* parser); -/* Return the tree for a definition's arguments. */ -tree_t* parser_parse_darg(parser_t* parser); +/* Return the tree for a call. */ +tree_t* parser_parse_call(parser_t* parser); + +/* Return the tree for a call's arguments. */ +tree_t* parser_parse_carg(parser_t* parser); /* Return the tree for a definition. */ tree_t* parser_parse_def(parser_t* parser); -/* Return the tree for a call's arguments. */ -tree_t* parser_parse_carg(parser_t* parser); +/* Return the tree for a definition tag. */ +tree_t* parser_parse_tag(parser_t* parser); -/* Return the tree for a call. */ -tree_t* parser_parse_call(parser_t* parser); +/* Return the tree for a definition's arguments. */ +tree_t* parser_parse_darg(parser_t* parser); + +/* + Check whether the current token matches the given type. + - If it doesn't, return 0 and throw error. +*/ +int parser_match(parser_t* parser, token_type_t type); + +/* Steps the parser forward by one token, then check whether the new token matches the given type. */ +int parser_nxt_token_match(parser_t* parser, token_type_t type); /* Parse. */ void parser_parse(parser_t* parser); diff --git a/src/lexer.c b/src/lexer.c index 5094b00..aa068a9 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -61,9 +61,9 @@ void lexer_do_reg(lexer_t* lexer) { case SYNTAX_TAG_DELIM: lexer->state = LEXER_STATE_TAG; break; -/* case SYNTAX_NAMESPACE_DELIM: + /*case SYNTAX_NAMESPACE_DELIM: lexer_add_current_char(lexer, TOKEN_NAMESPACE_DELIM); - break; */ + break;*/ case SYNTAX_SET: lexer_add_current_char(lexer, TOKEN_TYPE_SET); break; diff --git a/src/parser.c b/src/parser.c index 731df78..ea2245c 100644 --- a/src/parser.c +++ b/src/parser.c @@ -75,6 +75,9 @@ tree_t* parser_parse_expr(parser_t* parser) { case TOKEN_TYPE_KWD: expr = parser_parse_kwd(parser); break; + case TOKEN_TYPE_TAG: + expr = parser_parse_def(parser); + break; default: LOG_WARF("%s: Unknown token type: %d", __func__, parser->token->type); parser_nxt_token(parser); @@ -83,6 +86,63 @@ tree_t* parser_parse_expr(parser_t* parser) { return expr; } +tree_t* parser_parse_def(parser_t* parser) { + tree_t* def = tree_init(TREE_TYPE_DEF); + + def->data.def.tag = parser_parse_tag(parser); + + if (parser->token->type == TOKEN_TYPE_APPLY) { + parser_nxt_token(parser); + def->data.def.arg = parser_parse_darg(parser); + } else { + def->data.def.arg = NULL; + } + + if (parser->token->type == TOKEN_TYPE_SET) { + parser_nxt_token(parser); + def->data.def.val = parser_parse_expr(parser); + } else { + def->data.def.val = NULL; + } + + return def; +} + +tree_t* parser_parse_tag(parser_t* parser) { + if ( + parser->token && + parser->token->type != TOKEN_TYPE_TAG + ) { return NULL; } + + tree_t* tag = tree_init(TREE_TYPE_TAG); + + tag->data.tag.val = parser->token->val; + parser->token->val = NULL; + + parser_nxt_token(parser); + + tag->data.tag.nxt = parser_parse_tag(parser); + + return tag; +} + +tree_t* parser_parse_darg(parser_t* parser) { + tree_t* darg = tree_init(TREE_TYPE_DARG); + + darg->data.darg.tag = parser_parse_tag(parser); + + parser_nxt_token(parser); + + if (parser->token->type == TOKEN_TYPE_LIST_DELIM) { + parser_nxt_token(parser); + darg->data.darg.nxt = parser_parse_darg(parser); + } else { + darg->data.darg.nxt = NULL; + } + + return darg; +} + tree_t* parser_parse_carg(parser_t* parser) { tree_t* carg; @@ -151,62 +211,6 @@ tree_t* parser_parse_lstr(parser_t* parser) { return lstr; } -tree_t* parser_parse_tag(parser_t* parser) { - if (parser->token->type != TOKEN_TYPE_TAG) { return NULL; } - - tree_t* tag; - - tag = tree_init(TREE_TYPE_TAG); - - tag->data.tag.val = parser->token->val; - parser->token->val = NULL; - tag->data.tag.nxt = ( - parser_nxt_token(parser) ? - parser_parse_tag(parser) : - NULL - ); - - return tag; -} - -tree_t* parser_parse_darg(parser_t* parser) { - tree_t* darg; - - darg = tree_init(TREE_TYPE_DARG); - - if (parser->token->type != TOKEN_TYPE_TAG) { return NULL; } - - darg->data.darg.tag = parser_parse_tag(parser); - - LOG_WARF("%d", parser->token->type); - - if (parser->token->type != TOKEN_TYPE_LIST_DELIM) { - darg->data.darg.nxt = NULL; - } else { - parser_nxt_token(parser) && - (darg->data.darg.nxt = parser_parse_darg(parser)); - } - - return darg; -} - -tree_t* parser_parse_def(parser_t* parser) { - tree_t* def; - - def = tree_init(TREE_TYPE_DEF); - - def->data.def.tag = parser_parse_tag(parser); - - parser->token->type == TOKEN_TYPE_APPLY && - parser_nxt_token(parser) && - ( def->data.def.arg = parser_parse_darg(parser) ); - parser->token->type == TOKEN_TYPE_SET && - parser_nxt_token(parser) && - ( def->data.def.val = parser_parse_expr(parser) ); - - return def; -} - tree_t* parser_parse_call(parser_t* parser) { tree_t* call; diff --git a/test/parser.c b/test/parser.c index 503244f..abc1ea9 100644 --- a/test/parser.c +++ b/test/parser.c @@ -797,6 +797,171 @@ void cargumented_call_of_lint() { tree_destroy(tree); } +void def_bare_lint() { + tree_t* tree; + pp_t* pp; + lexer_t* lexer; + parser_t* parser; + + char src[] = ":i:n = 3"; + + /* + + [block] + val: + [def] + tag: + [tag] + val: + i + nxt: + [tag] + val: + n + nxt: + NULL + arg: + NULL + val: + [lint] + val: + 3 + nxt: + NULL + + */ + + tree = tree_init(TREE_TYPE_BLOCK); + tree_t* tree0def = tree->data.block.val = tree_init(TREE_TYPE_DEF); + tree_t* tree0tag = tree0def->data.def.tag = tree_init(TREE_TYPE_TAG); + char* val0 = tree0tag->data.tag.val = ecalloc(2, sizeof(char)); + strcpy(val0, "i"); + tree_t* tree1tag = tree0tag->data.tag.nxt = tree_init(TREE_TYPE_TAG); + char* val1 = tree1tag->data.tag.val = ecalloc(2, sizeof(char)); + strcpy(val1, "n"); + tree1tag->data.tag.nxt = NULL; + tree0def->data.def.arg = NULL; + tree_t* tree0lint = tree0def->data.def.val = tree_init(TREE_TYPE_LINT); + tree0lint->data.lint.val = 3; + tree->data.block.nxt = 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); + free(pp->psrc); + pp_destroy(pp); + tree_destroy(parser->tree); + parser_destroy(parser); + tree_destroy(tree); +} + +void def_add1() { + tree_t* tree; + pp_t* pp; + lexer_t* lexer; + parser_t* parser; + + char src[] = ":i:add1.:i:n = +.n, 1"; + + /* + + [block] + val: + [def] + tag: + [tag] + val: + i + nxt: + [tag] + val: + add1 + nxt: + NULL + arg: + [darg] + tag: + [tag] + val: + i + nxt: + [tag] + val: + n + nxt: + NULL + nxt: + NULL + val: + [call] + target: + + + arg: + [carg] + val: + [call] + target: + n + arg: + NULL + nxt: + [carg] + val: + [lint] + val: + 1 + nxt: + NULL + nxt: + NULL + + */ + + /* TODO: Write this test. */ + tree = tree_init(TREE_TYPE_BLOCK); + tree_t* tree0def = tree->data.block.val = tree_init(TREE_TYPE_DEF); + tree_t* tree0tag = tree0def->data.def.tag = tree_init(TREE_TYPE_TAG); + char* val0 = tree0tag->data.tag.val = ecalloc(2, sizeof(char)); + strcpy(val0, "i"); + tree_t* tree1tag = tree0tag->data.tag.nxt = tree_init(TREE_TYPE_TAG); + char* val1 = tree1tag->data.tag.val = ecalloc(2, sizeof(char)); + strcpy(val1, "n"); + tree1tag->data.tag.nxt = NULL; + tree0def->data.def.arg = NULL; + tree_t* tree0lint = tree0def->data.def.val = tree_init(TREE_TYPE_LINT); + tree0lint->data.lint.val = 3; + tree->data.block.nxt = 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); + free(pp->psrc); + pp_destroy(pp); + tree_destroy(parser->tree); + parser_destroy(parser); + tree_destroy(tree); +} + int main() { empty(); single_lint(); @@ -812,6 +977,7 @@ int main() { double_bare_call(); cargumented_call_of_call(); cargumented_call_of_lint(); + def_bare_lint(); TEST_REPORT; |