2 * Regular Pattern Analyzer Toolkit (RPA/Tk)
3 * Copyright (c) 2009-2012 Martin Stoilov
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 * Martin Stoilov <martin@rpasearch.com>
24 #include "rlib/rmem.h"
25 #include "rlib/rstring.h"
26 #include "rex/rexdfa.h"
29 rexdfa_t *rex_dfa_create(rexuint_t nstates, rexuint_t ntrans, rexuint_t naccsubstates, rexuint_t nsubstates)
31 rexdfa_t *dfa = (rexdfa_t *)r_zmalloc(sizeof(*dfa));
32 dfa->states = r_zmalloc(sizeof(rexdfs_t) * nstates);
33 dfa->trans = r_zmalloc(sizeof(rexdft_t) * ntrans);
35 dfa->accsubstates = r_zmalloc(sizeof(rexdfss_t) * naccsubstates);
37 dfa->substates = r_zmalloc(sizeof(rexdfss_t) * nsubstates);
38 dfa->nstates = nstates;
40 dfa->nsubstates = nsubstates;
41 dfa->naccsubstates = naccsubstates;
46 void rex_dfa_destroy(rexdfa_t *dfa)
49 r_free(dfa->substates);
50 r_free(dfa->accsubstates);
58 rexdfs_t *rex_dfa_state(rexdfa_t *dfa, rexuint_t nstate)
61 if (nstate >= dfa->nstates)
63 s = REX_DFA_STATE(dfa, nstate);
68 rexdft_t *rex_dfa_transition(rexdfa_t *dfa, rexuint_t nstate, rexuint_t ntrans)
71 rexdfs_t *s = rex_dfa_state(dfa, nstate);
74 if (ntrans >= s->ntrans)
76 t = REX_DFA_TRANSITION(dfa, nstate, ntrans);
81 rexdfss_t *rex_dfa_substate(rexdfa_t *dfa, rexuint_t nstate, rexuint_t nsubstate)
84 rexdfs_t *s = rex_dfa_state(dfa, nstate);
87 if (nsubstate >= s->nsubstates)
89 ss = REX_DFA_SUBSTATE(dfa, nstate, nsubstate);
94 rexdfss_t *rex_dfa_accsubstate(rexdfa_t *dfa, rexuint_t nstate, rexuint_t naccsubstate)
97 rexdfs_t *s = rex_dfa_state(dfa, nstate);
100 if (naccsubstate >= s->naccsubstates)
102 ss = REX_DFA_ACCSUBSTATE(dfa, nstate, naccsubstate);
107 rexuint_t rex_dfa_next(rexdfa_t *dfa, rexuint_t nstate, rexchar_t input)
109 rexuint_t newstate = 0;
110 REX_DFA_NEXT(dfa, nstate, input, &newstate);
115 void rex_dfa_dumpstate(rexdfa_t *dfa, rexuint_t nstate)
119 int bufsize = sizeof(buf) - 1;
121 rexdfs_t *s = rex_dfa_state(dfa, nstate);
122 rexdfss_t *ss = NULL;
127 fprintf(stdout, "State %ld", (unsigned long)nstate);
128 fprintf(stdout, " (");
129 for (index = 0; index < s->nsubstates; index++) {
130 ss = REX_DFA_SUBSTATE(dfa, nstate, index);
132 fprintf(stdout, "%ld", (unsigned long)ss->uid);
133 if (ss->type == REX_STATETYPE_ACCEPT)
134 fprintf(stdout, "*");
135 if (index + 1 < s->nsubstates)
136 fprintf(stdout, ",");
139 fprintf(stdout, ")");
142 fprintf(stdout, ": ");
143 if (s->type == REX_STATETYPE_ACCEPT) {
144 fprintf(stdout, " REX_STATETYPE_ACCEPT ");
145 fprintf(stdout, " (");
146 for (index = 0; index < s->naccsubstates; index++) {
147 ss = REX_DFA_ACCSUBSTATE(dfa, nstate, index);
149 fprintf(stdout, "%ld*", (unsigned long)ss->uid);
150 if (index + 1 < s->naccsubstates)
151 fprintf(stdout, ",");
154 fprintf(stdout, ")");
155 } else if (s->type == REX_STATETYPE_DEAD) {
156 fprintf(stdout, " REX_STATETYPE_DEAD ");
157 } else if (s->type == REX_STATETYPE_START) {
158 fprintf(stdout, " REX_STATETYPE_START ");
160 fprintf(stdout, "\n");
161 for (index = 0; index < s->ntrans; index++) {
162 t = &dfa->trans[s->trans + index];
164 if (t->lowin != t->highin) {
165 if (isprint(t->lowin) && !isspace(t->lowin) && isprint(t->highin) && !isspace(t->highin) && !r_strchr("[]-^", t->lowin) && !r_strchr("[]-^", t->highin))
166 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, " [%c - %c] ", t->lowin, t->highin);
168 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, " [0x%X - 0x%X] ", t->lowin, t->highin);
170 if (isprint(t->lowin) && !isspace(t->lowin))
171 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, " '%c' ", t->lowin);
173 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, " 0x%X ", t->lowin);
175 r_memset(buf + n, ' ', bufsize - n);
177 n += r_snprintf(buf + n, n < bufsize ? bufsize - n : 0, "-> %ld", t->state);
178 fprintf(stdout, "%s\n", buf);
181 fprintf(stdout, " (none)\n");
182 fprintf(stdout, "\n");