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