moka/lib/parser.c

193 lines
4.4 KiB
C
Raw Normal View History

2024-03-26 18:31:33 +00:00
#include "parser.h"
#define MK_TRY(func) parser_try(self, func)
void parser_init(struct parser* self, struct lexer* lexer)
{
assert(self);
assert(lexer);
self->lexer = lexer;
}
void parser_free(struct parser* self)
{
assert(self);
}
struct node* parser_try_new_parse(struct parser* self)
{
assert(self);
return MK_TRY(parser_try_new_root);
}
struct node* parser_try(struct parser* self,
struct node* (*rule)(struct parser*))
{
assert(self);
assert(rule);
struct lex_context ctx = lexer_state(self->lexer);
struct node* node = rule(self);
2024-03-29 09:04:13 +00:00
2024-03-26 18:31:33 +00:00
if (node == NULL)
{
lexer_restore(self->lexer, ctx);
}
return node;
}
struct node* parser_try_new_root(struct parser* self)
{
assert(self);
struct node* root = malloc(sizeof(struct node));
node_init(root, NODE_ROOT, NULL, self->lexer->context.line);
while (!lexer_end(self->lexer))
{
struct node* expr = MK_TRY(parser_try_new_expr);
2024-03-29 09:04:13 +00:00
if (!expr && !lexer_end(self->lexer))
2024-03-26 18:31:33 +00:00
{
2024-03-29 09:04:13 +00:00
printf("not at end: %c\n", self->lexer->source[self->lexer->context.cursor]);
2024-03-26 18:31:33 +00:00
node_free(root);
free(root);
return NULL;
}
node_add_new_child(root, expr);
2024-03-26 18:31:33 +00:00
}
return root;
}
struct node* parser_try_new_expr(struct parser* self)
{
assert(self);
if (lexer_next_is(self->lexer, TOKEN_OPAR, 0))
{
return MK_TRY(parser_try_new_call);
}
return MK_TRY(parser_try_new_atom);
}
struct node* parser_try_new_call(struct parser* self)
{
assert(self);
if (!lexer_next_is(self->lexer, TOKEN_OPAR, 0))
{
return NULL;
}
lexer_skip(self->lexer, TOKEN_OPAR);
struct node* target = MK_TRY(parser_try_new_expr);
if (!target)
{
return NULL;
}
struct node* call = malloc(sizeof(struct node));
node_init(call, NODE_CALL, NULL, target->line);
node_add_new_child(call, target);
while (!lexer_next_is(self->lexer, TOKEN_CPAR, 0))
{
struct node* arg = MK_TRY(parser_try_new_expr);
if (!arg)
{
node_free(target); free(target);
node_free(call); free(call);
node_free(arg); free(arg);
return NULL;
}
node_add_new_child(call, arg);
}
if (!lexer_next_is(self->lexer, TOKEN_CPAR, 0))
{
node_free(target); free(target);
node_free(call); free(call);
return NULL;
}
lexer_skip(self->lexer, TOKEN_CPAR);
return call;
}
2024-03-26 18:31:33 +00:00
struct node* parser_try_new_atom(struct parser* self)
{
assert(self);
if (lexer_next_is(self->lexer, TOKEN_FLOAT, 0))
{
struct node* node = malloc(sizeof(struct node));
struct token* tok = lexer_try_new_next(self->lexer);
assert(tok);
node_init(node, NODE_FLOAT, tok,
self->lexer->context.line);
return node;
}
if (lexer_next_is(self->lexer, TOKEN_INT, 0))
{
struct node* node = malloc(sizeof(struct node));
struct token* tok = lexer_try_new_next(self->lexer);
assert(tok);
node_init(node, NODE_INT, tok,
self->lexer->context.line);
return node;
}
if (lexer_next_is(self->lexer, TOKEN_BOOL, 0))
{
struct node* node = malloc(sizeof(struct node));
struct token* tok = lexer_try_new_next(self->lexer);
assert(tok);
node_init(node, NODE_BOOL, tok,
self->lexer->context.line);
return node;
}
if (lexer_next_is(self->lexer, TOKEN_STRING, 0))
{
struct node* node = malloc(sizeof(struct node));
struct token* tok = lexer_try_new_next(self->lexer);
assert(tok);
node_init(node, NODE_STRING, tok,
self->lexer->context.line);
return node;
}
if (lexer_next_is(self->lexer, TOKEN_SYMBOL, 0))
{
struct node* node = malloc(sizeof(struct node));
struct token* tok = lexer_try_new_next(self->lexer);
assert(tok);
node_init(node, NODE_SYMBOL, tok,
self->lexer->context.line);
return node;
}
if (lexer_next_is(self->lexer, TOKEN_IDENT, 0))
{
struct node* node = malloc(sizeof(struct node));
struct token* tok = lexer_try_new_next(self->lexer);
assert(tok);
node_init(node, NODE_IDENT, tok,
self->lexer->context.line);
return node;
}
2024-03-29 09:04:13 +00:00
2024-03-26 18:31:33 +00:00
return NULL;
}