Vaucanson 1.4
|
00001 // dump_visitor.hxx: this file is part of the Vaucanson project. 00002 // 00003 // Vaucanson, a generic library for finite state machines. 00004 // 00005 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2010 The Vaucanson Group. 00006 // 00007 // This program is free software; you can redistribute it and/or 00008 // modify it under the terms of the GNU General Public License 00009 // as published by the Free Software Foundation; either version 2 00010 // of the License, or (at your option) any later version. 00011 // 00012 // The complete GNU General Public Licence Notice can be found as the 00013 // `COPYING' file in the root directory. 00014 // 00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file. 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 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 | DumpVisitor | 00064 `------------*/ 00065 00066 template <class Word, class Weight, typename Semiring, typename Monoid> 00067 class DumpVisitor : public ConstNodeVisitor<Word, Weight> 00068 { 00069 public: 00070 00071 // Type helpers. 00072 typedef Word monoid_elt_value_t; 00073 typedef Weight semiring_elt_value_t; 00074 typedef Node<Word, Weight> node_t; 00075 typedef algebra::MonoidRep<Monoid> monoid_rep_t; 00076 typedef boost::shared_ptr<monoid_rep_t> shared_monoid_rep_t; 00077 typedef algebra::SeriesRep<Semiring, Monoid> series_rep_t; 00078 typedef boost::shared_ptr<series_rep_t> shared_series_rep_t; 00079 typedef algebra::MonoidRepDefault<Monoid> default_monoid_rep_t; 00080 typedef algebra::SeriesRepDefault<Semiring, Monoid> 00081 default_series_rep_t; 00082 00083 DumpVisitor(std::ostream& ostr, 00084 const Monoid& monoid, 00085 shared_series_rep_t sr = default_series_rep_t:: 00086 get_instance()) 00087 : ostr_(ostr), 00088 monoid_(monoid), 00089 monoid_rep_(monoid.representation()), 00090 series_rep_(sr) 00091 { 00092 if (not ostr_.pword(rat::zero())) 00093 ostr_ << setzero(series_rep_->zero); 00094 00095 if (not ostr_.pword(rat::id())) 00096 ostr_ << setid(monoid_rep_->empty); 00097 } 00098 00099 virtual 00100 ~DumpVisitor() 00101 { 00102 ostr_.flush(); 00103 } 00104 00105 protected: 00106 00107 void 00108 enclose_if(const bool cond, const node_t* node) 00109 { 00110 if (cond) 00111 { 00112 ostr_ << series_rep_->open_par; 00113 node->accept(*this); 00114 ostr_ << series_rep_->close_par; 00115 } 00116 else 00117 node->accept(*this); 00118 } 00119 00120 enum 00121 { 00122 NODE_LWEIGHT = Node<Word, Weight>::lweight, 00123 NODE_RWEIGHT = Node<Word, Weight>::rweight, 00124 NODE_PROD = Node<Word, Weight>::prod, 00125 NODE_SUM = Node<Word, Weight>::sum, 00126 }; 00127 00128 void 00129 product_print_child(const node_t* child) 00130 { 00131 switch (child->what()) 00132 { 00133 case NODE_SUM: 00134 // If MODE_SUM is already set, there is no need to enclose the 00135 // child, since it will be done in sum(). 00136 enclose_if(not (ostr_.iword(print_mode()) & MODE_ADD), child); 00137 break; 00138 default: 00139 child->accept(*this); 00140 break; 00141 } 00142 } 00143 00144 public: 00145 00146 virtual 00147 void 00148 product(const node_t* lhs, const node_t* rhs) 00149 { 00150 const long verbose = ostr_.iword(print_mode()) & MODE_MUL; 00151 00152 if (verbose) 00153 ostr_ << series_rep_->open_par; 00154 00155 product_print_child(lhs); 00156 ostr_ << series_rep_->times; 00157 product_print_child(rhs); 00158 00159 if (verbose) 00160 ostr_ << series_rep_->close_par; 00161 } 00162 00163 virtual 00164 void 00165 sum(const node_t* lhs, const node_t* rhs) 00166 { 00167 const long verbose = ostr_.iword(print_mode()) & MODE_ADD; 00168 00169 if (verbose) 00170 ostr_ << series_rep_->open_par; 00171 00172 lhs->accept(*this); 00173 ostr_ << series_rep_->plus; 00174 rhs->accept(*this); 00175 00176 if (verbose) 00177 ostr_ << series_rep_->close_par; 00178 } 00179 00180 virtual 00181 void 00182 star(const node_t* node) 00183 { 00184 const long mode = ostr_.iword(print_mode()); 00185 const unsigned node_type = node->what(); 00186 00187 switch (node_type) 00188 { 00189 case NODE_SUM: 00190 enclose_if(not (mode & MODE_ADD), node); 00191 break; 00192 case NODE_PROD: 00193 enclose_if(not (mode & MODE_MUL), node); 00194 break; 00195 case NODE_LWEIGHT: 00196 enclose_if(not (mode & MODE_LWEIGHT), node); 00197 break; 00198 case NODE_RWEIGHT: 00199 enclose_if(not (mode & MODE_RWEIGHT), node); 00200 break; 00201 default: 00202 enclose_if(mode & MODE_STAR, node); 00203 break; 00204 } 00205 ostr_ << series_rep_->star; 00206 } 00207 00208 virtual 00209 void 00210 left_weight(const semiring_elt_value_t& w, const node_t* node) 00211 { 00212 const long mode = ostr_.iword(print_mode()); 00213 const unsigned node_type = node->what(); 00214 long verbose; 00215 bool enclose_all (false); 00216 00217 switch (node_type) 00218 { 00219 case NODE_PROD: 00220 verbose = not (mode & MODE_MUL); 00221 break; 00222 case NODE_SUM: 00223 verbose = not (mode & MODE_ADD); 00224 break; 00225 case NODE_LWEIGHT: 00226 verbose = not (mode & MODE_LWEIGHT); 00227 break; 00228 case NODE_RWEIGHT: 00229 verbose = not (mode & MODE_RWEIGHT); 00230 break; 00231 default: 00232 verbose = false; 00233 enclose_all = mode & MODE_LWEIGHT; 00234 break; 00235 } 00236 00237 if (enclose_all) 00238 ostr_ << series_rep_->open_par; 00239 00240 ostr_ << series_rep_->open_weight << w 00241 << series_rep_->close_weight << series_rep_->spaces.front(); 00242 enclose_if(verbose, node); 00243 00244 if (enclose_all) 00245 ostr_ << series_rep_->close_par; 00246 } 00247 00248 virtual 00249 void 00250 right_weight(const semiring_elt_value_t& w, const node_t* node) 00251 { 00252 const long mode = ostr_.iword(print_mode()); 00253 const unsigned node_type = node->what(); 00254 long verbose; 00255 bool enclose_all (false); 00256 00257 switch (node_type) 00258 { 00259 case NODE_PROD: 00260 verbose = not (mode & MODE_MUL); 00261 break; 00262 case NODE_SUM: 00263 verbose = not (mode & MODE_ADD); 00264 break; 00265 case NODE_LWEIGHT: 00266 verbose = not (mode & MODE_LWEIGHT); 00267 break; 00268 case NODE_RWEIGHT: 00269 verbose = not (mode & MODE_RWEIGHT); 00270 break; 00271 default: 00272 verbose = false; 00273 enclose_all = mode & MODE_RWEIGHT; 00274 break; 00275 } 00276 00277 if (enclose_all) 00278 ostr_ << series_rep_->open_par; 00279 00280 enclose_if(verbose, node); 00281 ostr_ << series_rep_->spaces.front() << series_rep_->open_weight 00282 << w << series_rep_->close_weight; 00283 00284 if (enclose_all) 00285 ostr_ << series_rep_->close_par; 00286 } 00287 00288 virtual 00289 void 00290 constant(const monoid_elt_value_t& m) 00291 { 00292 op_rout(monoid_, ostr_, m); 00293 } 00294 00295 virtual 00296 void 00297 zero() 00298 { 00299 // FIXME: factor with constant. 00300 ostr_ << *static_cast<const std::string*> (ostr_.pword(rat::zero())); 00301 } 00302 00303 virtual 00304 void 00305 one() 00306 { 00307 // FIXME: factor with constant. 00308 ostr_ << *static_cast<const std::string*> (ostr_.pword(rat::id())); 00309 } 00310 00311 protected: 00312 std::ostream& ostr_; 00313 const Monoid& monoid_; 00314 shared_monoid_rep_t monoid_rep_; 00315 shared_series_rep_t series_rep_; 00316 }; 00317 00318 /*------------. 00319 | operator << | 00320 `------------*/ 00321 00322 // template <class Word, class Weight> 00323 // std::ostream& 00324 // operator << (std::ostream& ostr, const exp<Word, Weight>& e) 00325 // { 00326 // DumpVisitor<Word, Weight, true, true> v (ostr); 00327 // e.accept(v); 00328 // return ostr; 00329 // } 00330 00331 /*------. 00332 | setpm | 00333 `------*/ 00334 00335 inline 00336 setpm::setpm(print_mode_t mode) : mode_ (mode) 00337 { 00338 } 00339 00340 inline 00341 std::ostream& 00342 setpm::operator () (std::ostream& ostr) const 00343 { 00344 ostr.iword(print_mode()) = mode_; 00345 return ostr; 00346 } 00347 00348 /*------. 00349 | getpm | 00350 `------*/ 00351 00352 inline 00353 print_mode_t 00354 getpm(std::ostream& ostr) 00355 { 00356 return print_mode_t (ostr.iword(print_mode())); 00357 } 00358 00359 /*--------. 00360 | setzero | 00361 `--------*/ 00362 00363 inline 00364 setzero::setzero(const std::string& zero) : z_ (zero) 00365 { 00366 } 00367 00368 inline 00369 std::ostream& 00370 setzero::operator () (std::ostream& ostr) const 00371 { 00372 const int idx = zero(); 00373 00374 if (not ostr.pword(idx)) 00375 ostr.register_callback(misc::pword_delete<std::string>, idx); 00376 else 00377 delete static_cast<std::string*> (ostr.pword(idx)); 00378 ostr.pword(idx) = new std::string (z_); 00379 return ostr; 00380 } 00381 00382 /*------. 00383 | setid | 00384 `------*/ 00385 00386 inline 00387 setid::setid(const std::string& id) : i_ (id) 00388 { 00389 } 00390 00391 inline 00392 std::ostream& 00393 setid::operator () (std::ostream& ostr) const 00394 { 00395 const int idx = id(); 00396 00397 if (not ostr.pword(idx)) 00398 ostr.register_callback(misc::pword_delete<std::string>, idx); 00399 else 00400 delete static_cast<std::string*> (ostr.pword(idx)); 00401 ostr.pword(idx) = new std::string (i_); 00402 return ostr; 00403 } 00404 00405 } // rat 00406 00407 } // vcsn 00408 00409 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SERIES_RAT_DUMP_VISITOR_HXX