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
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
00064
00065
00066 template <class Word, class Weight, typename Semiring, typename Monoid>
00067 class DumpVisitor : public ConstNodeVisitor<Word, Weight>
00068 {
00069 public:
00070
00071
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 = std::cout,
00084 shared_monoid_rep_t mr = default_monoid_rep_t::
00085 get_instance(),
00086 shared_series_rep_t sr = default_series_rep_t::
00087 get_instance())
00088 : ostr_(ostr),
00089 monoid_rep_(mr),
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
00135
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 typename monoid_elt_value_t::const_iterator i = m.begin();
00293
00294
00295 ostr_ << *i;
00296 ++i;
00297
00298
00299 while (i != m.end())
00300 {
00301 ostr_ << monoid_rep_->concat << *i;
00302 ++i;
00303 }
00304 }
00305
00306 virtual
00307 void
00308 zero()
00309 {
00310
00311 ostr_ << *static_cast<const std::string*> (ostr_.pword(rat::zero()));
00312 }
00313
00314 virtual
00315 void
00316 one()
00317 {
00318
00319 ostr_ << *static_cast<const std::string*> (ostr_.pword(rat::id()));
00320 }
00321
00322 protected:
00323 std::ostream& ostr_;
00324 shared_monoid_rep_t monoid_rep_;
00325 shared_series_rep_t series_rep_;
00326 };
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 inline
00346 setpm::setpm(print_mode_t mode) : mode_ (mode)
00347 {
00348 }
00349
00350 inline
00351 std::ostream&
00352 setpm::operator () (std::ostream& ostr) const
00353 {
00354 ostr.iword(print_mode()) = mode_;
00355 return ostr;
00356 }
00357
00358
00359
00360
00361
00362 inline
00363 print_mode_t
00364 getpm(std::ostream& ostr)
00365 {
00366 return print_mode_t (ostr.iword(print_mode()));
00367 }
00368
00369
00370
00371
00372
00373 inline
00374 setzero::setzero(const std::string& zero) : z_ (zero)
00375 {
00376 }
00377
00378 inline
00379 std::ostream&
00380 setzero::operator () (std::ostream& ostr) const
00381 {
00382 const int idx = zero();
00383
00384 if (not ostr.pword(idx))
00385 ostr.register_callback(misc::pword_delete<std::string>, idx);
00386 else
00387 delete static_cast<std::string*> (ostr.pword(idx));
00388 ostr.pword(idx) = new std::string (z_);
00389 return ostr;
00390 }
00391
00392
00393
00394
00395
00396 inline
00397 setid::setid(const std::string& id) : i_ (id)
00398 {
00399 }
00400
00401 inline
00402 std::ostream&
00403 setid::operator () (std::ostream& ostr) const
00404 {
00405 const int idx = id();
00406
00407 if (not ostr.pword(idx))
00408 ostr.register_callback(misc::pword_delete<std::string>, idx);
00409 else
00410 delete static_cast<std::string*> (ostr.pword(idx));
00411 ostr.pword(idx) = new std::string (i_);
00412 return ostr;
00413 }
00414
00415 }
00416
00417 }
00418
00419 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SERIES_RAT_DUMP_VISITOR_HXX