Rename p_free_tree() to p_tree_delete()

This commit is contained in:
Josh Holtrop 2026-02-17 19:24:50 -05:00
parent 6fd5186159
commit ff61dd05d9
17 changed files with 50 additions and 44 deletions

View File

@ -1,8 +1,13 @@
## v4.0.0 ## v4.0.0
### New Features
- Add `p_context_delete()`.
### Breaking Changes ### Breaking Changes
- Replace `p_context_init()` with `p_context_new()` and `p_context_delete()`. - Replace `p_context_init()` with `p_context_new()` and `p_context_delete()`.
- Renamed `p_free_tree()` to `p_tree_delete()`.
## v3.0.0 ## v3.0.0

View File

@ -8,6 +8,7 @@
-> `context`). -> `context`).
- Add a call to `p_context_delete()` (for C or C++) after lexing/parsing to - Add a call to `p_context_delete()` (for C or C++) after lexing/parsing to
reclaim context memory. reclaim context memory.
- Rename `p_free_tree()` calls to `p_tree_delete()`.
## v3.0.0 ## v3.0.0

View File

@ -1206,7 +1206,7 @@ size_t <%= @grammar.prefix %>user_terminate_code(<%= @grammar.prefix %>context_t
} }
<% if @grammar.tree %> <% if @grammar.tree %>
static void free_tree_node(TreeNode * node) static void tree_delete(TreeNode * node)
{ {
if (node->is_token) if (node->is_token)
{ {
@ -1221,7 +1221,7 @@ static void free_tree_node(TreeNode * node)
{ {
if (node->fields[i] != NULL) if (node->fields[i] != NULL)
{ {
free_tree_node(node->fields[i]); tree_delete(node->fields[i]);
} }
} }
} }
@ -1231,18 +1231,18 @@ static void free_tree_node(TreeNode * node)
/** /**
* Free all tree node memory. * Free all tree node memory.
*/ */
void <%= @grammar.prefix %>free_tree(<%= @grammar.tree_prefix %><%= @grammar.start_rules[0] %><%= @grammar.tree_suffix %> * tree) void <%= @grammar.prefix %>tree_delete(<%= @grammar.tree_prefix %><%= @grammar.start_rules[0] %><%= @grammar.tree_suffix %> * tree)
{ {
free_tree_node((TreeNode *)tree); tree_delete((TreeNode *)tree);
} }
<% @grammar.start_rules.each_with_index do |start_rule, i| %> <% @grammar.start_rules.each_with_index do |start_rule, i| %>
/** /**
* Free all tree node memory. * Free all tree node memory.
*/ */
void <%= @grammar.prefix %>free_tree_<%= start_rule %>(<%= @grammar.tree_prefix %><%= start_rule %><%= @grammar.tree_suffix %> * tree) void <%= @grammar.prefix %>tree_delete_<%= start_rule %>(<%= @grammar.tree_prefix %><%= start_rule %><%= @grammar.tree_suffix %> * tree)
{ {
free_tree_node((TreeNode *)tree); tree_delete((TreeNode *)tree);
} }
<% end %> <% end %>
<% end %> <% end %>

View File

@ -211,9 +211,9 @@ size_t <%= @grammar.prefix %>parse_<%= start_rule %>(<%= @grammar.prefix %>conte
<% end %> <% end %>
<% if @grammar.tree %> <% if @grammar.tree %>
void <%= @grammar.prefix %>free_tree(<%= @grammar.tree_prefix %><%= @grammar.start_rules[0] %><%= @grammar.tree_suffix %> * tree); void <%= @grammar.prefix %>tree_delete(<%= @grammar.tree_prefix %><%= @grammar.start_rules[0] %><%= @grammar.tree_suffix %> * tree);
<% @grammar.start_rules.each_with_index do |start_rule, i| %> <% @grammar.start_rules.each_with_index do |start_rule, i| %>
void <%= @grammar.prefix %>free_tree_<%= start_rule %>(<%= @grammar.tree_prefix %><%= start_rule %><%= @grammar.tree_suffix %> * tree); void <%= @grammar.prefix %>tree_delete_<%= start_rule %>(<%= @grammar.tree_prefix %><%= start_rule %><%= @grammar.tree_suffix %> * tree);
<% end %> <% end %>
<% end %> <% end %>

View File

@ -391,7 +391,7 @@ assert(itemsmore.pItem.pItem.pItem.pToken1 !is null);
If user lexer code block allocates memory to store in a token node's `pvalue`, If user lexer code block allocates memory to store in a token node's `pvalue`,
the `free_token_node` grammar statement can be used to specify the name of a the `free_token_node` grammar statement can be used to specify the name of a
function which will be called during the `p_free_tree()` call to free the memory function which will be called during the `p_tree_delete()` call to free the memory
associated with a token node. associated with a token node.
Example: Example:
@ -808,12 +808,12 @@ start Module ModuleItem Statement Expression;
``` ```
When multiple start rules are specified, multiple `p_parse_*()` functions, When multiple start rules are specified, multiple `p_parse_*()` functions,
`p_result_*()`, and `p_free_tree_*()` functions (in tree mode) are generated. `p_result_*()`, and `p_tree_delete_*()` functions (in tree mode) are generated.
A default `p_parse()`, `p_result()`, `p_free_tree()` are generated corresponding A default `p_parse()`, `p_result()`, `p_tree_delete()` are generated corresponding
to the first start rule. to the first start rule.
Additionally, each start rule causes the generation of another version of each Additionally, each start rule causes the generation of another version of each
of these functions, for example `p_parse_Statement()`, `p_result_Statement()`, of these functions, for example `p_parse_Statement()`, `p_result_Statement()`,
and `p_free_tree_Statement()`. and `p_tree_delete_Statement()`.
##> Specifying the parser module name - the `module` statement ##> Specifying the parser module name - the `module` statement
@ -1232,26 +1232,26 @@ assert(code_point == 0x1F9E1u);
assert(code_point_length == 4u); assert(code_point_length == 4u);
``` ```
### `p_free_tree` ### `p_tree_delete`
The `p_free_tree()` function can be used to free the memory used by the tree. The `p_tree_delete()` function can be used to free the memory used by the tree.
It should be passed the same value that is returned by `p_result()`. It should be passed the same value that is returned by `p_result()`.
The `p_free_tree()` function is only available for C/C++ output targets. The `p_tree_delete()` function is only available for C/C++ output targets.
Note that if any lexer user code block allocates memory to store in a token's Note that if any lexer user code block allocates memory to store in a token's
`pvalue`, in order to properly free this memory a `free_token_node` function `pvalue`, in order to properly free this memory a `free_token_node` function
should be specified in the grammar file. should be specified in the grammar file.
If specified, the `free_token_node` function will be called during the If specified, the `free_token_node` function will be called during the
`p_free_tree()` process to allow user code to free any memory associated with `p_tree_delete()` process to allow user code to free any memory associated with
a token node's `pvalue`. a token node's `pvalue`.
When multiple start rules are specified, a separate `p_free_tree` function is When multiple start rules are specified, a separate `p_tree_delete` function is
generated for each which frees the tree resulting from parsing the given rule. generated for each which frees the tree resulting from parsing the given rule.
For example, if `Statement` is specified as a start rule: For example, if `Statement` is specified as a start rule:
``` ```
p_free_tree_Statement(statement_tree); p_tree_delete_Statement(statement_tree);
``` ```
In this case, Propane will free a `Statement` tree structure returned by the In this case, Propane will free a `Statement` tree structure returned by the

View File

@ -1504,7 +1504,7 @@ token b <<
Start -> a:a b:b; Start -> a:a b:b;
EOF EOF
run_propane(language: language) run_propane(language: language)
compile("spec/test_free_tree_token_node_memory.#{language}", language: language) compile("spec/test_tree_delete_token_node_memory.#{language}", language: language)
results = run_test(language: language) results = run_test(language: language)
expect(results.stderr).to eq "" expect(results.stderr).to eq ""
expect(results.status).to eq 0 expect(results.status).to eq 0

View File

@ -17,7 +17,7 @@ int main()
assert(start->pR == NULL); assert(start->pR == NULL);
assert(start->r == NULL); assert(start->r == NULL);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
input = "abcd"; input = "abcd";
@ -34,7 +34,7 @@ int main()
assert(start->pR == start->r); assert(start->pR == start->r);
assert_eq(TOKEN_c, start->pR->pToken1->token); assert_eq(TOKEN_c, start->pR->pToken1->token);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
input = "bdc"; input = "bdc";
@ -46,7 +46,7 @@ int main()
assert(start->r != NULL); assert(start->r != NULL);
assert_eq(TOKEN_d, start->pR->pToken1->token); assert_eq(TOKEN_d, start->pR->pToken1->token);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
return 0; return 0;

View File

@ -16,7 +16,7 @@ int main()
assert(start->pR3 == NULL); assert(start->pR3 == NULL);
assert(start->pR == NULL); assert(start->pR == NULL);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
input = "abcd"; input = "abcd";
@ -31,7 +31,7 @@ int main()
assert(start->pR == start->pR3); assert(start->pR == start->pR3);
assert_eq(TOKEN_c, start->pR->pToken1->token); assert_eq(TOKEN_c, start->pR->pToken1->token);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
input = "bdc"; input = "bdc";
@ -43,7 +43,7 @@ int main()
assert(start->pR != NULL); assert(start->pR != NULL);
assert_eq(TOKEN_d, start->pR->pToken1->token); assert_eq(TOKEN_d, start->pR->pToken1->token);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
return 0; return 0;

View File

@ -13,7 +13,7 @@ int main()
assert(top->pToken != NULL); assert(top->pToken != NULL);
assert_eq(TOKEN_hi, top->pToken->token); assert_eq(TOKEN_hi, top->pToken->token);
p_free_tree(top); p_tree_delete(top);
p_context_delete(context); p_context_delete(context);
return 0; return 0;

View File

@ -15,7 +15,7 @@ int main()
assert_not_null(start->bs->bs->b); assert_not_null(start->bs->bs->b);
assert_not_null(start->bs->bs->bs->b); assert_not_null(start->bs->bs->bs->b);
assert_not_null(start->bs->bs->bs->bs->b); assert_not_null(start->bs->bs->bs->bs->b);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
context = p_context_new((uint8_t const *)input, strlen(input)); context = p_context_new((uint8_t const *)input, strlen(input));
@ -25,7 +25,7 @@ int main()
assert_not_null(bs->bs->b); assert_not_null(bs->bs->b);
assert_not_null(bs->bs->bs->b); assert_not_null(bs->bs->bs->b);
assert_not_null(bs->bs->bs->bs->b); assert_not_null(bs->bs->bs->bs->b);
p_free_tree_Bs(bs); p_tree_delete_Bs(bs);
p_context_delete(context); p_context_delete(context);
input = "c"; input = "c";
@ -33,7 +33,7 @@ int main()
assert(p_parse_R(context) == P_SUCCESS); assert(p_parse_R(context) == P_SUCCESS);
R * r = p_result_R(context); R * r = p_result_R(context);
assert_not_null(r->c); assert_not_null(r->c);
p_free_tree_R(r); p_tree_delete_R(r);
p_context_delete(context); p_context_delete(context);
return 0; return 0;

View File

@ -33,7 +33,7 @@ int main()
assert_eq(22, itemsmore->pItem->pToken1->pvalue); assert_eq(22, itemsmore->pItem->pToken1->pvalue);
assert(itemsmore->pItemsMore == NULL); assert(itemsmore->pItemsMore == NULL);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
input = ""; input = "";
@ -42,7 +42,7 @@ int main()
start = p_result(context); start = p_result(context);
assert(start->pItems == NULL); assert(start->pItems == NULL);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
input = "2 1"; input = "2 1";
@ -57,7 +57,7 @@ int main()
assert(start->pItems->pItem->pDual->pTwo2 == NULL); assert(start->pItems->pItem->pDual->pTwo2 == NULL);
assert(start->pItems->pItem->pDual->pOne1 == NULL); assert(start->pItems->pItem->pDual->pOne1 == NULL);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
return 0; return 0;

View File

@ -15,6 +15,6 @@ int main()
assert(start->b != NULL); assert(start->b != NULL);
assert(*start->b->pvalue == 2); assert(*start->b->pvalue == 2);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
} }

View File

@ -15,7 +15,7 @@ int main()
assert_eq(TOKEN_b, start->second->pToken->token); assert_eq(TOKEN_b, start->second->pToken->token);
assert_eq(TOKEN_c, start->third->pToken->token); assert_eq(TOKEN_c, start->third->pToken->token);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
return 0; return 0;

View File

@ -30,7 +30,7 @@ int main()
assert_eq(3, start->end_position.row); assert_eq(3, start->end_position.row);
assert_eq(8, start->end_position.col); assert_eq(8, start->end_position.col);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
input = "a\nbb"; input = "a\nbb";
@ -57,7 +57,7 @@ int main()
assert_eq(2, start->end_position.row); assert_eq(2, start->end_position.row);
assert_eq(2, start->end_position.col); assert_eq(2, start->end_position.col);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
input = "a\nc\nc"; input = "a\nc\nc";
@ -84,7 +84,7 @@ int main()
assert_eq(3, start->end_position.row); assert_eq(3, start->end_position.row);
assert_eq(1, start->end_position.col); assert_eq(1, start->end_position.col);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
input = "a"; input = "a";
@ -107,7 +107,7 @@ int main()
assert_eq(1, start->end_position.row); assert_eq(1, start->end_position.row);
assert_eq(1, start->end_position.col); assert_eq(1, start->end_position.col);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
return 0; return 0;

View File

@ -412,7 +412,7 @@ int main(int argc, char * argv[])
} }
free(pfds); free(pfds);
p_free_tree(pmod); p_tree_delete(pmod);
p_context_delete(context); p_context_delete(context);
return 0; return 0;

