moka/lib/parser.c

119 lines
2.8 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);
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* atom = MK_TRY(parser_try_new_atom);
if (!atom && !lexer_end(self->lexer))
{
node_free(root);
free(root);
return NULL;
}
node_add_new_child(root, atom);
}
return root;
}
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;
}
return NULL;
}