#include "parser.h" #include "lib/lexer.h" #include "lib/node.h" void parser_init(parser_t* parser, lexer_t* lexer, err_t* err) { assert(parser); parser->lexer = lexer; parser->err = err; } void parser_free(parser_t* parser) { assert(parser); } node_t* parser_try_new_tree(parser_t* parser) { assert(parser); return parser_try_new_mod(parser); } node_t* parser_try_new_mod(parser_t* parser) { assert(parser); node_t* mod = malloc(sizeof(node_t)); node_init(mod, NODE_MOD, "", parser->lexer->line); size_t len = strlen(parser->lexer->source); while (parser->lexer->cursor < len) { node_t* expr = parser_try_new_expr(parser); if (expr) { node_add_child(mod, expr); } else { node_free(mod); free(mod); return NULL; } } return mod; } node_t* parser_try_new_expr(parser_t* parser) { assert(parser); return parser_try_new_builtin(parser); } node_t* parser_try_new_builtin(parser_t* parser) { assert(parser); NodeType next = lexer_peek(parser->lexer, 1); if (next == NODE_NUM || next == NODE_BOOL || next == NODE_STR) { return parser_try_new_consume(parser, next); } return NULL; } node_t* parser_try_new_consume(parser_t* parser, NodeType type) { assert(parser); node_t* next = lexer_try_new_next(parser->lexer); if (!next) { return NULL; } if (next->type != type) { size_t const SZ = RZ_STR_LIMIT; char err_msg[SZ]; snprintf(err_msg, SZ, "unexpected node '%s'", NodeTypeStr[next->type]); err_error(parser->err, err_msg, next->line); node_free(next); free(next); return NULL; } return next; }