#include "parser.h" #include "lib/commons.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_new_child(mod, expr); } else { node_free(mod); free(mod); return NULL; } } return mod; } node_t* parser_try_new_expr(parser_t* parser) { assert(parser); NodeType type = lexer_peek(parser->lexer, 1); if (type == -1) { return NULL; } if (type == NODE_ASSERT) { return parser_try_new_assert(parser); } if (type == NODE_LET) { return parser_try_new_vardecl(parser); } return parser_try_new_or(parser); } node_t* parser_try_new_assert(parser_t* parser) { assert(parser); node_t* node = parser_try_new_consume(parser, NODE_ASSERT); assert(node); node_t* expr = parser_try_new_expr(parser); assert(expr); node_add_new_child(node, expr); return node; } node_t* parser_try_new_vardecl(parser_t* parser) { assert(parser); parser_skip(parser, NODE_LET); node_t* ident = parser_try_new_consume(parser, NODE_IDENT); parser_skip(parser, NODE_ASSIGN); node_t* expr = parser_try_new_expr(parser); node_t* node = malloc(sizeof(node_t)); node_init(node, NODE_VARDECL, "", parser->lexer->line); node_add_new_child(node, ident); node_add_new_child(node, expr); return node; } node_t* parser_try_new_or(parser_t* parser) { assert(parser); node_t* lhs = parser_try_new_and(parser); while (1) { int next = lexer_peek(parser->lexer, 1); if (next != NODE_OR) { break; } node_t* node = parser_try_new_consume(parser, next); node_add_new_child(node, lhs); node_add_new_child(node, parser_try_new_and(parser)); lhs = node; } return lhs; } node_t* parser_try_new_and(parser_t* parser) { assert(parser); node_t* lhs = parser_try_new_eqne(parser); while (1) { int next = lexer_peek(parser->lexer, 1); if (next != NODE_AND) { break; } node_t* node = parser_try_new_consume(parser, next); assert(node); node_add_new_child(node, lhs); node_t* eqne = parser_try_new_eqne(parser); assert(eqne); node_add_new_child(node, eqne); lhs = node; } return lhs; } node_t* parser_try_new_eqne(parser_t* parser) { assert(parser); node_t* lhs = parser_try_new_cmp(parser); assert(lhs); while (1) { NodeType next_type = lexer_peek(parser->lexer, 1); if (next_type == NODE_EQ || next_type == NODE_NE) { node_t* node = lexer_try_new_next(parser->lexer); node_add_new_child(node, lhs); node_add_new_child(node, parser_try_new_cmp(parser)); lhs = node; } else { break; } } return lhs; } node_t* parser_try_new_cmp(parser_t* parser) { assert(parser); node_t* lhs = parser_try_new_term(parser); assert(lhs); int next = lexer_peek(parser->lexer, 1); if (next == NODE_LT || next == NODE_GT || next == NODE_LE || next == NODE_GE) { node_t* node = parser_try_new_consume(parser, next); node_add_new_child(node, lhs); node_add_new_child(node, parser_try_new_term(parser)); lhs = node; } return lhs; } node_t* parser_try_new_term(parser_t* parser) { assert(parser); node_t* lhs = parser_try_new_factor(parser); assert(lhs); while (1) { NodeType next = lexer_peek(parser->lexer, 1); if (next == NODE_ADD || next == NODE_SUB) { node_t* node = parser_try_new_consume(parser, next); node_add_new_child(node, lhs); node_add_new_child(node, parser_try_new_factor(parser)); lhs = node; } else { break; } } return lhs; } node_t* parser_try_new_factor(parser_t* parser) { assert(parser); node_t* lhs = parser_try_new_power(parser); assert(lhs); while (1) { NodeType next = lexer_peek(parser->lexer, 1); if (next == NODE_MUL || next == NODE_DIV || next == NODE_MODULO) { node_t* node = parser_try_new_consume(parser, next); node_add_new_child(node, lhs); node_add_new_child(node, parser_try_new_power(parser)); lhs = node; } else { break; } } return lhs; } node_t* parser_try_new_power(parser_t* parser) { assert(parser); node_t* lhs = parser_try_new_unary(parser); assert(lhs); NodeType next = lexer_peek(parser->lexer, 1); if (next == NODE_POW) { node_t* node = parser_try_new_consume(parser, next); node_add_new_child(node, lhs); node_add_new_child(node, parser_try_new_unary(parser)); lhs = node; } return lhs; } node_t* parser_try_new_unary(parser_t* parser) { assert(parser); NodeType next = lexer_peek(parser->lexer, 1); if (next == NODE_SUB) { node_t* node = parser_try_new_consume(parser, next); assert(node); node_add_new_child(node, parser_try_new_group(parser)); assert(node); return node; } if (next == NODE_NOT) { node_t* node = parser_try_new_consume(parser, next); assert(node); node_add_new_child(node, parser_try_new_unary(parser)); return node; } node_t* group = parser_try_new_group(parser); assert(group); return group; } node_t* parser_try_new_group(parser_t* parser) { assert(parser); NodeType next = lexer_peek(parser->lexer, 1); if (next == NODE_OPAR) { lexer_skip_next(parser->lexer); node_t* node = parser_try_new_expr(parser); assert(node); assert(lexer_peek(parser->lexer, 1) == NODE_CPAR); lexer_skip_next(parser->lexer); return node; } node_t* builtin = parser_try_new_builtin(parser); assert(builtin); return builtin; } 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 || next == NODE_IDENT) { return parser_try_new_consume(parser, next); } if (next) { node_t* node = lexer_try_new_next(parser->lexer); char nstr[RZ_STR_LIMIT]; node_str(node, nstr, RZ_STR_LIMIT); node_free(node); free(node); size_t limit = RZ_STR_LIMIT + strlen(nstr); char msg[limit]; snprintf(msg, limit, "unexpected node '%s'.", nstr); err_fatal(parser->err, msg, parser->lexer->line); err_dump(parser->err); } 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_fatal(parser->err, err_msg, next->line); node_free(next); free(next); err_dump(parser->err); return NULL; } return next; } int parser_skip(parser_t* parser, NodeType type) { assert(parser); node_t* next = lexer_try_new_next(parser->lexer); assert(next); 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_fatal(parser->err, err_msg, next->line); node_free(next); free(next); err_dump(parser->err); return 0; } else { node_free(next); free(next); return 1; } }