Compare commits
No commits in common. "d6d5951b957c18d60998d6d000cf36b7a1d57cd5" and "074b174d0f32b0ca5d620406ca8a4f2390b65fcc" have entirely different histories.
d6d5951b95
...
074b174d0f
@ -25,9 +25,6 @@ static void add_fsa(fsa_t *f, const fsa_t *o, int *init_out, int *final_out)
|
|||||||
}
|
}
|
||||||
memcpy(f->states + f->count, o->states, o->count * sizeof(fsa_state_t));
|
memcpy(f->states + f->count, o->states, o->count * sizeof(fsa_state_t));
|
||||||
|
|
||||||
// Mark o's final state as non-final.
|
|
||||||
f->states[f->count].final = false;
|
|
||||||
|
|
||||||
// Retarget the rules of the copied states to refer to the new
|
// Retarget the rules of the copied states to refer to the new
|
||||||
// state indices.
|
// state indices.
|
||||||
for (int i = f->count; i < count; ++i) {
|
for (int i = f->count; i < count; ++i) {
|
||||||
|
@ -160,17 +160,13 @@ static void insert(table_t *table, int *nfa_states, int count, int dfa_state)
|
|||||||
table->entries = calloc(table->capacity, sizeof(table_entry_t));
|
table->entries = calloc(table->capacity, sizeof(table_entry_t));
|
||||||
assert(NULL != table->entries);
|
assert(NULL != table->entries);
|
||||||
for (int i = 0; i < old_capacity; ++i) {
|
for (int i = 0; i < old_capacity; ++i) {
|
||||||
if (0 != entries[i].nfa_state_count) {
|
if (0 != entries[i].nfa_state_count)
|
||||||
|
continue;
|
||||||
insert(
|
insert(
|
||||||
table, entries[i].nfa_states, entries[i].nfa_state_count,
|
table, entries[i].nfa_states, entries[i].nfa_state_count,
|
||||||
entries[i].dfa_state);
|
entries[i].dfa_state);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
free(entries);
|
free(entries);
|
||||||
|
|
||||||
// Recurse to insert the entry now that the table has been
|
|
||||||
// expanded.
|
|
||||||
insert(table, nfa_states, count, dfa_state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool lookup_or_create(
|
static bool lookup_or_create(
|
||||||
|
@ -33,8 +33,7 @@ int fsa_add_state(fsa_t *fsa)
|
|||||||
{
|
{
|
||||||
if (fsa->count >= fsa->capacity) {
|
if (fsa->count >= fsa->capacity) {
|
||||||
fsa->capacity *= 2;
|
fsa->capacity *= 2;
|
||||||
fsa->states
|
fsa->states = realloc(fsa->states, fsa->capacity);
|
||||||
= realloc(fsa->states, fsa->capacity * sizeof(fsa_state_t));
|
|
||||||
assert(NULL != fsa->states);
|
assert(NULL != fsa->states);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,8 +56,7 @@ void fsa_add_rule(fsa_t *fsa, int from, int to, int input)
|
|||||||
fsa_state_t *state = &fsa->states[from];
|
fsa_state_t *state = &fsa->states[from];
|
||||||
if (state->count >= state->capacity) {
|
if (state->count >= state->capacity) {
|
||||||
state->capacity *= 2;
|
state->capacity *= 2;
|
||||||
state->rules
|
state->rules = realloc(state->rules, state->capacity);
|
||||||
= realloc(state->rules, state->capacity * sizeof(fsa_rule_t));
|
|
||||||
assert(NULL != state->rules);
|
assert(NULL != state->rules);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,47 +273,6 @@ test_union_of_single_term_and_sequence_containing_starred_term(void)
|
|||||||
fsa_free(&fsa);
|
fsa_free(&fsa);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_sequence_of_subexpr_a_or_empty_and_b(void)
|
|
||||||
{
|
|
||||||
// (a|ε)b
|
|
||||||
regex_term_t *inner_terms0 = malloc(1 * sizeof(regex_term_t));
|
|
||||||
inner_terms0[0].quantifier = REGEX_QUANTIFIER_NONE;
|
|
||||||
inner_terms0[0].type = REGEX_TERM_LITERAL;
|
|
||||||
inner_terms0[0].literal = 'a';
|
|
||||||
regex_term_t *inner_terms1 = malloc(1 * sizeof(regex_term_t));
|
|
||||||
inner_terms1[0].quantifier = REGEX_QUANTIFIER_NONE;
|
|
||||||
inner_terms1[0].type = REGEX_TERM_EMPTY;
|
|
||||||
regex_sequence_t *inner_alternatives
|
|
||||||
= malloc(2 * sizeof(regex_sequence_t));
|
|
||||||
inner_alternatives[0].count = inner_alternatives[0].capacity = 1;
|
|
||||||
inner_alternatives[0].contents = inner_terms0;
|
|
||||||
inner_alternatives[1].count = inner_alternatives[1].capacity = 1;
|
|
||||||
inner_alternatives[1].contents = inner_terms1;
|
|
||||||
regex_term_t *terms = malloc(2 * sizeof(regex_term_t));
|
|
||||||
terms[0].quantifier = REGEX_QUANTIFIER_NONE;
|
|
||||||
terms[0].type = REGEX_TERM_SUBEXPR;
|
|
||||||
terms[0].subexpr.count = terms[0].subexpr.capacity = 2;
|
|
||||||
terms[0].subexpr.contents = inner_alternatives;
|
|
||||||
terms[1].quantifier = REGEX_QUANTIFIER_NONE;
|
|
||||||
terms[1].type = REGEX_TERM_LITERAL;
|
|
||||||
terms[1].literal = 'b';
|
|
||||||
regex_sequence_t *alternatives = malloc(1 * sizeof(regex_sequence_t));
|
|
||||||
alternatives[0].count = alternatives[0].capacity = 2;
|
|
||||||
alternatives[0].contents = terms;
|
|
||||||
regex_t regex = { .count = 1, .capacity = 1, .contents = alternatives };
|
|
||||||
|
|
||||||
fsa_t fsa;
|
|
||||||
construct_nfa(®ex, &fsa);
|
|
||||||
|
|
||||||
ASSERT_TRUE(accepts(&fsa, "ab"));
|
|
||||||
ASSERT_TRUE(accepts(&fsa, "b"));
|
|
||||||
ASSERT_FALSE(accepts(&fsa, ""));
|
|
||||||
ASSERT_FALSE(accepts(&fsa, "a"));
|
|
||||||
|
|
||||||
regex_free(®ex);
|
|
||||||
fsa_free(&fsa);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
TESTING_BEGIN();
|
TESTING_BEGIN();
|
||||||
@ -329,7 +288,6 @@ int main(void)
|
|||||||
// Compound expressions
|
// Compound expressions
|
||||||
test_sequence_containing_starred_union();
|
test_sequence_containing_starred_union();
|
||||||
test_union_of_single_term_and_sequence_containing_starred_term();
|
test_union_of_single_term_and_sequence_containing_starred_term();
|
||||||
test_sequence_of_subexpr_a_or_empty_and_b();
|
|
||||||
|
|
||||||
return TESTING_END();
|
return TESTING_END();
|
||||||
}
|
}
|
||||||
|
@ -47,40 +47,11 @@ static void test_arbitrary_regex_1(void)
|
|||||||
fsa_free(&dfa);
|
fsa_free(&dfa);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_arbitrary_regex_2(void)
|
|
||||||
{
|
|
||||||
fsa_t dfa;
|
|
||||||
const char *regex = "(l|wh)?[aeiou]+";
|
|
||||||
const bool success = compile(regex, strlen(regex), &dfa);
|
|
||||||
ASSERT_TRUE(success);
|
|
||||||
ASSERT_ACCEPTS(&dfa, "laaaa");
|
|
||||||
ASSERT_ACCEPTS(&dfa, "eeeee");
|
|
||||||
ASSERT_ACCEPTS(&dfa, "iii");
|
|
||||||
ASSERT_ACCEPTS(&dfa, "whooo");
|
|
||||||
ASSERT_ACCEPTS(&dfa, "u");
|
|
||||||
ASSERT_REJECTS(&dfa, "wh");
|
|
||||||
ASSERT_REJECTS(&dfa, "lxxx");
|
|
||||||
fsa_free(&dfa);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void test_system_header_include_regex(void)
|
|
||||||
{
|
|
||||||
fsa_t dfa;
|
|
||||||
const char *regex = "#include <[abcdefghijklmnopqrstuvwxyz]+\\.h>";
|
|
||||||
const bool success = compile(regex, strlen(regex), &dfa);
|
|
||||||
ASSERT_TRUE(success);
|
|
||||||
ASSERT_ACCEPTS(&dfa, "#include <stdio.h>");
|
|
||||||
ASSERT_REJECTS(&dfa, "#include \"foo.h\"");
|
|
||||||
fsa_free(&dfa);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
TESTING_BEGIN();
|
TESTING_BEGIN();
|
||||||
test_foo_or_bar_regex();
|
test_foo_or_bar_regex();
|
||||||
test_even_number_of_Is_regex();
|
test_even_number_of_Is_regex();
|
||||||
test_arbitrary_regex_1();
|
test_arbitrary_regex_1();
|
||||||
test_arbitrary_regex_2();
|
|
||||||
test_system_header_include_regex();
|
|
||||||
return TESTING_END();
|
return TESTING_END();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user