RPA Toolkit
Merge branch 'master' of ssh://git.rpatk.net/git/rpatk
[rpatk.git] / tests / testrex / main.c
1 #include <stdio.h>
2 #include <string.h>
3
4 #include "rlib/rutf.h"
5 #include "rlib/rarray.h"
6 #include "rlib/rmem.h"
7 #include "rex/rexdb.h"
8 #include "rex/rexstate.h"
9 #include "rex/rexnfasimulator.h"
10 #include "rex/rexcompiler.h"
11 #include "rex/rexdfaconv.h"
12
13
14 static void init_ababb(rexdb_t *nfa)
15 {
16         rexstate_t *s0 = rex_state_create(0, REX_STATETYPE_START);
17         rexstate_t *s1 = rex_state_create(1, REX_STATETYPE_NONE);
18         rexstate_t *s2 = rex_state_create(2, REX_STATETYPE_NONE);
19         rexstate_t *s3 = rex_state_create(3, REX_STATETYPE_NONE);
20         rexstate_t *s4 = rex_state_create(4, REX_STATETYPE_NONE);
21         rexstate_t *s5 = rex_state_create(5, REX_STATETYPE_NONE);
22         rexstate_t *s6 = rex_state_create(6, REX_STATETYPE_NONE);
23         rexstate_t *s7 = rex_state_create(7, REX_STATETYPE_NONE);
24         rexstate_t *s8 = rex_state_create(8, REX_STATETYPE_NONE);
25         rexstate_t *s9 = rex_state_create(9, REX_STATETYPE_NONE);
26         rexstate_t *s10 = rex_state_create(10, REX_STATETYPE_ACCEPT);
27
28         rex_db_insertstate(nfa, s0);
29         rex_db_insertstate(nfa, s1);
30         rex_db_insertstate(nfa, s2);
31         rex_db_insertstate(nfa, s3);
32         rex_db_insertstate(nfa, s4);
33         rex_db_insertstate(nfa, s5);
34         rex_db_insertstate(nfa, s6);
35         rex_db_insertstate(nfa, s7);
36         rex_db_insertstate(nfa, s8);
37         rex_db_insertstate(nfa, s9);
38         rex_db_insertstate(nfa, s10);
39
40         rex_state_addtransition_e_dst(s0, s1);
41         rex_state_addtransition_e_dst(s0, s7);
42         rex_state_addtransition_e_dst(s1, s2);
43         rex_state_addtransition_e_dst(s1, s4);
44         rex_state_addtransition_e_dst(s3, s6);
45         rex_state_addtransition_e_dst(s6, s1);
46         rex_state_addtransition_e_dst(s5, s6);
47         rex_state_addtransition_e_dst(s6, s7);
48
49         rex_state_addtransition_dst(s2, 'a', 'a', s3);
50         rex_state_addtransition_dst(s4, 'b', 'b', s5);
51         rex_state_addtransition_dst(s7, 'a', 'a', s8);
52         rex_state_addtransition_dst(s8, 'b', 'b', s9);
53         rex_state_addtransition_dst(s9, 'b', 'b', s10);
54
55 }
56
57
58 static void init_s4(rexdb_t *nfa)
59 {
60         rexstate_t *s0 = rex_state_create(0, REX_STATETYPE_NONE);       /* Dummy state, not used */
61         rexstate_t *s1 = rex_state_create(1, REX_STATETYPE_START);
62         rexstate_t *s2 = rex_state_create(2, REX_STATETYPE_NONE);
63         rexstate_t *s3 = rex_state_create(3, REX_STATETYPE_ACCEPT);
64         rexstate_t *s4 = rex_state_create(4, REX_STATETYPE_NONE);
65
66         rex_db_insertstate(nfa, s0);
67         rex_db_insertstate(nfa, s1);
68         rex_db_insertstate(nfa, s2);
69         rex_db_insertstate(nfa, s3);
70         rex_db_insertstate(nfa, s4);
71
72         rex_state_addtransition_e_dst(s2, s1);
73         rex_state_addtransition_e_dst(s4, s3);
74
75         rex_state_addtransition_dst(s1, 'a', 'a', s2);
76         rex_state_addtransition_dst(s2, 'b', 'b', s3);
77         rex_state_addtransition_dst(s3, 'a', 'a', s2);
78         rex_state_addtransition_dst(s1, 'c', 'c', s4);
79         rex_state_addtransition_dst(s4, 'c', 'c', s3);
80 }
81
82
83 int main(int argc, char *argv[])
84 {
85         int i;
86         long startstate = -1;
87         const char *ptr, *in, *end;
88         const char *name;
89         rex_nfasimulator_t *si = rex_nfasimulator_create();
90         rexdb_t *nfa = rex_db_create(REXDB_TYPE_NFA);
91
92
93         for (i = 1; i < argc; i++) {
94                 if (strcmp(argv[i], "-e") == 0) {
95                         if (++i < argc) {
96                                 name = argv[i];
97                         }
98                         if (++i < argc) {
99                                 startstate = rex_db_addexpression_s(nfa, startstate, argv[i], (rexuserdata_t)name);
100                         }
101                 } else if (strcmp(argv[i], "-D") == 0) {
102                         size_t j;
103                         for (j = 0; j < r_array_length(nfa->states); j++) {
104                                 rex_db_dumpstate(nfa, j);
105                         }
106                 } else if (strcmp(argv[i], "-d") == 0) {
107                         size_t j;
108                         rexdb_t *dfadb = rex_db_createdfa(nfa, 1);
109                         rexdfa_t *dfa = rex_db_todfa(dfadb, 1);
110                         for (j = 0; j < dfa->nstates; j++) {
111                                 rex_dfa_dumpstate(dfa, j);
112                         }
113                         rex_dfa_destroy(dfa);
114                         rex_db_destroy(dfadb);
115                 } else if (strcmp(argv[i], "-ababb") == 0) {
116                         init_ababb(nfa);
117                         startstate = 0;
118                 } else if (strcmp(argv[i], "-s4") == 0) {
119                         init_s4(nfa);
120                         startstate = 1;
121                 } else {
122                         if (startstate < 0)
123                                 return 1;
124                         ptr = in = argv[i];
125                         end = in + strlen(in);
126                         rex_nfasimulator_run(si, nfa, startstate, in, strlen(in));
127                         if (r_array_length(si->accepts)) {
128                                 rex_accept_t *acc = (rex_accept_t *)r_array_lastslot(si->accepts);
129                                 rexstate_t *s = acc->state;
130                                 if (s->userdata)
131                                         fprintf(stdout, "%s: ", (const char*)s->userdata);
132                                 fwrite(in, 1, acc->inputsize, stdout);
133                                 fprintf(stdout, "\n");
134                         }
135                 }
136         }
137         rex_db_destroy(nfa);
138         rex_nfasimulator_destroy(si);
139         fprintf(stdout, "memory: %ld KB (leaked %ld Bytes)\n", (long)r_debug_get_maxmem()/1000, (long)r_debug_get_allocmem());
140         return 0;
141 }