Expose parse tree free procedures

This commit is contained in:
Camden Dixie O'Brien 2024-10-26 14:59:26 +01:00
parent cdaea7a1ec
commit 2bcdfbcd61
3 changed files with 32 additions and 29 deletions

View File

@ -219,22 +219,25 @@ int parse_expr(const char *input, int rem, parse_tree_t *out)
return used; return used;
} }
static void class_free(parse_class_t *c) void parse_free_tree_children(const parse_tree_t *t)
{ {
if (NULL != c->contents) if (NULL != t->alternatives) {
free(c->contents); for (int i = 0; i < t->count; ++i)
parse_free_sequence_children(&t->alternatives[i]);
free(t->alternatives);
}
} }
static void sequence_free(parse_sequence_t *s) void parse_free_sequence_children(const parse_sequence_t *s)
{ {
if (NULL != s->contents) { if (NULL != s->contents) {
for (int i = 0; i < s->len; ++i) { for (int i = 0; i < s->len; ++i) {
switch (s->contents[i].type) { switch (s->contents[i].type) {
case PARSE_TERM_CLASS: case PARSE_TERM_CLASS:
class_free(&s->contents[i].class); parse_free_class_children(&s->contents[i].class);
break; break;
case PARSE_TERM_SUBEXPR: case PARSE_TERM_SUBEXPR:
parse_tree_free_children(&s->contents[i].subexpr); parse_free_tree_children(&s->contents[i].subexpr);
break; break;
case PARSE_TERM_WILDCARD: case PARSE_TERM_WILDCARD:
case PARSE_TERM_LITERAL: case PARSE_TERM_LITERAL:
@ -245,11 +248,8 @@ static void sequence_free(parse_sequence_t *s)
} }
} }
void parse_tree_free_children(parse_tree_t *t) void parse_free_class_children(const parse_class_t *c)
{ {
if (NULL != t->alternatives) { if (NULL != c->contents)
for (int i = 0; i < t->count; ++i) free(c->contents);
sequence_free(&t->alternatives[i]);
free(t->alternatives);
}
} }

View File

@ -50,6 +50,9 @@ typedef struct _parse_term {
} parse_term_t; } parse_term_t;
int parse_expr(const char *input, int rem, parse_tree_t *out); int parse_expr(const char *input, int rem, parse_tree_t *out);
void parse_tree_free_children(parse_tree_t *t);
void parse_free_tree_children(const parse_tree_t *t);
void parse_free_sequence_children(const parse_sequence_t *s);
void parse_free_class_children(const parse_class_t *c);
#endif #endif

View File

@ -14,7 +14,7 @@ static void a_has_1_alternative(void)
const int result = PARSE_EXPR_STRING("a", &t); const int result = PARSE_EXPR_STRING("a", &t);
ASSERT_NE(-1, result); ASSERT_NE(-1, result);
ASSERT_EQ(1, t.count); ASSERT_EQ(1, t.count);
parse_tree_free_children(&t); parse_free_tree_children(&t);
} }
static void a_pipe_b_has_2_alternatives(void) static void a_pipe_b_has_2_alternatives(void)
@ -23,7 +23,7 @@ static void a_pipe_b_has_2_alternatives(void)
const int result = PARSE_EXPR_STRING("a|b", &t); const int result = PARSE_EXPR_STRING("a|b", &t);
ASSERT_NE(-1, result); ASSERT_NE(-1, result);
ASSERT_EQ(2, t.count); ASSERT_EQ(2, t.count);
parse_tree_free_children(&t); parse_free_tree_children(&t);
} }
static void a_pipe_b_pipe_c_has_3_alternatives(void) static void a_pipe_b_pipe_c_has_3_alternatives(void)
@ -32,7 +32,7 @@ static void a_pipe_b_pipe_c_has_3_alternatives(void)
const int result = PARSE_EXPR_STRING("a|b|c", &t); const int result = PARSE_EXPR_STRING("a|b|c", &t);
ASSERT_NE(-1, result); ASSERT_NE(-1, result);
ASSERT_EQ(3, t.count); ASSERT_EQ(3, t.count);
parse_tree_free_children(&t); parse_free_tree_children(&t);
} }
static void a_is_parsed_as_unquantified_literal(void) static void a_is_parsed_as_unquantified_literal(void)
@ -49,7 +49,7 @@ static void a_is_parsed_as_unquantified_literal(void)
ASSERT_EQ(PARSE_TERM_LITERAL, t.alternatives[0].contents[0].type); ASSERT_EQ(PARSE_TERM_LITERAL, t.alternatives[0].contents[0].type);
ASSERT_EQ('a', t.alternatives[0].contents[0].literal); ASSERT_EQ('a', t.alternatives[0].contents[0].literal);
parse_tree_free_children(&t); parse_free_tree_children(&t);
} }
static void b_is_parsed_as_unquantified_literal(void) static void b_is_parsed_as_unquantified_literal(void)
@ -66,7 +66,7 @@ static void b_is_parsed_as_unquantified_literal(void)
ASSERT_EQ(PARSE_TERM_LITERAL, t.alternatives[0].contents[0].type); ASSERT_EQ(PARSE_TERM_LITERAL, t.alternatives[0].contents[0].type);
ASSERT_EQ('b', t.alternatives[0].contents[0].literal); ASSERT_EQ('b', t.alternatives[0].contents[0].literal);
parse_tree_free_children(&t); parse_free_tree_children(&t);
} }
static void abc_is_parsed_as_sequence_of_unquantified_literals(void) static void abc_is_parsed_as_sequence_of_unquantified_literals(void)
@ -91,7 +91,7 @@ static void abc_is_parsed_as_sequence_of_unquantified_literals(void)
ASSERT_EQ(PARSE_TERM_LITERAL, t.alternatives[0].contents[2].type); ASSERT_EQ(PARSE_TERM_LITERAL, t.alternatives[0].contents[2].type);
ASSERT_EQ('c', t.alternatives[0].contents[2].literal); ASSERT_EQ('c', t.alternatives[0].contents[2].literal);
parse_tree_free_children(&t); parse_free_tree_children(&t);
} }
static void dot_is_parsed_as_unquantified_wildcard_term(void) static void dot_is_parsed_as_unquantified_wildcard_term(void)
@ -107,7 +107,7 @@ static void dot_is_parsed_as_unquantified_wildcard_term(void)
PARSE_QUANTIFIER_NONE, t.alternatives[0].contents[0].quantifier); PARSE_QUANTIFIER_NONE, t.alternatives[0].contents[0].quantifier);
ASSERT_EQ(PARSE_TERM_WILDCARD, t.alternatives[0].contents[0].type); ASSERT_EQ(PARSE_TERM_WILDCARD, t.alternatives[0].contents[0].type);
parse_tree_free_children(&t); parse_free_tree_children(&t);
} }
static void backslash_dot_is_parsed_as_unquantified_literal(void) static void backslash_dot_is_parsed_as_unquantified_literal(void)
@ -124,7 +124,7 @@ static void backslash_dot_is_parsed_as_unquantified_literal(void)
ASSERT_EQ(PARSE_TERM_LITERAL, t.alternatives[0].contents[0].type); ASSERT_EQ(PARSE_TERM_LITERAL, t.alternatives[0].contents[0].type);
ASSERT_EQ('.', t.alternatives[0].contents[0].literal); ASSERT_EQ('.', t.alternatives[0].contents[0].literal);
parse_tree_free_children(&t); parse_free_tree_children(&t);
} }
static void backslash_backslash_is_parsed_as_unquantified_literal(void) static void backslash_backslash_is_parsed_as_unquantified_literal(void)
@ -141,7 +141,7 @@ static void backslash_backslash_is_parsed_as_unquantified_literal(void)
ASSERT_EQ(PARSE_TERM_LITERAL, t.alternatives[0].contents[0].type); ASSERT_EQ(PARSE_TERM_LITERAL, t.alternatives[0].contents[0].type);
ASSERT_EQ('\\', t.alternatives[0].contents[0].literal); ASSERT_EQ('\\', t.alternatives[0].contents[0].literal);
parse_tree_free_children(&t); parse_free_tree_children(&t);
} }
static void a_pipe_b_in_parens_is_parsed_as_subexpr_term(void) static void a_pipe_b_in_parens_is_parsed_as_subexpr_term(void)
@ -174,7 +174,7 @@ static void a_pipe_b_in_parens_is_parsed_as_subexpr_term(void)
ASSERT_EQ(PARSE_TERM_LITERAL, inner->alternatives[1].contents[0].type); ASSERT_EQ(PARSE_TERM_LITERAL, inner->alternatives[1].contents[0].type);
ASSERT_EQ('b', inner->alternatives[1].contents[0].literal); ASSERT_EQ('b', inner->alternatives[1].contents[0].literal);
parse_tree_free_children(&t); parse_free_tree_children(&t);
} }
static void a_in_parens_b_is_parsed_as_sequence_with_subexpr_term(void) static void a_in_parens_b_is_parsed_as_sequence_with_subexpr_term(void)
@ -202,7 +202,7 @@ static void a_in_parens_b_is_parsed_as_sequence_with_subexpr_term(void)
ASSERT_EQ(PARSE_TERM_LITERAL, inner->alternatives[0].contents[0].type); ASSERT_EQ(PARSE_TERM_LITERAL, inner->alternatives[0].contents[0].type);
ASSERT_EQ('a', inner->alternatives[0].contents[0].literal); ASSERT_EQ('a', inner->alternatives[0].contents[0].literal);
parse_tree_free_children(&t); parse_free_tree_children(&t);
} }
static void dot_star_is_parsed_as_star_quantified_wildcard(void) static void dot_star_is_parsed_as_star_quantified_wildcard(void)
@ -218,7 +218,7 @@ static void dot_star_is_parsed_as_star_quantified_wildcard(void)
PARSE_QUANTIFIER_STAR, t.alternatives[0].contents[0].quantifier); PARSE_QUANTIFIER_STAR, t.alternatives[0].contents[0].quantifier);
ASSERT_EQ(PARSE_TERM_WILDCARD, t.alternatives[0].contents[0].type); ASSERT_EQ(PARSE_TERM_WILDCARD, t.alternatives[0].contents[0].type);
parse_tree_free_children(&t); parse_free_tree_children(&t);
} }
static void dot_plus_is_parsed_as_plus_quantified_wildcard(void) static void dot_plus_is_parsed_as_plus_quantified_wildcard(void)
@ -234,7 +234,7 @@ static void dot_plus_is_parsed_as_plus_quantified_wildcard(void)
PARSE_QUANTIFIER_PLUS, t.alternatives[0].contents[0].quantifier); PARSE_QUANTIFIER_PLUS, t.alternatives[0].contents[0].quantifier);
ASSERT_EQ(PARSE_TERM_WILDCARD, t.alternatives[0].contents[0].type); ASSERT_EQ(PARSE_TERM_WILDCARD, t.alternatives[0].contents[0].type);
parse_tree_free_children(&t); parse_free_tree_children(&t);
} }
static void dot_question_mark_is_parsed_as_qmrk_quantified_wildcard(void) static void dot_question_mark_is_parsed_as_qmrk_quantified_wildcard(void)
@ -250,7 +250,7 @@ static void dot_question_mark_is_parsed_as_qmrk_quantified_wildcard(void)
PARSE_QUANTIFIER_QMRK, t.alternatives[0].contents[0].quantifier); PARSE_QUANTIFIER_QMRK, t.alternatives[0].contents[0].quantifier);
ASSERT_EQ(PARSE_TERM_WILDCARD, t.alternatives[0].contents[0].type); ASSERT_EQ(PARSE_TERM_WILDCARD, t.alternatives[0].contents[0].type);
parse_tree_free_children(&t); parse_free_tree_children(&t);
} }
static void a_in_brackets_is_parsed_as_class_containing_only_a(void) static void a_in_brackets_is_parsed_as_class_containing_only_a(void)
@ -270,7 +270,7 @@ static void a_in_brackets_is_parsed_as_class_containing_only_a(void)
ASSERT_NOT_NULL(t.alternatives[0].contents[0].class.contents); ASSERT_NOT_NULL(t.alternatives[0].contents[0].class.contents);
ASSERT_EQ('a', t.alternatives[0].contents[0].class.contents[0]); ASSERT_EQ('a', t.alternatives[0].contents[0].class.contents[0]);
parse_tree_free_children(&t); parse_free_tree_children(&t);
} }
static void caret_a_in_brackets_parses_as_negated_class(void) static void caret_a_in_brackets_parses_as_negated_class(void)
@ -290,7 +290,7 @@ static void caret_a_in_brackets_parses_as_negated_class(void)
ASSERT_NOT_NULL(t.alternatives[0].contents[0].class.contents); ASSERT_NOT_NULL(t.alternatives[0].contents[0].class.contents);
ASSERT_EQ('a', t.alternatives[0].contents[0].class.contents[0]); ASSERT_EQ('a', t.alternatives[0].contents[0].class.contents[0]);
parse_tree_free_children(&t); parse_free_tree_children(&t);
} }
int main(void) int main(void)