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