00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef ASTL_NFA_MMAP_H
00027 #define ASTL_NFA_MMAP_H
00028
00029 #include <set>
00030 #include <map>
00031 #include <algorithm>
00032 #include <utility>
00033 #include <astl.h>
00034
00035 #if (__GNUG__ && __GNUG__ > 2)
00036 using namespace __gnu_cxx;
00037 #endif
00038
00039 using namespace std;
00040
00041 namespace astl {
00042
00043 template <class CharTraits>
00044 struct nfa_mmap_key_compare
00045 : public binary_function<typename CharTraits::char_type,
00046 typename CharTraits::char_type, bool>
00047 {
00048 bool operator()(const typename CharTraits::char_type &x,
00049 const typename CharTraits::char_type &y) const {
00050 return CharTraits::lt(x, y);
00051 }
00052 };
00053
00054 template <typename State, typename CharTraits, typename Tag>
00055 struct nfa_mmap_state_data
00056 {
00057 Tag t;
00058 multimap<typename CharTraits::char_type, State,
00059 nfa_mmap_key_compare<CharTraits> > edges;
00060 };
00061
00062
00063
00064 template <typename State, typename CharTraits>
00065 struct nfa_mmap_state_data<State, CharTraits, empty_tag>
00066 {
00067 static empty_tag t;
00068 multimap<typename CharTraits::char_type, State,
00069 nfa_mmap_key_compare<CharTraits> > edges;
00070 };
00071
00072 template <class State, class Alphabet>
00073 empty_tag nfa_mmap_state_data<State, Alphabet, empty_tag>::t;
00074
00075
00076 template <class _Sigma = plain,
00077 class _Tag = empty_tag>
00078 class NFA_mmap : public NFA_concept
00079 {
00080 public:
00081 typedef _Sigma char_traits;
00082 typedef typename _Sigma::char_type char_type;
00083 typedef _Tag tag_type;
00084 typedef unsigned int state_type;
00085
00086
00087 typedef char_type Alphabet;
00088 typedef char_traits Sigma;
00089 typedef tag_type Tag;
00090 typedef state_type State;
00091
00092 protected:
00093 typedef multimap<char_type, state_type,
00094 nfa_mmap_key_compare<char_traits> > transition_container;
00095 typedef vector<char> set_F;
00096 typedef nfa_mmap_state_data<state_type, char_traits, tag_type> state_data;
00097
00098
00099 state_type new_state(const state_data &x) {
00100 Q.push_back(new state_data(x));
00101 ++state_count_;
00102 trans_count_ += x.edges.size();
00103 return Q.size() - 1;
00104 }
00105
00106 vector<state_data*> Q;
00107 set<state_type> I;
00108 set_F F;
00109 unsigned long state_count_, trans_count_;
00110
00111 public:
00112 class edges_type
00113 {
00114 friend class NFA_mmap<_Sigma, _Tag>;
00115 protected:
00116 const transition_container *container;
00117
00118 public:
00119 typedef typename transition_container::key_type key_type;
00120 typedef typename transition_container::mapped_type mapped_type;
00121 typedef typename transition_container::mapped_type data_type;
00122 typedef typename transition_container::value_type value_type;
00123 typedef typename transition_container::key_compare key_compare;
00124 typedef typename transition_container::const_reference const_reference;
00125 typedef typename transition_container::size_type size_type;
00126 typedef typename transition_container::difference_type difference_type;
00127 typedef typename transition_container::value_compare value_compare;
00128
00129 typedef typename transition_container::const_iterator const_iterator;
00130 typedef typename transition_container::const_reverse_iterator const_reverse_iterator;
00131
00132
00133
00134 protected:
00135 edges_type(const transition_container *c)
00136 : container(c) { }
00137
00138 public:
00139 edges_type(const edges_type& x) : container(x.container) { }
00140 ~edges_type() { }
00141
00142
00143 key_compare key_comp() const { return container->key_comp(); }
00144 value_compare value_comp() const { return container->value_comp(); }
00145 const_iterator begin() const { return container->begin(); }
00146 const_iterator end() const { return container->end(); }
00147 const_reverse_iterator rbegin() const { return container->rbegin(); }
00148 const_reverse_iterator rend() const { return container->rend(); }
00149 bool empty() const { return container->empty(); }
00150 size_type size() const { return container->size(); }
00151 size_type max_size() const { return container->max_size(); }
00152
00153
00154 const_iterator find(const key_type& x) const { return container->find(x); }
00155 size_type count(const key_type& x) const { return container->count(x); }
00156 const_iterator lower_bound(const key_type& x) const { return container->lower_bound(x); }
00157 const_iterator upper_bound(const key_type& x) const { return container->upper_bound(x); }
00158 pair<const_iterator, const_iterator> equal_range(const key_type& x) const {
00159 return container->equal_range(x);
00160 }
00161
00162
00163 friend bool operator == (const edges_type& x, const edges_type& y) {
00164 return x.container == y.container || *x.container == *y.container;
00165 }
00166 };
00167
00168 typedef skip_blanks_iterator<state_data> const_iterator;
00169
00170
00171 typedef edges_type Edges;
00172
00173 static const state_type null_state = 0;
00174
00175 set<state_type>& initial() {
00176 return I;
00177 }
00178
00179 const set<state_type>& initial() const {
00180 return I;
00181 }
00182
00183 set_F::reference final(state_type s) {
00184 return F[s];
00185 }
00186
00187 bool final(state_type s) const {
00188 return F[s] != '\0';
00189 }
00190
00191 state_type new_state()
00192 {
00193 Q.push_back(new state_data);
00194 ++state_count_;
00195 F.push_back('\0');
00196 return Q.size() - 1;
00197 }
00198
00199 template <class OutputIterator>
00200 OutputIterator new_state(unsigned long how_many, OutputIterator x)
00201 {
00202 for(; how_many > 0; --how_many)
00203 *x++ = new_state();
00204 return (x);
00205 }
00206
00207 void del_state(state_type s)
00208 {
00209 trans_count_ -= Q[s]->edges.size();
00210 delete Q[s];
00211 --state_count_;
00212 Q[s] = NULL;
00213 I.erase(s);
00214 }
00215
00216 void set_trans(state_type s, const char_type &l, state_type aim)
00217 {
00218 Q[s]->edges.insert(make_pair(l, aim));
00219 ++trans_count_;
00220 }
00221
00222 void del_trans(state_type s, const char_type &l) {
00223 trans_count_ -= Q[s]->edges.erase(l);
00224 }
00225
00226 void del_trans(state_type s, const char_type &l, state_type aim)
00227 {
00228 pair<typename multimap<char_type, state_type>::iterator,
00229 typename multimap<char_type, state_type>::iterator>
00230 p = Q[s]->edges.equal_range(l);
00231 for(; p.first != p.second && (*p).second != aim; ++p.first);
00232 Q[s]->edges.erase(p.first);
00233 --trans_count_;
00234 }
00235
00236 void change_trans(state_type s, const char_type &l,
00237 state_type former_aim, state_type new_aim)
00238 {
00239 transition_container &e = Q[s]->edges;
00240 typename transition_container::iterator p = e.find(l);
00241 for(; (*p).second != former_aim; ++p);
00242 (*p).second = new_aim;
00243 }
00244
00245 void copy_state(state_type from, state_type to)
00246 {
00247 trans_count_ += Q[from]->edges.size() - Q[to]->edges.size();
00248 *Q[to] = *Q[from];
00249 F[to] = F[from];
00250 }
00251
00252 template <class OutputIterator>
00253 OutputIterator delta1(state_type s, const char_type &l,
00254 OutputIterator x) const
00255 {
00256 return std::transform(Q[s]->edges.lower_bound(l),
00257 Q[s]->edges.upper_bound(l),
00258 x, select2nd<pair<char_type, state_type> >());
00259 }
00260
00261 state_type duplicate_state(state_type q) {
00262 state_type s = new_state(*Q[q]);
00263 F[s] = F[q];
00264 return s;
00265 }
00266
00267 unsigned long state_count() const {
00268 return state_count_;
00269 }
00270
00271 unsigned long trans_count() const {
00272 return trans_count_;
00273 }
00274
00275 Tag& tag(state_type s) {
00276 return Q[s]->t;
00277 }
00278
00279 const Tag& tag(state_type s) const {
00280 return Q[s]->t;
00281 }
00282
00283 edges_type delta2(state_type s) const {
00284 return edges_type(&Q[s]->edges);
00285 }
00286
00287 const_iterator begin() const {
00288 const_iterator x(&Q, 0);
00289 return ++x;
00290 }
00291
00292 const_iterator end() const {
00293 return const_iterator(&Q, Q.size());
00294 }
00295
00296 NFA_mmap(unsigned long n = 0)
00297 : Q(1, (state_data*) NULL), I(), F(1, '\0'), state_count_(0),
00298 trans_count_(0) {
00299 Q.reserve(n + 1);
00300 }
00301
00302 ~NFA_mmap()
00303 {
00304 const_iterator start, finish = end();
00305 for(start = begin(); start != finish; ++start)
00306 del_state(*start);
00307 }
00308 };
00309
00310 template <typename CharTraits, typename Tag>
00311 const typename NFA_mmap<CharTraits, Tag>::state_type
00312 NFA_mmap<CharTraits, Tag>::null_state;
00313
00314 }
00315
00316 #endif // ASTL_NFA_MMAP_H
00317
00318
00319
00320
00321
00322
00323
00324