Skip to content

Commit

Permalink
Merge pull request #498 from katef/sv/determinise-with-config
Browse files Browse the repository at this point in the history
Temporary interface: Add fsm_determinise_with_config.
  • Loading branch information
katef authored Oct 10, 2024
2 parents 0961848 + 07e1a0c commit bfeb7ce
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 7 deletions.
15 changes: 15 additions & 0 deletions include/fsm/fsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,21 @@ fsm_remove_epsilons(struct fsm *fsm);
int
fsm_determinise(struct fsm *fsm);

/* Determinise, with a passed in configuration
* and a distinct return value for reaching
* the state limit. */
struct fsm_determinise_config {
size_t state_limit; /* 0: no limit */
};
enum fsm_determinise_with_config_res {
FSM_DETERMINISE_WITH_CONFIG_OK,
FSM_DETERMINISE_WITH_CONFIG_STATE_LIMIT_REACHED,
FSM_DETERMINISE_WITH_CONFIG_ERRNO,
};
enum fsm_determinise_with_config_res
fsm_determinise_with_config(struct fsm *fsm,
const struct fsm_determinise_config *config);

/*
* Make a DFA complete, as per fsm_iscomplete.
*/
Expand Down
44 changes: 37 additions & 7 deletions src/libfsm/determinise.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,20 @@ dump_labels(FILE *f, const uint64_t labels[4])
}
}

int
fsm_determinise(struct fsm *nfa)
enum fsm_determinise_with_config_res
fsm_determinise_with_config(struct fsm *nfa,
const struct fsm_determinise_config *config)
{
int res = 0;
enum fsm_determinise_with_config_res res = FSM_DETERMINISE_WITH_CONFIG_ERRNO;
struct mappingstack *stack = NULL;

struct interned_state_set_pool *issp = NULL;
struct map map = { NULL, 0, 0, NULL };
struct mapping *curr = NULL;
size_t dfacount = 0;
const size_t state_limit = config == NULL
? 0
: config->state_limit;

struct analyze_closures_env ac_env = { 0 };

Expand All @@ -40,7 +44,7 @@ fsm_determinise(struct fsm *nfa)
*/
if (fsm_has(nfa, fsm_hasepsilons)) {
if (!fsm_remove_epsilons(nfa)) {
return 0;
return FSM_DETERMINISE_WITH_CONFIG_ERRNO;
}
}

Expand All @@ -52,7 +56,12 @@ fsm_determinise(struct fsm *nfa)

issp = interned_state_set_pool_alloc(nfa->alloc);
if (issp == NULL) {
return 0;
return FSM_DETERMINISE_WITH_CONFIG_ERRNO;
}

if (state_limit != 0 && fsm_countstates(nfa) > state_limit) {
res = FSM_DETERMINISE_WITH_CONFIG_STATE_LIMIT_REACHED;
goto cleanup;
}

{
Expand All @@ -74,7 +83,7 @@ fsm_determinise(struct fsm *nfa)
*/

if (!fsm_getstart(nfa, &start)) {
res = 1;
res = FSM_DETERMINISE_WITH_CONFIG_OK;
goto cleanup;
}

Expand Down Expand Up @@ -150,6 +159,11 @@ fsm_determinise(struct fsm *nfa)
assert(m->dfastate < dfacount);
} else {
/* not found -- add a new one and push it to the stack for processing */

if (state_limit != 0 && dfacount > state_limit) {
res = FSM_DETERMINISE_WITH_CONFIG_STATE_LIMIT_REACHED;
goto cleanup;
}
if (!map_add(&map, dfacount, iss, &m)) {
goto cleanup;
}
Expand Down Expand Up @@ -260,7 +274,7 @@ fsm_determinise(struct fsm *nfa)
assert(fsm_all(nfa, fsm_isdfa));
#endif

res = 1;
res = FSM_DETERMINISE_WITH_CONFIG_OK;

cleanup:
map_free(&map);
Expand Down Expand Up @@ -311,6 +325,22 @@ fsm_determinise(struct fsm *nfa)
return res;
}

int
fsm_determinise(struct fsm *nfa)
{
enum fsm_determinise_with_config_res res = fsm_determinise_with_config(nfa, NULL);
switch (res) {
case FSM_DETERMINISE_WITH_CONFIG_OK:
return 1;
case FSM_DETERMINISE_WITH_CONFIG_STATE_LIMIT_REACHED:
/* unreachable */
return 0;
case FSM_DETERMINISE_WITH_CONFIG_ERRNO:
default:
return 0;
}
}

/* Add DFA_state to the list for NFA_state. */
static int
add_reverse_mapping(const struct fsm_alloc *alloc,
Expand Down
1 change: 1 addition & 0 deletions src/libfsm/libfsm.syms
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ fsm_countstates
fsm_trim
fsm_reverse
fsm_determinise
fsm_determinise_with_config
fsm_remove_epsilons
fsm_complete
fsm_minimise
Expand Down

0 comments on commit bfeb7ce

Please sign in to comment.