00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
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 
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             
00124             
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           default:
00215             verbose = false;
00216             enclose_all = mode & MODE_LWEIGHT;
00217             break;
00218           }
00219 
00220         if (enclose_all)
00221           ostr_ << "(";
00222 
00223         ostr_ << "{" << w << "} ";
00224         enclose_if(verbose, node);
00225 
00226         if (enclose_all)
00227           ostr_ << ")";
00228       }
00229 
00230       virtual
00231       void
00232       right_weight(const semiring_elt_value_t& w, const node_t* node)
00233       {
00234         const long      mode = ostr_.iword(print_mode());
00235         const unsigned  node_type = node->what();
00236         long            verbose;
00237         bool            enclose_all (false);
00238 
00239         switch (node_type)
00240           {
00241           case NODE_PROD:
00242             verbose = not (mode & MODE_MUL);
00243             break;
00244           case NODE_SUM:
00245             verbose = not (mode & MODE_ADD);
00246             break;
00247           default:
00248             verbose = false;
00249             enclose_all = mode & MODE_LWEIGHT;
00250             break;
00251           }
00252 
00253         if (enclose_all)
00254           ostr_ << "(";
00255 
00256         enclose_if(verbose, node);
00257         ostr_ << " {" << w << "}";
00258 
00259         if (enclose_all)
00260           ostr_ << ")";
00261       }
00262 
00263       virtual
00264       void
00265       constant(const monoid_elt_value_t& m)
00266       {
00267         ostr_ << m;
00268       }
00269 
00270       virtual
00271       void
00272       zero()
00273       {
00274         ostr_ << *static_cast<const std::string*> (ostr_.pword(rat::zero()));
00275       }
00276 
00277       virtual
00278       void
00279       one()
00280       {
00281         ostr_ << *static_cast<const std::string*> (ostr_.pword(id()));
00282       }
00283 
00284     protected:
00285       std::ostream&     ostr_;
00286     };
00287 
00288     
00289 
00290 
00291 
00292     template <class Word, class Weight>
00293     std::ostream&
00294     operator << (std::ostream& ostr, const exp<Word, Weight>& e)
00295     {
00296       DumpVisitor<Word, Weight> v (ostr);
00297       e.accept(v);
00298       return ostr;
00299     }
00300 
00301     
00302 
00303 
00304 
00305     inline
00306     setpm::setpm(print_mode_t mode) : mode_ (mode)
00307     {
00308     }
00309 
00310     inline
00311     std::ostream&
00312     setpm::operator () (std::ostream& ostr) const
00313     {
00314       ostr.iword(print_mode()) = mode_;
00315       return ostr;
00316     }
00317 
00318     
00319 
00320 
00321 
00322     inline
00323     print_mode_t
00324     getpm(std::ostream& ostr)
00325     {
00326       return print_mode_t (ostr.iword(print_mode()));
00327     }
00328 
00329     
00330 
00331 
00332 
00333     inline
00334     setzero::setzero(const std::string& zero) : z_ (zero)
00335     {
00336     }
00337 
00338     inline
00339     std::ostream&
00340     setzero::operator () (std::ostream& ostr) const
00341     {
00342       const int idx = zero();
00343 
00344       if (not ostr.pword(idx))
00345         ostr.register_callback(misc::pword_delete<std::string>, idx);
00346       else
00347         delete static_cast<std::string*> (ostr.pword(idx));
00348       ostr.pword(idx) = new std::string (z_);
00349       return ostr;
00350     }
00351 
00352     
00353 
00354 
00355 
00356     inline
00357     setid::setid(const std::string& id) : i_ (id)
00358     {
00359     }
00360 
00361     inline
00362     std::ostream&
00363     setid::operator () (std::ostream& ostr) const
00364     {
00365       const int idx = id();
00366 
00367       if (not ostr.pword(idx))
00368         ostr.register_callback(misc::pword_delete<std::string>, idx);
00369       else
00370         delete static_cast<std::string*> (ostr.pword(idx));
00371       ostr.pword(idx) = new std::string (i_);
00372       return ostr;
00373     }
00374 
00375   } 
00376 
00377 } 
00378 
00379 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SERIES_RAT_DUMP_VISITOR_HXX