/* * Copyright (c) Camden Dixie O'Brien * SPDX-License-Identifier: AGPL-3.0-only */ #include "fsa.h" #include #include #define FSA_START_CAPACITY 16 #define STATE_START_CAPACITY 16 void fsa_init(fsa_t *fsa) { fsa->count = 0; fsa->capacity = FSA_START_CAPACITY; fsa->states = malloc(fsa->capacity * sizeof(fsa_state_t)); assert(NULL != fsa->states); fsa->initial = fsa_add_state(fsa); fsa->states[fsa->initial].final = true; } void fsa_free(const fsa_t *fsa) { for (int i = 0; i < fsa->count; ++i) free(fsa->states[i].rules); free(fsa->states); } int fsa_add_state(fsa_t *fsa) { if (fsa->count >= fsa->capacity) { fsa->capacity *= 2; fsa->states = realloc(fsa->states, fsa->capacity); assert(NULL != fsa->states); } fsa_state_t *state = &fsa->states[fsa->count]; state->final = false; state->count = 0; state->capacity = STATE_START_CAPACITY; state->rules = malloc(state->capacity * sizeof(fsa_rule_t)); assert(state->rules); return fsa->count++; } void fsa_add_rule(fsa_t *fsa, int from, int to, char input) { assert(fsa->count > from); assert(fsa->count > to); fsa_state_t *state = &fsa->states[from]; if (state->count >= state->capacity) { state->capacity *= 2; state->rules = realloc(state->rules, state->capacity); assert(NULL != state->rules); } fsa_rule_t *rule = &state->rules[state->count]; rule->input = input; rule->next = to; ++state->count; }