dump_visitor.hxx

00001 // dump_visitor.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008 The Vaucanson Group.
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 //
00012 // The complete GNU General Public Licence Notice can be found as the
00013 // `COPYING' file in the root directory.
00014 //
00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
00016 //
00017 #ifndef VCSN_ALGEBRA_IMPLEMENTATION_SERIES_RAT_DUMP_VISITOR_HXX
00018 # define VCSN_ALGEBRA_IMPLEMENTATION_SERIES_RAT_DUMP_VISITOR_HXX
00019 
00020 # include <vaucanson/algebra/concept/letter.hh>
00021 # include <vaucanson/algebra/implementation/series/rat/dump_visitor.hh>
00022 # include <vaucanson/algebra/implementation/series/rat/nodes.hh>
00023 
00024 # include <vaucanson/misc/escaper.hh>
00025 # include <iostream>
00026 
00027 namespace vcsn {
00028 
00029   namespace rat {
00030 
00032 
00033 
00035     inline
00036     int
00037     print_mode()
00038     {
00039       static const int idx = std::ios::xalloc();
00040       return idx;
00041     }
00042 
00044     inline
00045     int
00046     zero()
00047     {
00048       static const int idx = std::ios::xalloc();
00049       return idx;
00050     }
00051 
00053     inline
00054     int
00055     id()
00056     {
00057       static const int idx = std::ios::xalloc();
00058       return idx;
00059     }
00060 
00062 
00063     /*------------.
00064     | DumpVisitor |
00065     `------------*/
00066 
00067     template <class Word, class Weight>
00068     class DumpVisitor : public ConstNodeVisitor<Word, Weight>
00069     {
00070     public:
00071 
00072       typedef Word                      monoid_elt_value_t;
00073       typedef Weight                    semiring_elt_value_t;
00074       typedef Node<Word, Weight>        node_t;
00075 
00076     public:
00077 
00078       DumpVisitor(std::ostream& ostr = std::cout)
00079         : ostr_ (ostr)
00080       {
00081         if (not ostr_.pword(rat::zero()))
00082           ostr_ << setzero(algebra::letter_traits<typename Word::value_type>::default_zero());
00083 
00084         if (not ostr_.pword(rat::id()))
00085           ostr_ << setid(algebra::letter_traits<typename Word::value_type>::default_epsilon());
00086       }
00087 
00088       virtual
00089       ~DumpVisitor()
00090       {
00091         ostr_.flush();
00092       }
00093 
00094     protected:
00095 
00096       void
00097       enclose_if(const bool cond, const node_t* node)
00098       {
00099         if (cond)
00100           {
00101             ostr_ << "(";
00102             node->accept(*this);
00103             ostr_ << ")";
00104           }
00105         else
00106           node->accept(*this);
00107       }
00108 
00109       enum
00110         {
00111           NODE_LWEIGHT  = Node<Word, Weight>::lweight,
00112           NODE_RWEIGHT  = Node<Word, Weight>::rweight,
00113           NODE_PROD     = Node<Word, Weight>::prod,
00114           NODE_SUM      = Node<Word, Weight>::sum,
00115         };
00116 
00117       void
00118       product_print_child(const node_t* child)
00119       {
00120         switch(child->what())
00121           {
00122           case NODE_SUM:
00123             // If MODE_SUM is already set, there is no need to enclose the
00124             // child, since it will be done in sum().
00125             enclose_if(not (ostr_.iword(print_mode()) & MODE_ADD), child);
00126             break;
00127           default:
00128             child->accept(*this);
00129             break;
00130           }
00131       }
00132 
00133     public:
00134 
00135       virtual
00136       void
00137       product(const node_t* lhs, const node_t* rhs)
00138       {
00139         const long verbose = ostr_.iword(print_mode()) & MODE_MUL;
00140 
00141         if (verbose)
00142           ostr_ << "(";
00143 
00144         product_print_child(lhs);
00145         ostr_ << ".";
00146         product_print_child(rhs);
00147 
00148         if (verbose)
00149           ostr_ << ")";
00150       }
00151 
00152       virtual
00153       void
00154       sum(const node_t* lhs, const node_t* rhs)
00155       {
00156         const long verbose = ostr_.iword(print_mode()) & MODE_ADD;
00157 
00158         if (verbose)
00159           ostr_ << "(";
00160 
00161         lhs->accept(*this);
00162         ostr_ << "+";
00163         rhs->accept(*this);
00164 
00165         if (verbose)
00166           ostr_ << ")";
00167       }
00168 
00169       virtual
00170       void
00171       star(const node_t* node)
00172       {
00173         const long      mode = ostr_.iword(print_mode());
00174         const unsigned  node_type = node->what();
00175 
00176         switch (node_type)
00177           {
00178           case NODE_SUM:
00179             enclose_if(not (mode & MODE_ADD), node);
00180             break;
00181           case NODE_PROD:
00182             enclose_if(not (mode & MODE_MUL), node);
00183             break;
00184           case NODE_LWEIGHT:
00185             enclose_if(not (mode & MODE_LWEIGHT), node);
00186             break;
00187           case NODE_RWEIGHT:
00188             enclose_if(not (mode & MODE_RWEIGHT), node);
00189             break;
00190           default:
00191             enclose_if(mode & MODE_STAR, node);
00192             break;
00193           }
00194         ostr_ << "*";
00195       }
00196 
00197       virtual
00198       void
00199       left_weight(const semiring_elt_value_t& w, const node_t* node)
00200       {
00201         const long      mode = ostr_.iword(print_mode());
00202         const unsigned  node_type = node->what();
00203         long            verbose;
00204         bool            enclose_all (false);
00205 
00206         switch (node_type)
00207           {
00208           case NODE_PROD:
00209             verbose = not (mode & MODE_MUL);
00210             break;
00211           case NODE_SUM:
00212             verbose = not (mode & MODE_ADD);
00213             break;
00214           case NODE_LWEIGHT:
00215             verbose = not (mode & MODE_LWEIGHT);
00216             break;
00217           case NODE_RWEIGHT:
00218             verbose = not (mode & MODE_RWEIGHT);
00219             break;
00220           default:
00221             verbose = false;
00222             enclose_all = mode & MODE_LWEIGHT;
00223             break;
00224           }
00225 
00226         if (enclose_all)
00227           ostr_ << "(";
00228 
00229         ostr_ << "{" << w << "} ";
00230         enclose_if(verbose, node);
00231 
00232         if (enclose_all)
00233           ostr_ << ")";
00234       }
00235 
00236       virtual
00237       void
00238       right_weight(const semiring_elt_value_t& w, const node_t* node)
00239       {
00240         const long      mode = ostr_.iword(print_mode());
00241         const unsigned  node_type = node->what();
00242         long            verbose;
00243         bool            enclose_all (false);
00244 
00245         switch (node_type)
00246           {
00247           case NODE_PROD:
00248             verbose = not (mode & MODE_MUL);
00249             break;
00250           case NODE_SUM:
00251             verbose = not (mode & MODE_ADD);
00252             break;
00253           case NODE_LWEIGHT:
00254             verbose = not (mode & MODE_LWEIGHT);
00255             break;
00256           case NODE_RWEIGHT:
00257             verbose = not (mode & MODE_RWEIGHT);
00258             break;
00259           default:
00260             verbose = false;
00261             enclose_all = mode & MODE_RWEIGHT;
00262             break;
00263           }
00264 
00265         if (enclose_all)
00266           ostr_ << "(";
00267 
00268         enclose_if(verbose, node);
00269         ostr_ << " {" << w << "}";
00270 
00271         if (enclose_all)
00272           ostr_ << ")";
00273       }
00274 
00275       virtual
00276       void
00277       constant(const monoid_elt_value_t& m)
00278       {
00279         ostr_ << m;
00280       }
00281 
00282       virtual
00283       void
00284       zero()
00285       {
00286         ostr_ << *static_cast<const std::string*> (ostr_.pword(rat::zero()));
00287       }
00288 
00289       virtual
00290       void
00291       one()
00292       {
00293         ostr_ << *static_cast<const std::string*> (ostr_.pword(id()));
00294       }
00295 
00296     protected:
00297       std::ostream&     ostr_;
00298     };
00299 
00300     /*------------.
00301     | operator << |
00302     `------------*/
00303 
00304     template <class Word, class Weight>
00305     std::ostream&
00306     operator << (std::ostream& ostr, const exp<Word, Weight>& e)
00307     {
00308       DumpVisitor<Word, Weight> v (ostr);
00309       e.accept(v);
00310       return ostr;
00311     }
00312 
00313     /*------.
00314     | setpm |
00315     `------*/
00316 
00317     inline
00318     setpm::setpm(print_mode_t mode) : mode_ (mode)
00319     {
00320     }
00321 
00322     inline
00323     std::ostream&
00324     setpm::operator () (std::ostream& ostr) const
00325     {
00326       ostr.iword(print_mode()) = mode_;
00327       return ostr;
00328     }
00329 
00330     /*------.
00331     | getpm |
00332     `------*/
00333 
00334     inline
00335     print_mode_t
00336     getpm(std::ostream& ostr)
00337     {
00338       return print_mode_t (ostr.iword(print_mode()));
00339     }
00340 
00341     /*--------.
00342     | setzero |
00343     `--------*/
00344 
00345     inline
00346     setzero::setzero(const std::string& zero) : z_ (zero)
00347     {
00348     }
00349 
00350     inline
00351     std::ostream&
00352     setzero::operator () (std::ostream& ostr) const
00353     {
00354       const int idx = zero();
00355 
00356       if (not ostr.pword(idx))
00357         ostr.register_callback(misc::pword_delete<std::string>, idx);
00358       else
00359         delete static_cast<std::string*> (ostr.pword(idx));
00360       ostr.pword(idx) = new std::string (z_);
00361       return ostr;
00362     }
00363 
00364     /*------.
00365     | setid |
00366     `------*/
00367 
00368     inline
00369     setid::setid(const std::string& id) : i_ (id)
00370     {
00371     }
00372 
00373     inline
00374     std::ostream&
00375     setid::operator () (std::ostream& ostr) const
00376     {
00377       const int idx = id();
00378 
00379       if (not ostr.pword(idx))
00380         ostr.register_callback(misc::pword_delete<std::string>, idx);
00381       else
00382         delete static_cast<std::string*> (ostr.pword(idx));
00383       ostr.pword(idx) = new std::string (i_);
00384       return ostr;
00385     }
00386 
00387   } // rat
00388 
00389 } // vcsn
00390 
00391 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SERIES_RAT_DUMP_VISITOR_HXX

Generated on Thu Oct 9 20:22:34 2008 for Vaucanson by  doxygen 1.5.1