- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

# 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, 2010 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
    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, typename Semiring, typename Monoid>
    00067     class DumpVisitor : public ConstNodeVisitor<Word, Weight>
    00068     {
    00069     public:
    00070
    00071       // Type helpers.
    00072       typedef Word                                      monoid_elt_value_t;
    00073       typedef Weight                                    semiring_elt_value_t;
    00074       typedef Node<Word, Weight>                        node_t;
    00075       typedef algebra::MonoidRep<Monoid>                monoid_rep_t;
    00076       typedef boost::shared_ptr<monoid_rep_t>           shared_monoid_rep_t;
    00077       typedef algebra::SeriesRep<Semiring, Monoid>      series_rep_t;
    00078       typedef boost::shared_ptr<series_rep_t>           shared_series_rep_t;
    00079       typedef algebra::MonoidRepDefault<Monoid>         default_monoid_rep_t;
    00080       typedef algebra::SeriesRepDefault<Semiring, Monoid>
    00081         default_series_rep_t;
    00082
    00083       DumpVisitor(std::ostream& ostr,
    00084                   const Monoid& monoid,
    00085                   shared_series_rep_t sr = default_series_rep_t::
    00086                   get_instance())
    00087         : ostr_(ostr),
    00088           monoid_(monoid),
    00089           monoid_rep_(monoid.representation()),
    00090           series_rep_(sr)
    00091       {
    00092         if (not ostr_.pword(rat::zero()))
    00093           ostr_ << setzero(series_rep_->zero);
    00094
    00095         if (not ostr_.pword(rat::id()))
    00096           ostr_ << setid(monoid_rep_->empty);
    00097       }
    00098
    00099       virtual
    00100       ~DumpVisitor()
    00101       {
    00102         ostr_.flush();
    00103       }
    00104
    00105     protected:
    00106
    00107       void
    00108       enclose_if(const bool cond, const node_t* node)
    00109       {
    00110         if (cond)
    00111           {
    00112             ostr_ << series_rep_->open_par;
    00113             node->accept(*this);
    00114             ostr_ << series_rep_->close_par;
    00115           }
    00116         else
    00117           node->accept(*this);
    00118       }
    00119
    00120       enum
    00121         {
    00122           NODE_LWEIGHT  = Node<Word, Weight>::lweight,
    00123           NODE_RWEIGHT  = Node<Word, Weight>::rweight,
    00124           NODE_PROD     = Node<Word, Weight>::prod,
    00125           NODE_SUM      = Node<Word, Weight>::sum,
    00126         };
    00127
    00128       void
    00129       product_print_child(const node_t* child)
    00130       {
    00131         switch (child->what())
    00132           {
    00133           case NODE_SUM:
    00134             // If MODE_SUM is already set, there is no need to enclose the
    00135             // child, since it will be done in sum().
    00136             enclose_if(not (ostr_.iword(print_mode()) & MODE_ADD), child);
    00137             break;
    00138           default:
    00139             child->accept(*this);
    00140             break;
    00141           }
    00142       }
    00143
    00144     public:
    00145
    00146       virtual
    00147       void
    00148       product(const node_t* lhs, const node_t* rhs)
    00149       {
    00150         const long verbose = ostr_.iword(print_mode()) & MODE_MUL;
    00151
    00152         if (verbose)
    00153           ostr_ << series_rep_->open_par;
    00154
    00155         product_print_child(lhs);
    00156         ostr_ << series_rep_->times;
    00157         product_print_child(rhs);
    00158
    00159         if (verbose)
    00160           ostr_ << series_rep_->close_par;
    00161       }
    00162
    00163       virtual
    00164       void
    00165       sum(const node_t* lhs, const node_t* rhs)
    00166       {
    00167         const long verbose = ostr_.iword(print_mode()) & MODE_ADD;
    00168
    00169         if (verbose)
    00170           ostr_ << series_rep_->open_par;
    00171
    00172         lhs->accept(*this);
    00173         ostr_ << series_rep_->plus;
    00174         rhs->accept(*this);
    00175
    00176         if (verbose)
    00177           ostr_ << series_rep_->close_par;
    00178       }
    00179
    00180       virtual
    00181       void
    00182       star(const node_t* node)
    00183       {
    00184         const long      mode = ostr_.iword(print_mode());
    00185         const unsigned  node_type = node->what();
    00186
    00187         switch (node_type)
    00188           {
    00189           case NODE_SUM:
    00190             enclose_if(not (mode & MODE_ADD), node);
    00191             break;
    00192           case NODE_PROD:
    00193             enclose_if(not (mode & MODE_MUL), node);
    00194             break;
    00195           case NODE_LWEIGHT:
    00196             enclose_if(not (mode & MODE_LWEIGHT), node);
    00197             break;
    00198           case NODE_RWEIGHT:
    00199             enclose_if(not (mode & MODE_RWEIGHT), node);
    00200             break;
    00201           default:
    00202             enclose_if(mode & MODE_STAR, node);
    00203             break;
    00204           }
    00205         ostr_ << series_rep_->star;
    00206       }
    00207
    00208       virtual
    00209       void
    00210       left_weight(const semiring_elt_value_t& w, const node_t* node)
    00211       {
    00212         const long      mode = ostr_.iword(print_mode());
    00213         const unsigned  node_type = node->what();
    00214         long            verbose;
    00215         bool            enclose_all (false);
    00216
    00217         switch (node_type)
    00218           {
    00219           case NODE_PROD:
    00220             verbose = not (mode & MODE_MUL);
    00221             break;
    00222           case NODE_SUM:
    00223             verbose = not (mode & MODE_ADD);
    00224             break;
    00225           case NODE_LWEIGHT:
    00226             verbose = not (mode & MODE_LWEIGHT);
    00227             break;
    00228           case NODE_RWEIGHT:
    00229             verbose = not (mode & MODE_RWEIGHT);
    00230             break;
    00231           default:
    00232             verbose = false;
    00233             enclose_all = mode & MODE_LWEIGHT;
    00234             break;
    00235           }
    00236
    00237         if (enclose_all)
    00238           ostr_ << series_rep_->open_par;
    00239
    00240         ostr_ << series_rep_->open_weight << w
    00241               << series_rep_->close_weight << series_rep_->spaces.front();
    00242         enclose_if(verbose, node);
    00243
    00244         if (enclose_all)
    00245           ostr_ << series_rep_->close_par;
    00246       }
    00247
    00248       virtual
    00249       void
    00250       right_weight(const semiring_elt_value_t& w, const node_t* node)
    00251       {
    00252         const long      mode = ostr_.iword(print_mode());
    00253         const unsigned  node_type = node->what();
    00254         long            verbose;
    00255         bool            enclose_all (false);
    00256
    00257         switch (node_type)
    00258           {
    00259           case NODE_PROD:
    00260             verbose = not (mode & MODE_MUL);
    00261             break;
    00262           case NODE_SUM:
    00263             verbose = not (mode & MODE_ADD);
    00264             break;
    00265           case NODE_LWEIGHT:
    00266             verbose = not (mode & MODE_LWEIGHT);
    00267             break;
    00268           case NODE_RWEIGHT:
    00269             verbose = not (mode & MODE_RWEIGHT);
    00270             break;
    00271           default:
    00272             verbose = false;
    00273             enclose_all = mode & MODE_RWEIGHT;
    00274             break;
    00275           }
    00276
    00277         if (enclose_all)
    00278           ostr_ << series_rep_->open_par;
    00279
    00280         enclose_if(verbose, node);
    00281         ostr_ << series_rep_->spaces.front() << series_rep_->open_weight
    00282               << w << series_rep_->close_weight;
    00283
    00284         if (enclose_all)
    00285           ostr_ << series_rep_->close_par;
    00286       }
    00287
    00288       virtual
    00289       void
    00290       constant(const monoid_elt_value_t& m)
    00291       {
    00292         op_rout(monoid_, ostr_, m);
    00293       }
    00294
    00295       virtual
    00296       void
    00297       zero()
    00298       {
    00299         // FIXME: factor with constant.
    00300         ostr_ << *static_cast<const std::string*> (ostr_.pword(rat::zero()));
    00301       }
    00302
    00303       virtual
    00304       void
    00305       one()
    00306       {
    00307         // FIXME: factor with constant.
    00308         ostr_ << *static_cast<const std::string*> (ostr_.pword(rat::id()));
    00309       }
    00310
    00311     protected:
    00312       std::ostream&     ostr_;
    00313       const Monoid&     monoid_;
    00314       shared_monoid_rep_t monoid_rep_;
    00315       shared_series_rep_t series_rep_;
    00316     };
    00317
    00318     /*------------.
    00319     | operator << |
    00320     `------------*/
    00321
    00322 //    template <class Word, class Weight>
    00323 //    std::ostream&
    00324 //    operator << (std::ostream& ostr, const exp<Word, Weight>& e)
    00325 //    {
    00326 //      DumpVisitor<Word, Weight, true, true> v (ostr);
    00327 //      e.accept(v);
    00328 //      return ostr;
    00329 //    }
    00330
    00331     /*------.
    00332     | setpm |
    00333     `------*/
    00334
    00335     inline
    00336     setpm::setpm(print_mode_t mode) : mode_ (mode)
    00337     {
    00338     }
    00339
    00340     inline
    00341     std::ostream&
    00342     setpm::operator () (std::ostream& ostr) const
    00343     {
    00344       ostr.iword(print_mode()) = mode_;
    00345       return ostr;
    00346     }
    00347
    00348     /*------.
    00349     | getpm |
    00350     `------*/
    00351
    00352     inline
    00353     print_mode_t
    00354     getpm(std::ostream& ostr)
    00355     {
    00356       return print_mode_t (ostr.iword(print_mode()));
    00357     }
    00358
    00359     /*--------.
    00360     | setzero |
    00361     `--------*/
    00362
    00363     inline
    00364     setzero::setzero(const std::string& zero) : z_ (zero)
    00365     {
    00366     }
    00367
    00368     inline
    00369     std::ostream&
    00370     setzero::operator () (std::ostream& ostr) const
    00371     {
    00372       const int idx = zero();
    00373
    00374       if (not ostr.pword(idx))
    00375         ostr.register_callback(misc::pword_delete<std::string>, idx);
    00376       else
    00377         delete static_cast<std::string*> (ostr.pword(idx));
    00378       ostr.pword(idx) = new std::string (z_);
    00379       return ostr;
    00380     }
    00381
    00382     /*------.
    00383     | setid |
    00384     `------*/
    00385
    00386     inline
    00387     setid::setid(const std::string& id) : i_ (id)
    00388     {
    00389     }
    00390
    00391     inline
    00392     std::ostream&
    00393     setid::operator () (std::ostream& ostr) const
    00394     {
    00395       const int idx = id();
    00396
    00397       if (not ostr.pword(idx))
    00398         ostr.register_callback(misc::pword_delete<std::string>, idx);
    00399       else
    00400         delete static_cast<std::string*> (ostr.pword(idx));
    00401       ostr.pword(idx) = new std::string (i_);
    00402       return ostr;
    00403     }
    00404
    00405   } // rat
    00406
    00407 } // vcsn
    00408
    00409 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SERIES_RAT_DUMP_VISITOR_HXX