Define FSA data structure

This commit is contained in:
2024-10-26 19:57:10 +01:00
parent 0ecab6c142
commit ad6c385f42
5 changed files with 222 additions and 1 deletions

67
lib/fsa.c Normal file
View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) Camden Dixie O'Brien
* SPDX-License-Identifier: AGPL-3.0-only
*/
#include "fsa.h"
#include <assert.h>
#include <stdlib.h>
#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, int input)
{
assert(fsa->count > from);
assert(fsa->count > to);
assert(input < ALPHABET_SIZE);
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;
}

38
lib/fsa.h Normal file
View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) Camden Dixie O'Brien
* SPDX-License-Identifier: AGPL-3.0-only
*/
#ifndef FSA_H
#define FSA_H
#include <stdbool.h>
#define CHAR_COUNT 256
#define ALPHABET_SIZE (CHAR_COUNT + 1)
// Use one more than any valid char to represent empty string
#define EPSILON CHAR_COUNT
typedef struct {
int input, next;
} fsa_rule_t;
typedef struct {
bool final;
int count, capacity;
fsa_rule_t *rules;
} fsa_state_t;
typedef struct {
int count, capacity, initial;
fsa_state_t *states;
} fsa_t;
void fsa_init(fsa_t *fsa);
void fsa_free(const fsa_t *fsa);
int fsa_add_state(fsa_t *fsa);
void fsa_add_rule(fsa_t *fsa, int from, int to, int input);
#endif