From 2385d3860833b5d4215116b42a32528a4c22cee2 Mon Sep 17 00:00:00 2001 From: omicron Date: Wed, 16 Apr 2025 13:01:02 +0200 Subject: [PATCH] Prune the parse tree of NODE_NEWLINE after parsing succeeds --- src/ast.c | 15 +++++++++++++++ src/ast.h | 13 +++++++++++++ src/parser/parser.c | 6 +++++- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/ast.c b/src/ast.c index 5b93585..e47c949 100644 --- a/src/ast.c +++ b/src/ast.c @@ -188,3 +188,18 @@ static void ast_node_print_internal(ast_node_t *node, int indent) { void ast_node_print(ast_node_t *node) { ast_node_print_internal(node, 0); } + +void ast_node_prune(ast_node_t *node, node_id_t id) { + size_t new_len = 0; + for (size_t i = 0; i < node->len; i++) { + auto child = node->children[i]; + if (child->id == id) { + ast_node_free(child); + continue; + } + ast_node_prune(child, id); + node->children[new_len] = child; + new_len++; + } + node->len = new_len; +} diff --git a/src/ast.h b/src/ast.h index dafd736..038d88e 100644 --- a/src/ast.h +++ b/src/ast.h @@ -120,4 +120,17 @@ error_t *ast_node_add_child(ast_node_t *node, ast_node_t *child); */ void ast_node_print(ast_node_t *node); +/** + * Prune the children with a given id + * + * The tree is recursively visited and all child nodes of a given ID are pruned + * completely. If a node has the giver id, it will get removed along wih all its + * children, even if some of those children have different ids. The root node id + * is never checked so the tree is guaranteed to remain and allocated valid. + * + * @param node The root of the tree you want to prune + * @param id The id of the nodes you want to prune + */ +void ast_node_prune(ast_node_t *node, node_id_t id); + #endif // INCLUDE_SRC_AST_H_ diff --git a/src/parser/parser.c b/src/parser/parser.c index d6d4a18..f3db142 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -139,5 +139,9 @@ parse_result_t parse_statement(tokenlist_entry_t *current) { parse_result_t parse(tokenlist_entry_t *current) { current = tokenlist_skip_trivia(current); - return parse_many(current, NODE_PROGRAM, true, parse_statement); + parse_result_t result = + parse_many(current, NODE_PROGRAM, true, parse_statement); + if (result.node != nullptr) + ast_node_prune(result.node, NODE_NEWLINE); + return result; }