diff --git a/lib/construct.c b/lib/construct.c index 965beae..3eb4811 100644 --- a/lib/construct.c +++ b/lib/construct.c @@ -39,6 +39,10 @@ static void construct_term(const regex_term_t *term, fsa_t *out) static void concat_fsas(fsa_t *base, const fsa_t *other) { + // TODO: Handle the other's final state having transition rules. + assert(0 == other->states[0].count); + + // Copy states other than the final state (index zero) to base. const int new_count = base->count + other->count - 1; if (base->capacity < new_count) { do @@ -47,23 +51,25 @@ static void concat_fsas(fsa_t *base, const fsa_t *other) base->states = realloc(base->states, base->capacity); assert(base->states); } - const int copy_size = (other->count - 1) * sizeof(fsa_state_t); memcpy(&base->states[base->count], &other->states[1], copy_size); - const int id_offset = base->count - 1; + // Retarget new states' rules. for (int i = base->count; i < new_count; ++i) { fsa_state_t *state = &base->states[i]; for (int j = 0; j < state->count; ++j) { if (0 == state->rules[j].next) state->rules[j].next = base->initial; else - state->rules[j].next += id_offset; + // States' indices have increased by one less than the + // base count, as the final state came before them and + // was not copied. + state->rules[j].next += base->count - 1; } } + base->initial = other->initial + base->count - 1; base->count = new_count; - base->initial = other->initial + id_offset; free(other->states[0].rules); free(other->states);