Click
Loading...
Searching...
No Matches
simpledfa.hh
1// -*- c-basic-offset: 4 -*-
2#ifndef CLICK_SIMPLEDFA_HH
3#define CLICK_SIMPLEDFA_HH
4
5#include <click/string.hh>
6CLICK_DECLS
7
11class SimpleDFA {
12
13public:
14 const static int _verbose = 0;
15 typedef uint16_t state_t;
16
17 struct NextState {
18 state_t next[256];
19 };
20
21 static const uint16_t MATCHED = (uint16_t)-1;
22
23 SimpleDFA() : vector() {
24 vector.resize(1);
25 }
26
27 typedef NextState StateSet;
28
29 Vector<StateSet> compile(String pattern) {
30 int state = 0;
31 Vector<StateSet> c_pattern;
32 for (int i = 0; i < pattern.length(); i++) {
33 if (c_pattern.size() <= state)
34 c_pattern.resize(state + 1);
35 int next_state;
36 if (i + 1 == pattern.length())
37 next_state = MATCHED;
38 else
39 next_state = state + 1;
40 if (pattern[i] == '\\') {
41 if (pattern[i + 1] == '\\') {
42 i = i + 1;
43 } else {
44 i = i + 1; //Go to the next one and interpret normally
45 }
46 } else if (pattern[i] == '*') { //unescaped
47 for (int j = 0; j < 256; j ++) {
48 if (next_state == MATCHED)
49 c_pattern[state].next[j] = MATCHED;
50 else
51 c_pattern[state].next[j] = state;
52 }
53 //Do not set state = next_state, we will overwrite
54 continue;
55 }
56 c_pattern[state].next[pattern[i]] = next_state;
57 state = next_state;
58 }
59 return c_pattern;
60
61
62 }
63
64 int add_pattern(String pattern) {
65 int prevsz = vector.size();
66
67 if (_verbose)
68 click_chatter("Adding pattern %s",pattern.c_str());
69 Vector<StateSet> c_pattern = compile(pattern);
70 if (_verbose) {
71 click_chatter("Compiled :");
72 print(c_pattern);
73 }
74 int next_state;
75 if (c_pattern.size() > 1) {
76 create_states(c_pattern,prevsz); // Will add all the states at the end of the vector
77 next_state = prevsz - 1;
78 } else {
79 next_state = MATCHED;
80 }
81 for (int j = 0; j < prevsz; j++) { //We now attach the first letter to each possible state
82 attach(c_pattern,j, c_pattern[0], next_state);
83 }
84 if (_verbose) {
85 click_chatter("Final:");
86 print(vector);
87 }
88 return 0;
89 }
90
91 void attach(Vector<StateSet> c_pattern, state_t state, NextState nt, int pos) {
92 for (int j = 0; j < 256; j++) {
93 state_t p = nt.next[j];
94 if (p) {
95 state_t n = vector[state].next[j];
96 if (n == MATCHED)
97 continue;
98 if (p == MATCHED) {
99 vector[state].next[j] = MATCHED;
100 continue;
101 }
102 if (n) {
103 //A T
104 //A *-> 4
105 //click_chatter("%c exists, attaching state %d, to state %d",pattern[l],vector[state].next[pattern[l]],vector[next_state].next[pattern[l + 1]]);
106 //TODO : does not work here if c_pattern is a glob
107 attach(c_pattern, n, c_pattern[nt.next[j]], pos);
108 } else
109 vector[state].next[j] = nt.next[j] + pos;
110 }
111 }
112 }
113
114 void create_states(Vector<StateSet> c_pattern, int place) {
115 int state = place;
116 for (int i = 1; i < c_pattern.size(); i++) {
117 if (vector.size() <= state)
118 vector.resize(state + 1);
119 for (int j = 0; j < 256; j++) {
120 if (c_pattern[i].next[j]) {
121 if (c_pattern[i].next[j] == MATCHED) {
122 vector[state].next[j] = MATCHED;
123 } else {
124 vector[state].next[j] = place - 1 + c_pattern[i].next[j];
125 }
126 }
127 }
128 ++state;
129 }
130 }
131
132 inline void next(const unsigned char& c, state_t &state) {
133 state = vector[state].next[c];
134 }
135
136 inline void next_chunk(const unsigned char*& c, const int& size, state_t &state) {
137 for (int i = 0; i < size; i++) {
138 state = vector[state].next[*(c + i)];
139 if (state == MATCHED)
140 return;
141 }
142 }
143
144 void print(Vector<NextState> v) {
145 for (int i = 0; i < v.size(); i ++) {
146 click_chatter("S%d",i);
147 for (int j = 0 ; j < 256; j ++) {
148 if (v[i].next[j])
149 click_chatter(" %d - %c : %d",j,(char)j, v[i].next[j]);
150 }
151 }
152 }
171private:
172 Vector<NextState> vector;
173
174};
175
176CLICK_ENDDECLS
177
178#endif
Definition simpledfa.hh:11
A string of characters.
Definition string.hh:22
int length() const
Return the string's length.
Definition string.hh:509
const char * c_str() const
Null-terminate the string.
Definition string.hh:519
Vector template.
Definition vector.hh:111
void resize(size_type n, value_argument_type v=T())
Resize the vector to contain n elements.
Definition vector.hh:390
size_type size() const
Return the number of elements.
Definition vector.hh:231
Click's String class.