dfa_matrix.h

00001 
00002 #include <cassert>
00003 
00004 /*
00005  * ASTL - the Automaton Standard Template Library.
00006  * C++ generic components for Finite State Automata handling.
00007  * Copyright (C) 2000-2003 Vincent Le Maout (vincent.lemaout@chello.fr).
00008  *
00009  * This library is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2.1 of the License, or (at your option) any later version.
00013  *
00014  * This library is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Lesser General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public
00020  * License along with this library; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022  *
00023  */
00024 
00025 #ifndef ASTL_DFA_MATRIX_H
00026 #define ASTL_DFA_MATRIX_H
00027 
00028 
00029 #include <dfa_base.h>
00030 #include <iterator>   // iterator_tag
00031 #include <functional> // less<>
00032 #include <utility>    // pair<>
00033 #include <vector>
00034 #include <iostream>
00035 
00036 using namespace std;
00037 
00038 namespace astl {
00039 
00040   // g++ 3.2.2 & VC++ bug workaround
00041   // g++ 3.2.2 sees matrix_line as a variably modified type
00042   // VC++ sees unsigned int v[Sigma::size] as a zero-length array (??)
00043 #if (_MSC_VER) || ((__GNUG__ == 3) && (__GNUC_MINOR__ == 2) && (__GNUC_PATCHLEVEL__ == 2))
00044 #define MATRIX_PATCH
00045 #endif
00046 
00047   template <typename Sigma, typename State>
00048   class matrix_line
00049   {
00050   public:
00051     unsigned int size_;//    a count of the outgoing transitions
00052 #ifdef MATRIX_PATCH
00053     State *v;
00054 #else
00055     State v[Sigma::size];
00056 #endif
00057 
00058     typedef matrix_line self;
00059 
00060     matrix_line() : size_(0) {
00061 #ifdef MATRIX_PATCH
00062       v = new State[Sigma::size];
00063 #endif
00064       memset(v, 0, Sigma::size * sizeof(State));
00065 
00066     }
00067 
00068 #ifdef MATRIX_PATCH
00069     ~matrix_line() {
00070       delete [] v;
00071     }
00072 #endif
00073 
00074     matrix_line(const self &x)
00075       : size_(x.size_) {
00076 #ifdef MATRIX_PATCH
00077       v = new State[Sigma::size];
00078 #endif
00079       memcpy(v, x.v, Sigma::size * sizeof(State));
00080     }
00081 
00082     self& operator=(const self &x) {
00083       size_ = x.size_;
00084       memcpy(v, x.v, Sigma::size * sizeof(State));
00085       return (*this);
00086     }
00087 
00088     bool operator==(const self &x) const {
00089       return size_ == x.size_ && equal(v, v + Sigma::size, x.v);
00090     }
00091 
00092     size_t size() const {
00093       return size_;
00094     }
00095 
00096     unsigned int& size() {
00097       return size_;
00098     }
00099   };
00100 
00122   template <class CharTraits = plain,
00123             class Tag        = empty_tag,
00124             class StateType  = unsigned int>
00125   class DFA_matrix_base : public DFA_base<CharTraits, Tag, matrix_line<CharTraits, StateType>, StateType>
00126   {
00127   public:
00128     typedef DFA_base<CharTraits, Tag, matrix_line<CharTraits, StateType>, StateType> super;
00129     typedef CharTraits                                                    char_traits;
00130     typedef Tag                                                           tag_type;
00131     typedef typename CharTraits::char_type                                char_type;
00132     typedef unsigned int                                                  state_type;
00133     typedef DFA_matrix_base<CharTraits, Tag, StateType>                   self;
00134     using super::null_state;
00135 
00136     class edges_type
00137     {
00138     protected:
00139       typedef matrix_line<char_traits, StateType> Container;
00140       const Container *container;
00141 
00142     public:
00143       typedef char_type                         key_type;
00144       typedef state_type                        data_type;
00145       typedef pair<const char_type, state_type> value_type;
00146 
00147       struct key_compare : public binary_function<key_type, key_type, bool>
00148       {
00149         bool operator()(const key_type &x, const key_type &y) const {
00150           return char_traits::to_int_type(x) < char_traits::to_int_type(y);
00151         }
00152       };
00153 
00154       struct value_compare : public binary_function<value_type, value_type, bool>
00155       {
00156         bool operator()(const value_type &x, const value_type &y) const {
00157           return char_traits::to_int_type(x.first) <
00158             char_traits::to_int_type(y.first);
00159         }
00160       };
00161       typedef const value_type& const_reference;
00162       typedef int               difference_type;
00163 
00164       typedef typename super::char_traits::int_type    size_type;
00165 
00166       class const_iterator
00167         : public iterator<bidirectional_iterator_tag, value_type>
00168       {
00169         friend class edges_type;
00170         typedef const_iterator self;
00171 
00172       protected:
00173         const state_type *i;
00174         const Container *c;
00175 
00176         const_iterator(const state_type *_i, const Container *_c)
00177           : i(_i), c(_c)
00178         { }
00179 
00180       public:
00181         const_iterator()
00182         { }
00183 
00184         bool operator== (const self& x) const {
00185           return x.i == i;
00186         }
00187 
00188         bool operator!= (const self& x) const {
00189           return !(*this == x);
00190         }
00191 
00192         typename const_iterator::value_type operator* () const {
00193           return make_pair(DFA_matrix_base<CharTraits, Tag>::char_traits::to_char_type(i - c->v), *i);
00194         }
00195 
00196         self& operator ++ ()
00197         {
00198           for(++i; i != (c->v + DFA_matrix_base<CharTraits, Tag>::char_traits::size) && *i == 0; ++i);
00199           return *this;
00200         }
00201 
00202         self operator ++ (int)
00203         {
00204           const_iterator tmp = *this;
00205           ++(*this);
00206           return tmp;
00207         }
00208 
00209         self& operator -- ()
00210         {
00211           for(--i; *i == 0; --i);
00212           return *this;
00213         }
00214 
00215         self operator -- (int)
00216         {
00217           const_iterator tmp = *this;
00218           --(*this);
00219           return tmp;
00220         }
00221       };
00222 
00223       typedef reverse_iterator<const_iterator> const_reverse_iterator;
00224 
00225       // allocation/deallocation:
00226       edges_type(const Container *c = NULL)
00227         : container(c) { }
00228 
00229       const_iterator begin() const {
00230         const_iterator result(container->v, container);
00231         if (*(result.i) == 0)
00232           ++result;
00233         return result;
00234       }
00235 
00236       const_iterator end() const {
00237         const_iterator result(container->v + self::char_traits::size, container);
00238         return result;
00239       }
00240 
00241       const_reverse_iterator rbegin() const {
00242         return const_reverse_iterator(end());
00243       }
00244 
00245       const_reverse_iterator rend() const {
00246         return const_reverse_iterator(begin());
00247       }
00248 
00249       bool empty() const {
00250         return size() == 0;
00251       }
00252 
00253       size_type size() const {
00254         return container->size();
00255       }
00256 
00257       size_type max_size() const {
00258         return char_traits::size;
00259       }
00260 
00261       // map operations:
00262       key_compare key_comp() const {
00263         return key_compare();
00264       }
00265 
00266       value_compare value_comp() const {
00267         return value_compare();
00268       }
00269 
00270       const_iterator find(const key_type& x) const {
00271         if (container->v[char_traits::to_int_type(x)] == 0)
00272           return end();
00273         else
00274           return const_iterator(container->v + char_traits::to_int_type(x),
00275                                 container);
00276       }
00277 
00278       size_type count(const key_type& x) const {
00279         return container->v[char_traits::to_int_type(x)] == 0 ? 0 : 1;
00280       }
00281 
00282       // comparison:
00283       friend bool operator==(const edges_type& x, const edges_type& y) {
00284         return x.container == y.container || *x.container == *y.container;
00285       }
00286 
00287       const_iterator lower_bound(const key_type &k) const {
00288         return find(k);
00289       }
00290 
00291       const_iterator upper_bound(const key_type &k) const {
00292         const_iterator i = find(k);
00293         return i == end() ? i : ++i;
00294       }
00295 
00296       pair<const_iterator, const_iterator> equal_range(const key_type &k) const {
00297         const_iterator i = find(k);
00298         return i == end() ? make_pair(i, i) : make_pair(i, ++i);
00299       }
00300     };
00301 
00302     // Backward compatibility
00303     typedef edges_type Edges;
00304 
00305     void del_trans(state_type s, const char_type &l)
00306     {
00307       Q[s]->edges().v[char_traits::to_int_type(l)] = 0;
00308       --Q[s]->edges().size();
00309       --trans_count_;
00310     }
00311 
00312     void change_trans(state_type s, const char_type &l, state_type new_aim) {
00313       Q[s]->edges().v[char_traits::to_int_type(l)] = new_aim;
00314     }
00315 
00316     state_type delta1(state_type s, const char_type &l) const {
00317       return Q[s]->edges().v[super::char_traits::to_int_type(l)];
00318     }
00319 
00320     void set_trans(state_type s, const char_type &l, state_type aim)
00321     {
00322       Q[s]->edges().v[super::char_traits::to_int_type(l)] = aim;
00323       ++Q[s]->edges().size();
00324       ++trans_count_;
00325     }
00326 
00327     edges_type delta2(state_type s) const {
00328       return edges_type(&(Q[s]->edges()));
00329     }
00330 
00331     DFA_matrix_base(unsigned long n = 0)
00332       : super(n)
00333     { }
00334 
00335   protected:
00336     using super::Q;
00337     using super::trans_count_;
00338   };
00339 
00340   template <class CharTraits = plain,
00341             class Tag        = empty_tag>
00342   class DFA_matrix : public DFA_matrix_base<CharTraits, Tag, unsigned int>
00343   {
00344   public:
00345     typedef DFA_matrix_base<CharTraits, Tag, unsigned int> super;
00346     typedef typename super::char_traits                          char_traits;
00347     typedef typename super::tag_type                             tag_type;
00348     typedef typename super::char_type                            char_type;
00349     typedef typename super::state_type                           state_type;
00350     typedef DFA_matrix<CharTraits, Tag>      self;
00351     // using super::null_state;
00352 
00353     DFA_matrix(unsigned long n = 0)
00354       : super(n)
00355     { }
00356   };
00357 
00358   template <class CharTraits = plain,
00359             class Tag        = empty_tag>
00360   class DFA_matrix_mini : public DFA_matrix_base<CharTraits, Tag, unsigned short>
00361   {
00362   public:
00363     typedef DFA_matrix_base<CharTraits, Tag, unsigned short> super;
00364     typedef typename super::char_traits                          char_traits;
00365     typedef typename super::tag_type                             tag_type;
00366     typedef typename super::char_type                            char_type;
00367     typedef typename super::state_type                           state_type;
00368     typedef DFA_matrix_mini<CharTraits, Tag>      self;
00369     // using super::null_state;
00370 
00371     DFA_matrix_mini(unsigned long n = 0)
00372       : super(n)
00373     { }
00374   };
00375 
00376 } // namespace astl
00377 
00378 #endif  // ASTL_DFA_MATRIX_H
00379 
00380 
00381 
00382 
00383 

Generated on Sun Mar 8 02:41:33 2009 for ASTL by  doxygen 1.5.7.1