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