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

Generated on Wed Jun 13 17:00:21 2007 for Vaucanson by  doxygen 1.5.1