View File

@ -33,7 +33,7 @@ int main()
assert_eq(22, itemsmore->pItem->pToken1->pvalue); assert_eq(22, itemsmore->pItem->pToken1->pvalue);
assert(itemsmore->pItemsMore == NULL); assert(itemsmore->pItemsMore == NULL);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
input = ""; input = "";
@ -42,7 +42,7 @@ int main()
start = p_result(context); start = p_result(context);
assert(start->pItems == NULL); assert(start->pItems == NULL);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
input = "2 1"; input = "2 1";
@ -57,7 +57,7 @@ int main()
assert(start->pItems->pItem->pDual->pTwo2 == NULL); assert(start->pItems->pItem->pDual->pTwo2 == NULL);
assert(start->pItems->pItem->pDual->pOne1 == NULL); assert(start->pItems->pItem->pDual->pOne1 == NULL);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
return 0; return 0;

View File

@ -43,7 +43,7 @@ int main()
assert_eq(1, start->end_position.row); assert_eq(1, start->end_position.row);
assert_eq(6, start->end_position.col); assert_eq(6, start->end_position.col);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
input = "\n\n bb\nc\ncc\n\n a"; input = "\n\n bb\nc\ncc\n\n a";
@ -83,7 +83,7 @@ int main()
assert_eq(7, start->end_position.row); assert_eq(7, start->end_position.row);
assert_eq(6, start->end_position.col); assert_eq(6, start->end_position.col);
p_free_tree(start); p_tree_delete(start);
p_context_delete(context); p_context_delete(context);
return 0; return 0;