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