2023-12-09 17:24:41 +00:00
|
|
|
#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);
|
2023-12-09 21:59:24 +00:00
|
|
|
return parser_try_new_builtin(parser);
|
2023-12-09 17:24:41 +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);
|
|
|
|
|
2023-12-10 03:49:28 +00:00
|
|
|
if (next == NODE_NUM || next == NODE_BOOL || next == NODE_STR)
|
2023-12-09 21:59:24 +00:00
|
|
|
{
|
|
|
|
return parser_try_new_consume(parser, next);
|
|
|
|
}
|
|
|
|
|
|
|
|
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]);
|
|
|
|
err_error(parser->err, err_msg, next->line);
|
|
|
|
node_free(next);
|
|
|
|
free(next);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return next;
|
|
|
|
}
|