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 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/implementation/series/rat/dump_visitor.hh>
00021 # include <vaucanson/algebra/implementation/series/rat/nodes.hh>
00022 
00023 # include <vaucanson/misc/escaper.hh>
00024 
00025 namespace vcsn {
00026 
00027   namespace rat {
00028 
00030 
00031 
00033     inline
00034     int
00035     print_mode()
00036     {
00037       static const int idx = std::ios::xalloc();
00038       return idx;
00039     }
00040 
00042     inline
00043     int
00044     zero()
00045     {
00046       static const int idx = std::ios::xalloc();
00047       return idx;
00048     }
00049 
00051     inline
00052     int
00053     id()
00054     {
00055       static const int idx = std::ios::xalloc();
00056       return idx;
00057     }
00058 
00060 
00061     /*------------.
00062     | DumpVisitor |
00063     `------------*/
00064 
00065     template <class Word, class Weight>
00066     class DumpVisitor : public ConstNodeVisitor<Word, Weight>
00067     {
00068     public:
00069 
00070       typedef Word                      monoid_elt_value_t;
00071       typedef Weight                    semiring_elt_value_t;
00072       typedef Node<Word, Weight>        node_t;
00073 
00074     public:
00075 
00076       DumpVisitor(std::ostream& ostr = std::cout)
00077         : ostr_ (ostr)
00078       {
00079         if (not ostr_.pword(rat::zero()))
00080           ostr_ << setzero ("0");
00081 
00082         if (not ostr_.pword(rat::id()))
00083           ostr_ << setid ("1");
00084       }
00085 
00086       virtual
00087       ~DumpVisitor()
00088       {
00089         ostr_.flush();
00090       }
00091 
00092     protected:
00093 
00094       void
00095       enclose_if(const bool cond, const node_t* node)
00096       {
00097         if (cond)
00098           {
00099             ostr_ << "(";
00100             node->accept(*this);
00101             ostr_ << ")";
00102           }
00103         else
00104           node->accept(*this);
00105       }
00106 
00107       enum
00108         {
00109           NODE_LWEIGHT  = Node<Word, Weight>::lweight,
00110           NODE_RWEIGHT  = Node<Word, Weight>::rweight,
00111           NODE_PROD     = Node<Word, Weight>::prod,
00112           NODE_SUM      = Node<Word, Weight>::sum,
00113         };
00114 
00115       void
00116       product_print_child(const node_t* child)
00117       {
00118         switch(child->what())
00119           {
00120           case NODE_SUM:
00121             // If MODE_SUM is already set, there is no need to enclose the
00122             // child, since it will be done in sum().
00123             enclose_if(not (ostr_.iword(print_mode()) & MODE_ADD), child);
00124             break;
00125           default:
00126             child->accept(*this);
00127             break;
00128           }
00129       }
00130 
00131     public:
00132 
00133       virtual
00134       void
00135       product(const node_t* lhs, const node_t* rhs)
00136       {
00137         const long verbose = ostr_.iword(print_mode()) & MODE_MUL;
00138 
00139         if (verbose)
00140           ostr_ << "(";
00141 
00142         product_print_child(lhs);
00143         ostr_ << ".";
00144         product_print_child(rhs);
00145 
00146         if (verbose)
00147           ostr_ << ")";
00148       }
00149 
00150       virtual
00151       void
00152       sum(const node_t* lhs, const node_t* rhs)
00153       {
00154         const long verbose = ostr_.iword(print_mode()) & MODE_ADD;
00155 
00156         if (verbose)
00157           ostr_ << "(";
00158 
00159         lhs->accept(*this);
00160         ostr_ << "+";
00161         rhs->accept(*this);
00162 
00163         if (verbose)
00164           ostr_ << ")";
00165       }
00166 
00167       virtual
00168       void
00169       star(const node_t* node)
00170       {
00171         const long      mode = ostr_.iword(print_mode());
00172         const unsigned  node_type = node->what();
00173 
00174         switch (node_type)
00175           {
00176           case NODE_SUM:
00177             enclose_if(not (mode & MODE_ADD), node);
00178             break;
00179           case NODE_PROD:
00180             enclose_if(not (mode & MODE_MUL), node);
00181             break;
00182           case NODE_LWEIGHT:
00183             enclose_if(not (mode & MODE_LWEIGHT), node);
00184             break;
00185           case NODE_RWEIGHT:
00186             enclose_if(not (mode & MODE_RWEIGHT), node);
00187             break;
00188           default:
00189             enclose_if(mode & MODE_STAR, node);
00190             break;
00191           }
00192         ostr_ << "*";
00193       }
00194 
00195       virtual
00196       void
00197       left_weight(const semiring_elt_value_t& w, const node_t* node)
00198       {
00199         const long      mode = ostr_.iword(print_mode());
00200         const unsigned  node_type = node->what();
00201         long            verbose;
00202         bool            enclose_all (false);
00203 
00204         switch (node_type)
00205           {
00206           case NODE_PROD:
00207             verbose = not (mode & MODE_MUL);
00208             break;
00209           case NODE_SUM:
00210             verbose = not (mode & MODE_ADD);
00211             break;
00212           default:
00213             verbose = false;
00214             enclose_all = mode & MODE_LWEIGHT;
00215             break;
00216           }
00217 
00218         if (enclose_all)
00219           ostr_ << "(";
00220 
00221         ostr_ << w << " ";
00222         enclose_if(verbose, node);
00223 
00224         if (enclose_all)
00225           ostr_ << ")";
00226       }
00227 
00228       virtual
00229       void
00230       right_weight(const semiring_elt_value_t& w, const node_t* node)
00231       {
00232         const long      mode = ostr_.iword(print_mode());
00233         const unsigned  node_type = node->what();
00234         long            verbose;
00235         bool            enclose_all (false);
00236 
00237         switch (node_type)
00238           {
00239           case NODE_PROD:
00240             verbose = not (mode & MODE_MUL);
00241             break;
00242           case NODE_SUM:
00243             verbose = not (mode & MODE_ADD);
00244             break;
00245           default:
00246             verbose = false;
00247             enclose_all = mode & MODE_LWEIGHT;
00248             break;
00249           }
00250 
00251         if (enclose_all)
00252           ostr_ << "(";
00253 
00254         enclose_if(verbose, node);
00255         ostr_ << " " << w;
00256 
00257         if (enclose_all)
00258           ostr_ << ")";
00259       }
00260 
00261       virtual
00262       void
00263       constant(const monoid_elt_value_t& m)
00264       {
00265         ostr_ << misc::make_escaper(m);
00266       }
00267 
00268       virtual
00269       void
00270       zero()
00271       {
00272         ostr_ << *static_cast<const std::string*> (ostr_.pword(rat::zero()));
00273       }
00274 
00275       virtual
00276       void
00277       one()
00278       {
00279         ostr_ << *static_cast<const std::string*> (ostr_.pword(id()));
00280       }
00281 
00282     protected:
00283       std::ostream&     ostr_;
00284     };
00285 
00286     /*------------.
00287     | operator << |
00288     `------------*/
00289 
00290     template <class Word, class Weight>
00291     std::ostream&
00292     operator << (std::ostream& ostr, const exp<Word, Weight>& e)
00293     {
00294       DumpVisitor<Word, Weight> v (ostr);
00295       e.accept(v);
00296       return ostr;
00297     }
00298 
00299     /*------.
00300     | setpm |
00301     `------*/
00302 
00303     inline
00304     setpm::setpm(print_mode_t mode) : mode_ (mode)
00305     {
00306     }
00307 
00308     inline
00309     std::ostream&
00310     setpm::operator () (std::ostream& ostr) const
00311     {
00312       ostr.iword(print_mode()) = mode_;
00313       return ostr;
00314     }
00315 
00316     /*------.
00317     | getpm |
00318     `------*/
00319 
00320     inline
00321     print_mode_t
00322     getpm(std::ostream& ostr)
00323     {
00324       return print_mode_t (ostr.iword(print_mode()));
00325     }
00326 
00327     /*--------.
00328     | setzero |
00329     `--------*/
00330 
00331     inline
00332     setzero::setzero(const std::string& zero) : z_ (zero)
00333     {
00334     }
00335 
00336     inline
00337     std::ostream&
00338     setzero::operator () (std::ostream& ostr) const
00339     {
00340       const int idx = zero();
00341 
00342       if (not ostr.pword(idx))
00343         ostr.register_callback(misc::pword_delete<std::string>, idx);
00344       else
00345         delete static_cast<std::string*> (ostr.pword(idx));
00346       ostr.pword(idx) = new std::string (z_);
00347       return ostr;
00348     }
00349 
00350     /*------.
00351     | setid |
00352     `------*/
00353 
00354     inline
00355     setid::setid(const std::string& id) : i_ (id)
00356     {
00357     }
00358 
00359     inline
00360     std::ostream&
00361     setid::operator () (std::ostream& ostr) const
00362     {
00363       const int idx = id();
00364 
00365       if (not ostr.pword(idx))
00366         ostr.register_callback(misc::pword_delete<std::string>, idx);
00367       else
00368         delete static_cast<std::string*> (ostr.pword(idx));
00369       ostr.pword(idx) = new std::string (i_);
00370       return ostr;
00371     }
00372 
00373   } // rat
00374 
00375 } // vcsn
00376 
00377 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SERIES_RAT_DUMP_VISITOR_HXX

Generated on Sat Jul 29 17:12:59 2006 for Vaucanson by  doxygen 1.4.6