lang: ast: re-write expression parser to support keyword messages
also adjust some parser state callbackss to better support sub-parsers returning results to their parents.
This commit is contained in:
@@ -5,9 +5,21 @@
|
||||
#include <blue/core/queue.h>
|
||||
#include <ivy/lang/ast.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static void print_state_stack(struct ivy_parser *parser)
|
||||
{
|
||||
b_queue_iterator it = {0};
|
||||
b_queue_foreach (&it, &parser->p_state) {
|
||||
struct parser_state *state
|
||||
= b_unbox(struct parser_state, it.entry, s_entry);
|
||||
printf(" %s\n",
|
||||
ivy_ast_node_type_to_string(state->s_node->n_type));
|
||||
}
|
||||
}
|
||||
|
||||
enum ivy_status ivy_parser_create(struct ivy_parser **parser)
|
||||
{
|
||||
struct ivy_parser *out = malloc(sizeof *out);
|
||||
@@ -48,6 +60,9 @@ enum ivy_status ivy_parser_push_token(
|
||||
struct token_parse_result result = func(parser, tok);
|
||||
parser->p_status = result.r_status;
|
||||
|
||||
printf("states (after token)\n");
|
||||
print_state_stack(parser);
|
||||
|
||||
if (result.r_flags & PARSE_REPEAT_TOKEN) {
|
||||
continue;
|
||||
}
|
||||
@@ -108,6 +123,8 @@ struct parser_state *parser_push_state(
|
||||
node_type->n_init_state(parser, state);
|
||||
}
|
||||
|
||||
printf("states (after push)\n");
|
||||
print_state_stack(parser);
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -122,13 +139,17 @@ void parser_pop_state(struct ivy_parser *parser, enum pop_state_flags flags)
|
||||
b_queue_pop_back(&parser->p_state);
|
||||
|
||||
if (state && (flags & STATE_ADD_NODE_TO_PARENT)) {
|
||||
ast_node_add_child(state->s_parent, state->s_node);
|
||||
parser_add_child(parser, state->s_node);
|
||||
}
|
||||
|
||||
free(state);
|
||||
|
||||
printf("states (after pop)\n");
|
||||
print_state_stack(parser);
|
||||
}
|
||||
|
||||
void parser_replace_current_node(struct ivy_parser *parser, struct ivy_ast_node *new_node)
|
||||
void parser_replace_current_node(
|
||||
struct ivy_parser *parser, struct ivy_ast_node *new_node)
|
||||
{
|
||||
struct parser_state *state = parser_get_state_generic(parser);
|
||||
if (!state) {
|
||||
@@ -139,6 +160,23 @@ void parser_replace_current_node(struct ivy_parser *parser, struct ivy_ast_node
|
||||
state->s_node = new_node;
|
||||
}
|
||||
|
||||
enum ivy_status parser_add_child(
|
||||
struct ivy_parser *parser, struct ivy_ast_node *new_node)
|
||||
{
|
||||
struct parser_state *state = parser_get_state_generic(parser);
|
||||
if (!state) {
|
||||
return IVY_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
const struct ast_node_type *node_type
|
||||
= get_ast_node_type(state->s_node->n_type);
|
||||
if (!node_type || !node_type->n_add_child) {
|
||||
return IVY_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return node_type->n_add_child(state, new_node);
|
||||
}
|
||||
|
||||
bool ivy_parser_is_node_complete(struct ivy_parser *parser)
|
||||
{
|
||||
return (parser->p_state.q_first == parser->p_state.q_last);
|
||||
|
||||
Reference in New Issue
Block a user