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