From d5b40f9324bd99c4cda45d59b279ef62b1069868 Mon Sep 17 00:00:00 2001 From: Camden Dixie O'Brien Date: Sun, 27 Oct 2024 13:35:24 +0000 Subject: [PATCH] Support subexpressions in construct() --- lib/construct.c | 3 ++- tests/construct_tests.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/lib/construct.c b/lib/construct.c index f66e764..d952f7b 100644 --- a/lib/construct.c +++ b/lib/construct.c @@ -74,7 +74,8 @@ static void construct_term(const regex_term_t *term, fsa_t *out) construct_literal(term->literal, out); break; case REGEX_TERM_SUBEXPR: - return; + construct(&term->subexpr, out); + break; case REGEX_TERM_WILDCARD: case REGEX_TERM_CLASS: assert(false); diff --git a/tests/construct_tests.c b/tests/construct_tests.c index d81891b..446df7a 100644 --- a/tests/construct_tests.c +++ b/tests/construct_tests.c @@ -156,6 +156,42 @@ static void test_star(void) fsa_free(&fsa); } +static void test_subexpression(void) +{ + regex_term_t *inner_terms = malloc(1 * sizeof(regex_term_t)); + inner_terms[0].quantifier = REGEX_QUANTIFIER_NONE; + inner_terms[0].type = REGEX_TERM_LITERAL; + inner_terms[0].literal = 'a'; + regex_sequence_t *inner_alternatives + = malloc(1 * sizeof(regex_sequence_t)); + inner_alternatives[0].count = inner_alternatives[0].capacity = 1; + inner_alternatives[0].contents = inner_terms; + regex_term_t *terms = malloc(1 * sizeof(regex_term_t)); + terms[0].quantifier = REGEX_QUANTIFIER_NONE; + terms[0].type = REGEX_TERM_SUBEXPR; + terms[0].subexpr.count = terms[0].subexpr.capacity = 1; + terms[0].subexpr.contents = inner_alternatives; + regex_sequence_t *alternatives = malloc(1 * sizeof(regex_sequence_t)); + alternatives[0].count = alternatives[0].capacity = 1; + alternatives[0].contents = terms; + regex_t regex = { .count = 1, .capacity = 1, .contents = alternatives }; + + fsa_t fsa; + construct(®ex, &fsa); + + const fsa_state_t *initial = &fsa.states[fsa.initial]; + ASSERT_EQ(2, fsa.count); + ASSERT_EQ(1, initial->count); + ASSERT_EQ('a', initial->rules[0].input); + + const int next = initial->rules[0].next; + ASSERT_TRUE(fsa.states[next].final); + ASSERT_EQ(0, fsa.states[next].count); + + regex_free(®ex); + fsa_free(&fsa); +} + int main(void) { TESTING_BEGIN(); @@ -164,5 +200,6 @@ int main(void) test_sequence(); test_union(); test_star(); + test_subexpression(); return TESTING_END(); }