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