diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-09-13 06:34:31 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-09-13 06:34:31 -0700 |
commit | e7c55ed9b8ff89310dc08b98eb03fc35ef280e41 (patch) | |
tree | e10a87f229c38dd4c1ee23ab396bdbad1c469fee /regex.c | |
parent | af7509ea7af412e5290906f5c5fa092ff87c077f (diff) | |
download | txr-e7c55ed9b8ff89310dc08b98eb03fc35ef280e41.tar.gz txr-e7c55ed9b8ff89310dc08b98eb03fc35ef280e41.tar.bz2 txr-e7c55ed9b8ff89310dc08b98eb03fc35ef280e41.zip |
regex: re-introduce nfa_accept states.
The nfa_accept state label is re-introduced. This state type
has the same representation as nfa_empty; essentially, this
replaces the flag. This makes the state type smaller, and we
don't have to access the flag to tell if a state is an
acceptance state.
* regex.c (nfa_kind_t): New enum label, nfa_accept.
(struct nfa_state_empty): Member accept removed.
(nfa_accept_state_p): Macro tests only for nfa_accept type.
(nfa_empty_state_p): New macro.
(nfa_state_accept): Set type of new state to nfa_accept;
do not set accept flag.
(nfa_state_empty): Do not set accept flag.
(nfa_state_empty_convert): Do not clear accept flag.
(nfa_map_states): Handle nfa_accept in switch, in the
same case as nfa_empty.
(nfa_thread_epsilons): Don't test for accept state in
nfa_empty case; it would be always false now. Add nfa_accept
case to switch which only arranges for a traversal of the two
transitions. (Though these are expected to be null at the
stage of the graph when this function is applied).
(nfa_fold_accept): Switch type to nfa_accept rather than
setting accept flag.
(nfa_closure, nfa_move_closure): Use new macro for testing
whether a state is empty.
Diffstat (limited to 'regex.c')
-rw-r--r-- | regex.c | 27 |
1 files changed, 14 insertions, 13 deletions
@@ -190,7 +190,7 @@ typedef union char_set { } char_set_t; typedef enum { - nfa_empty, nfa_wild, nfa_single, nfa_set + nfa_empty, nfa_accept, nfa_wild, nfa_single, nfa_set } nfa_kind_t; struct nfa_state_any { @@ -203,7 +203,6 @@ struct nfa_state_empty { unsigned visited; nfa_state_t *trans0; nfa_state_t *trans1; - int accept; }; struct nfa_state_single { @@ -227,7 +226,9 @@ union nfa_state { struct nfa_state_set s; }; -#define nfa_accept_state_p(s) ((s)->a.kind == nfa_empty && (s)->e.accept) +#define nfa_accept_state_p(s) ((s)->a.kind == nfa_accept) +#define nfa_empty_state_p(s) ((s)->a.kind == nfa_accept || \ + (s)->a.kind == nfa_empty) struct nfa_machine { int is_nfa; /* common member */ @@ -812,10 +813,9 @@ static struct cobj_ops char_set_obj_ops = cobj_ops_init(eq, static nfa_state_t *nfa_state_accept(void) { nfa_state_t *st = coerce(nfa_state_t *, chk_malloc(sizeof *st)); - st->e.kind = nfa_empty; + st->e.kind = nfa_accept; st->e.visited = 0; st->e.trans0 = st->e.trans1 = 0; - st->e.accept = 1; return st; } @@ -826,7 +826,6 @@ static nfa_state_t *nfa_state_empty(nfa_state_t *t0, nfa_state_t *t1) st->e.visited = 0; st->e.trans0 = t0; st->e.trans1 = t1; - st->e.accept = 0; return st; } @@ -887,7 +886,6 @@ static void nfa_state_empty_convert(nfa_state_t *acc, nfa_state_t *t0, acc->e.kind = nfa_empty; acc->e.trans0 = t0; acc->e.trans1 = t1; - acc->e.accept = 0; } /* @@ -1071,6 +1069,7 @@ static void nfa_map_states(nfa_state_t *s, switch (s->a.kind) { case nfa_empty: + case nfa_accept: nfa_map_states(s->e.trans0, ctx, fun, visited); nfa_map_states(s->e.trans1, ctx, fun, visited); break; @@ -1144,8 +1143,6 @@ static void nfa_thread_epsilons(nfa_state_t **ps, unsigned visited) switch (s->a.kind) { case nfa_empty: - if (nfa_accept_state_p(s)) - break; if (s->e.trans0 && s->e.trans1) { ps0 = &s->e.trans0; ps1 = &s->e.trans1; @@ -1159,6 +1156,10 @@ static void nfa_thread_epsilons(nfa_state_t **ps, unsigned visited) *ps = 0; } break; + case nfa_accept: + ps0 = &s->e.trans0; + ps1 = &s->e.trans1; + break; case nfa_single: case nfa_wild: case nfa_set: @@ -1185,12 +1186,12 @@ static void nfa_fold_accept(nfa_state_t *s, mem_t *ctx) nfa_state_t *e1 = s->e.trans1; if (e0 && nfa_accept_state_p(e0)) { - s->e.accept = 1; + s->a.kind = nfa_accept; s->e.trans0 = 0; } if (e1 && nfa_accept_state_p(e1)) { - s->e.accept = 1; + s->a.kind = nfa_accept; s->e.trans1 = 0; } } @@ -1274,7 +1275,7 @@ static int nfa_closure(nfa_state_t **stack, nfa_state_t **set, int nin, /* Only states of type nfa_empty are interesting. Each such state at most two epsilon transitions. */ - if (top->a.kind == nfa_empty) { + if (nfa_empty_state_p(top)) { nfa_state_t *e0 = top->e.trans0; nfa_state_t *e1 = top->e.trans1; @@ -1362,7 +1363,7 @@ static int nfa_move_closure(nfa_state_t **stack, nfa_state_t **set, int nin, /* Only states of type nfa_empty are interesting. Each such state at most two epsilon transitions. */ - if (top->a.kind == nfa_empty) { + if (nfa_empty_state_p(top)) { nfa_state_t *e0 = top->e.trans0; nfa_state_t *e1 = top->e.trans1; |