00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef ASTL_DFA_BASE_H
00023 #define ASTL_DFA_BASE_H
00024
00025
00026
00027
00028
00029 #include <tools.h>
00030 #include <state.h>
00031 #include <vector>
00032
00033 using std::vector;
00034
00035 namespace astl {
00036
00042 template <class CharTraits, class TagType, class StateData_, class StateType = unsigned int>
00043 class DFA_base : public DFA_concept
00044 {
00045 public:
00046 typedef CharTraits char_traits;
00047 typedef TagType tag_type;
00048 typedef typename CharTraits::char_type char_type;
00049 typedef StateType state_type;
00051 protected:
00052 typedef vector<char> set_F;
00053 typedef state_data<tag_type, StateData_> StateData;
00054
00055 vector<StateData*> Q;
00056 state_type I;
00057 set_F F;
00058 unsigned long state_count_;
00059 unsigned long trans_count_;
00060
00061 public:
00062 typedef skip_blanks_iterator<StateData> const_iterator;
00063
00064 static const state_type null_state;
00065
00071 const_iterator begin() const {
00072 const_iterator x(&Q, 0);
00073 return ++x;
00074 }
00075
00079 const_iterator end() const {
00080 return const_iterator(&Q, Q.size());
00081 }
00082
00087 void initial(state_type s) {
00088 I = s;
00089 }
00090
00092 state_type initial() const {
00093 return I;
00094 }
00095
00099 bool final(state_type s) const {
00100 return F[s] != '\0';
00101 }
00102
00108 char& final(state_type s) {
00109 return F[s];
00110 }
00111
00117 state_type new_state() {
00118 Q.push_back(new StateData);
00119 F.push_back('\0');
00120 ++state_count_;
00121 return Q.size() - 1;
00122 }
00123
00124 template <class OutputIterator>
00125 OutputIterator new_state(unsigned long how_many, OutputIterator x)
00126 {
00127 for(; how_many > 0; --how_many)
00128 *x++ = new_state();
00129 return x;
00130 }
00131
00136 void del_state(state_type s)
00137 {
00138 if (s == initial()) initial(null_state);
00139 trans_count_ -= Q[s]->edges().size();
00140 delete Q[s];
00141 Q[s] = NULL;
00142 --state_count_;
00143 }
00144
00151 void copy_state(state_type from, state_type to) {
00152 trans_count_ += Q[from]->edges().size() - Q[to]->edges().size();
00153 *Q[to] = *Q[from];
00154 F[to] = F[from];
00155 }
00156
00161 state_type duplicate_state(state_type q)
00162 {
00163 Q.push_back(new StateData(*Q[q]));
00164 F.push_back(F[q]);
00165 ++state_count_;
00166 trans_count_ += Q[q]->edges().size();
00167 return Q.size() - 1;
00168 }
00169
00171 unsigned long state_count() const {
00172 return state_count_;
00173 }
00174
00176 unsigned long trans_count() const {
00177 return trans_count_;
00178 }
00179
00183 tag_type& tag(state_type s) {
00184 return Q[s]->tag();
00185 }
00186
00190 const tag_type& tag(state_type s) const {
00191 return Q[s]->tag();
00192 }
00193
00194 DFA_base(unsigned long n) :
00195 Q(1, (StateData*) 0), I(0), F(1, '\0'), state_count_(0UL),
00196 trans_count_(0UL) {
00197 Q.reserve(n + 1);
00198 }
00199
00200 ~DFA_base()
00201 {
00202 const_iterator start, finish = end();
00203 for(start = begin(); start != finish; ++start)
00204 del_state(*start);
00205 }
00206 };
00207
00208 template <class CharTraits, class TagType, class StateData_, class StateType>
00209 const typename DFA_base<CharTraits, TagType, StateData_, StateType>::state_type
00210 DFA_base<CharTraits, TagType, StateData_, StateType>::null_state = 0;
00211
00212 }
00213
00214 #endif // ASTL_DFA_BASE_H