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:
@@ -1,11 +1,11 @@
|
|||||||
#include "ctx.h"
|
|
||||||
#include "node.h"
|
|
||||||
#include "block.h"
|
#include "block.h"
|
||||||
|
|
||||||
|
#include "ctx.h"
|
||||||
#include "iterate.h"
|
#include "iterate.h"
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
#include <blue/object/string.h>
|
#include <blue/object/string.h>
|
||||||
#include <ivy/lang/lex.h>
|
#include <ivy/lang/lex.h>
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
static struct token_parse_result parse_end(
|
static struct token_parse_result parse_end(
|
||||||
struct ivy_parser *ctx, struct ivy_token *tok)
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
||||||
@@ -21,7 +21,7 @@ static struct token_parse_result parse_end(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct token_parse_result parse_bang(
|
static struct token_parse_result parse_bang(
|
||||||
struct ivy_parser* ctx, struct ivy_token* tok)
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
||||||
{
|
{
|
||||||
struct block_parser_state *state
|
struct block_parser_state *state
|
||||||
= parser_get_state(ctx, struct block_parser_state);
|
= parser_get_state(ctx, struct block_parser_state);
|
||||||
@@ -51,9 +51,10 @@ static struct token_parse_result parse_expr_begin(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static enum ivy_status add_child(
|
static enum ivy_status add_child(
|
||||||
struct ivy_ast_node *parent, struct ivy_ast_node *child)
|
struct parser_state *parent, struct ivy_ast_node *child)
|
||||||
{
|
{
|
||||||
struct ivy_ast_block_node *block = (struct ivy_ast_block_node *)parent;
|
struct ivy_ast_block_node *block
|
||||||
|
= (struct ivy_ast_block_node *)parent->s_node;
|
||||||
|
|
||||||
b_queue_push_back(&block->n_expr, &child->n_entry);
|
b_queue_push_back(&block->n_expr, &child->n_entry);
|
||||||
|
|
||||||
@@ -70,7 +71,7 @@ static void collect_children(
|
|||||||
{
|
{
|
||||||
struct ivy_ast_block_node *block = (struct ivy_ast_block_node *)node;
|
struct ivy_ast_block_node *block = (struct ivy_ast_block_node *)node;
|
||||||
b_queue_iterator it = {0};
|
b_queue_iterator it = {0};
|
||||||
b_queue_foreach(&it, &block->n_expr) {
|
b_queue_foreach (&it, &block->n_expr) {
|
||||||
struct ivy_ast_node *expr
|
struct ivy_ast_node *expr
|
||||||
= b_unbox(struct ivy_ast_node, it.entry, n_entry);
|
= b_unbox(struct ivy_ast_node, it.entry, n_entry);
|
||||||
ast_node_iterator_enqueue_node(iterator, node, expr);
|
ast_node_iterator_enqueue_node(iterator, node, expr);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "ctx.h"
|
#include "ctx.h"
|
||||||
#include "node.h"
|
|
||||||
#include "iterate.h"
|
#include "iterate.h"
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
#include <blue/object/string.h>
|
#include <blue/object/string.h>
|
||||||
#include <ivy/lang/lex.h>
|
#include <ivy/lang/lex.h>
|
||||||
@@ -15,7 +15,8 @@ struct class_parser_state {
|
|||||||
int s_prev_token;
|
int s_prev_token;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct token_parse_result parse_dollar(struct ivy_parser *ctx, struct ivy_token *tok)
|
static struct token_parse_result parse_dollar(
|
||||||
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
||||||
{
|
{
|
||||||
struct class_parser_state *state
|
struct class_parser_state *state
|
||||||
= parser_get_state(ctx, struct class_parser_state);
|
= parser_get_state(ctx, struct class_parser_state);
|
||||||
@@ -123,9 +124,9 @@ static struct token_parse_result parse_linefeed(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static enum ivy_status add_child(
|
static enum ivy_status add_child(
|
||||||
struct ivy_ast_node *parent, struct ivy_ast_node *child)
|
struct parser_state *state, struct ivy_ast_node *child)
|
||||||
{
|
{
|
||||||
struct ivy_ast_class_node *c = (struct ivy_ast_class_node *)parent;
|
struct ivy_ast_class_node *c = (struct ivy_ast_class_node *)state->s_node;
|
||||||
|
|
||||||
switch (child->n_type) {
|
switch (child->n_type) {
|
||||||
case IVY_AST_MSGH:
|
case IVY_AST_MSGH:
|
||||||
|
|||||||
@@ -5,9 +5,21 @@
|
|||||||
#include <blue/core/queue.h>
|
#include <blue/core/queue.h>
|
||||||
#include <ivy/lang/ast.h>
|
#include <ivy/lang/ast.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.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)
|
enum ivy_status ivy_parser_create(struct ivy_parser **parser)
|
||||||
{
|
{
|
||||||
struct ivy_parser *out = malloc(sizeof *out);
|
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);
|
struct token_parse_result result = func(parser, tok);
|
||||||
parser->p_status = result.r_status;
|
parser->p_status = result.r_status;
|
||||||
|
|
||||||
|
printf("states (after token)\n");
|
||||||
|
print_state_stack(parser);
|
||||||
|
|
||||||
if (result.r_flags & PARSE_REPEAT_TOKEN) {
|
if (result.r_flags & PARSE_REPEAT_TOKEN) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -108,6 +123,8 @@ struct parser_state *parser_push_state(
|
|||||||
node_type->n_init_state(parser, state);
|
node_type->n_init_state(parser, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("states (after push)\n");
|
||||||
|
print_state_stack(parser);
|
||||||
return state;
|
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);
|
b_queue_pop_back(&parser->p_state);
|
||||||
|
|
||||||
if (state && (flags & STATE_ADD_NODE_TO_PARENT)) {
|
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);
|
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);
|
struct parser_state *state = parser_get_state_generic(parser);
|
||||||
if (!state) {
|
if (!state) {
|
||||||
@@ -139,6 +160,23 @@ void parser_replace_current_node(struct ivy_parser *parser, struct ivy_ast_node
|
|||||||
state->s_node = new_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)
|
bool ivy_parser_is_node_complete(struct ivy_parser *parser)
|
||||||
{
|
{
|
||||||
return (parser->p_state.q_first == parser->p_state.q_last);
|
return (parser->p_state.q_first == parser->p_state.q_last);
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ extern struct parser_state *parser_push_state(
|
|||||||
extern void parser_pop_state(struct ivy_parser *parser, enum pop_state_flags flags);
|
extern void parser_pop_state(struct ivy_parser *parser, enum pop_state_flags flags);
|
||||||
extern struct parser_state *parser_get_state_generic(struct ivy_parser *parser);
|
extern struct parser_state *parser_get_state_generic(struct ivy_parser *parser);
|
||||||
|
|
||||||
extern void parser_replace_current_node(struct ivy_parser *parser, struct ivy_ast_node *new_node);
|
extern void parser_replace_current_node(
|
||||||
|
struct ivy_parser *parser, struct ivy_ast_node *new_node);
|
||||||
|
extern enum ivy_status parser_add_child(
|
||||||
|
struct ivy_parser *parser, struct ivy_ast_node *new_node);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
1052
lang/ast/expr.c
1052
lang/ast/expr.c
File diff suppressed because it is too large
Load Diff
@@ -80,9 +80,9 @@ static struct token_parse_result parse_pipe(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static enum ivy_status add_child(
|
static enum ivy_status add_child(
|
||||||
struct ivy_ast_node *parent, struct ivy_ast_node *child)
|
struct parser_state *parent, struct ivy_ast_node *child)
|
||||||
{
|
{
|
||||||
struct ivy_ast_msgh_node *msgh = (struct ivy_ast_msgh_node *)parent;
|
struct ivy_ast_msgh_node *msgh = (struct ivy_ast_msgh_node *)parent->s_node;
|
||||||
|
|
||||||
if (child->n_type == IVY_AST_SELECTOR && !msgh->n_sel) {
|
if (child->n_type == IVY_AST_SELECTOR && !msgh->n_sel) {
|
||||||
msgh->n_sel = (struct ivy_ast_selector_node *)child;
|
msgh->n_sel = (struct ivy_ast_selector_node *)child;
|
||||||
|
|||||||
@@ -170,24 +170,6 @@ struct ivy_ast_node *ast_node_create(enum ivy_ast_node_type type)
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ivy_status ast_node_add_child(
|
|
||||||
struct ivy_ast_node *parent, struct ivy_ast_node *child)
|
|
||||||
{
|
|
||||||
const struct ast_node_type *ops = get_ast_node_type(parent->n_type);
|
|
||||||
if (!ops) {
|
|
||||||
return IVY_ERR_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ivy_status (*add_child)(struct ivy_ast_node *, struct ivy_ast_node *)
|
|
||||||
= ops->n_add_child;
|
|
||||||
|
|
||||||
if (!add_child) {
|
|
||||||
return IVY_ERR_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return add_child(parent, child);
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum ivy_status node_print(
|
static enum ivy_status node_print(
|
||||||
struct ivy_ast_node *node, struct ivy_ast_node_iterator *it)
|
struct ivy_ast_node *node, struct ivy_ast_node_iterator *it)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
struct parser_state;
|
struct parser_state;
|
||||||
|
|
||||||
#define PARSE_RESULT(status, flags) \
|
#define PARSE_RESULT(status, flags) \
|
||||||
((struct token_parse_result) {.r_status = (status), .r_flags = (flags)})
|
((struct token_parse_result) { .r_status = (status), .r_flags = (flags) })
|
||||||
|
|
||||||
#define __TOK_PARSER_INDEX(x) ((x) - __IVY_TOK_INDEX_BASE)
|
#define __TOK_PARSER_INDEX(x) ((x) - __IVY_TOK_INDEX_BASE)
|
||||||
#define __SYM_PARSER_INDEX(x) ((x) - __IVY_SYM_INDEX_BASE)
|
#define __SYM_PARSER_INDEX(x) ((x) - __IVY_SYM_INDEX_BASE)
|
||||||
@@ -41,15 +41,15 @@ struct token_parse_result {
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef struct token_parse_result (*token_parse_function)(
|
typedef struct token_parse_result (*token_parse_function)(
|
||||||
struct ivy_parser *, struct ivy_token *);
|
struct ivy_parser*, struct ivy_token*);
|
||||||
|
|
||||||
struct ast_node_type {
|
struct ast_node_type {
|
||||||
enum ivy_status (*n_add_child)(
|
enum ivy_status (*n_add_child)(
|
||||||
struct ivy_ast_node *, struct ivy_ast_node *);
|
struct parser_state*, struct ivy_ast_node*);
|
||||||
void (*n_print)(struct ivy_ast_node *);
|
void (*n_print)(struct ivy_ast_node*);
|
||||||
void (*n_init_state)(struct ivy_parser *, struct parser_state *);
|
void (*n_init_state)(struct ivy_parser*, struct parser_state*);
|
||||||
void (*n_collect_children)(
|
void (*n_collect_children)(
|
||||||
struct ivy_ast_node *, struct ivy_ast_node_iterator *);
|
struct ivy_ast_node*, struct ivy_ast_node_iterator*);
|
||||||
|
|
||||||
size_t n_state_size;
|
size_t n_state_size;
|
||||||
size_t n_node_size;
|
size_t n_node_size;
|
||||||
@@ -65,12 +65,12 @@ struct ast_node_type {
|
|||||||
} n_expr_parser;
|
} n_expr_parser;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct ast_node_type *get_ast_node_type(enum ivy_ast_node_type type);
|
extern const struct ast_node_type* get_ast_node_type(enum ivy_ast_node_type type);
|
||||||
extern token_parse_function get_token_parser(
|
extern token_parse_function get_token_parser(
|
||||||
struct ivy_ast_node *context, struct ivy_token *tok);
|
struct ivy_ast_node* context, struct ivy_token* tok);
|
||||||
extern enum token_expr_type get_token_expr_type(struct ivy_token *tok);
|
extern enum token_expr_type get_token_expr_type(struct ivy_token* tok);
|
||||||
extern struct ivy_ast_node *ast_node_create(enum ivy_ast_node_type type);
|
extern struct ivy_ast_node* ast_node_create(enum ivy_ast_node_type type);
|
||||||
extern enum ivy_status ast_node_add_child(
|
extern enum ivy_status ast_node_add_child(
|
||||||
struct ivy_ast_node *parent, struct ivy_ast_node *child);
|
struct ivy_ast_node* parent, struct ivy_ast_node* child);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ struct unit_import_parser_state {
|
|||||||
int s_prev_token;
|
int s_prev_token;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct token_parse_result parse_dot(struct ivy_parser *ctx, struct ivy_token *tok)
|
static struct token_parse_result parse_dot(
|
||||||
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
||||||
{
|
{
|
||||||
struct unit_import_parser_state *state
|
struct unit_import_parser_state *state
|
||||||
= parser_get_state(ctx, struct unit_import_parser_state);
|
= parser_get_state(ctx, struct unit_import_parser_state);
|
||||||
@@ -56,12 +57,6 @@ static struct token_parse_result parse_linefeed(
|
|||||||
return PARSE_RESULT(IVY_OK, 0);
|
return PARSE_RESULT(IVY_OK, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum ivy_status add_child(
|
|
||||||
struct ivy_ast_node *parent, struct ivy_ast_node *child)
|
|
||||||
{
|
|
||||||
return IVY_ERR_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void print(struct ivy_ast_node *node)
|
static void print(struct ivy_ast_node *node)
|
||||||
{
|
{
|
||||||
struct ivy_ast_unit_import_node *unit_import
|
struct ivy_ast_unit_import_node *unit_import
|
||||||
@@ -93,7 +88,6 @@ static void init_state(struct ivy_parser *ctx, struct parser_state *sp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct ast_node_type unit_import_node_ops = {
|
struct ast_node_type unit_import_node_ops = {
|
||||||
.n_add_child = add_child,
|
|
||||||
.n_print = print,
|
.n_print = print,
|
||||||
.n_init_state = init_state,
|
.n_init_state = init_state,
|
||||||
.n_state_size = sizeof(struct unit_import_parser_state),
|
.n_state_size = sizeof(struct unit_import_parser_state),
|
||||||
|
|||||||
@@ -57,12 +57,6 @@ static struct token_parse_result parse_linefeed(
|
|||||||
return PARSE_RESULT(IVY_OK, 0);
|
return PARSE_RESULT(IVY_OK, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum ivy_status add_child(
|
|
||||||
struct ivy_ast_node *parent, struct ivy_ast_node *child)
|
|
||||||
{
|
|
||||||
return IVY_ERR_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void print(struct ivy_ast_node *node)
|
static void print(struct ivy_ast_node *node)
|
||||||
{
|
{
|
||||||
struct ivy_ast_unit_package_node *unit_package
|
struct ivy_ast_unit_package_node *unit_package
|
||||||
@@ -94,7 +88,6 @@ static void init_state(struct ivy_parser *ctx, struct parser_state *sp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct ast_node_type unit_package_node_ops = {
|
struct ast_node_type unit_package_node_ops = {
|
||||||
.n_add_child = add_child,
|
|
||||||
.n_print = print,
|
.n_print = print,
|
||||||
.n_init_state = init_state,
|
.n_init_state = init_state,
|
||||||
.n_state_size = sizeof(struct unit_package_parser_state),
|
.n_state_size = sizeof(struct unit_package_parser_state),
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ static struct token_parse_result parse_expr_begin(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static enum ivy_status add_child(
|
static enum ivy_status add_child(
|
||||||
struct ivy_ast_node *parent, struct ivy_ast_node *child)
|
struct parser_state *parent, struct ivy_ast_node *child)
|
||||||
{
|
{
|
||||||
struct ivy_ast_unit_node *unit = (struct ivy_ast_unit_node *)parent;
|
struct ivy_ast_unit_node *unit = (struct ivy_ast_unit_node *)parent->s_node;
|
||||||
b_queue_push_back(&unit->n_children, &child->n_entry);
|
b_queue_push_back(&unit->n_children, &child->n_entry);
|
||||||
return IVY_OK;
|
return IVY_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user