roza/lib/parser.c

409 lines
8.1 KiB
C
Raw Normal View History

2023-12-09 17:24:41 +00:00
#include "parser.h"
#include "lib/commons.h"
2023-12-09 17:24:41 +00:00
#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)
{
2023-12-11 17:01:22 +00:00
node_add_new_child(mod, expr);
2023-12-09 17:24:41 +00:00
}
else
{
node_free(mod);
free(mod);
return NULL;
}
}
return mod;
}
node_t* parser_try_new_expr(parser_t* parser)
{
assert(parser);
2023-12-11 17:01:22 +00:00
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);
}
2023-12-16 18:12:20 +00:00
return parser_try_new_or(parser);
2023-12-09 17:24:41 +00:00
}
2023-12-11 17:01:22 +00:00
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;
}
2023-12-16 18:12:20 +00:00
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);
2023-12-15 20:32:17 +00:00
node_t* lhs = parser_try_new_cmp(parser);
2023-12-16 18:12:20 +00:00
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);
2023-12-15 20:32:17 +00:00
node_add_new_child(node, parser_try_new_cmp(parser));
lhs = node;
}
else
{
break;
}
}
return lhs;
}
2023-12-15 20:32:17 +00:00
node_t* parser_try_new_cmp(parser_t* parser)
{
assert(parser);
2023-12-15 21:31:01 +00:00
node_t* lhs = parser_try_new_term(parser);
2023-12-16 18:12:20 +00:00
assert(lhs);
2023-12-15 20:32:17 +00:00
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);
2023-12-15 21:31:01 +00:00
node_add_new_child(node, parser_try_new_term(parser));
2023-12-15 20:32:17 +00:00
lhs = node;
}
return lhs;
}
2023-12-15 21:31:01 +00:00
node_t* parser_try_new_term(parser_t* parser)
{
assert(parser);
node_t* lhs = parser_try_new_factor(parser);
2023-12-16 18:12:20 +00:00
assert(lhs);
2023-12-15 21:31:01 +00:00
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);
2023-12-16 18:12:20 +00:00
assert(lhs);
2023-12-15 21:31:01 +00:00
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);
2023-12-16 18:12:20 +00:00
assert(lhs);
2023-12-15 21:31:01 +00:00
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);
2023-12-16 18:12:20 +00:00
assert(node);
2023-12-15 21:31:01 +00:00
node_add_new_child(node, parser_try_new_group(parser));
2023-12-16 18:12:20 +00:00
assert(node);
2023-12-15 21:31:01 +00:00
return node;
}
2023-12-16 18:12:20 +00:00
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;
2023-12-15 21:31:01 +00:00
}
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);
2023-12-16 18:12:20 +00:00
assert(node);
assert(lexer_peek(parser->lexer, 1) == NODE_CPAR);
2023-12-15 21:31:01 +00:00
lexer_skip_next(parser->lexer);
return node;
}
2023-12-16 18:12:20 +00:00
node_t* builtin = parser_try_new_builtin(parser);
assert(builtin);
return builtin;
2023-12-15 21:31:01 +00:00
}
2023-12-09 21:59:24 +00:00
node_t* parser_try_new_builtin(parser_t* parser)
2023-12-09 17:24:41 +00:00
{
assert(parser);
2023-12-09 21:59:24 +00:00
NodeType next = lexer_peek(parser->lexer, 1);
if (next == NODE_NUM
|| next == NODE_BOOL
|| next == NODE_STR
|| next == NODE_IDENT)
2023-12-09 21:59:24 +00:00
{
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);
}
2023-12-09 21:59:24 +00:00
return NULL;
2023-12-09 17:24:41 +00:00
}
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]);
2023-12-11 17:01:22 +00:00
err_fatal(parser->err, err_msg, next->line);
2023-12-09 17:24:41 +00:00
node_free(next);
free(next);
err_dump(parser->err);
2023-12-09 17:24:41 +00:00
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;
}
}