119 lines
2.8 KiB
C
119 lines
2.8 KiB
C
#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;
|
|
}
|
|
|