builders.hxx

00001 // builders.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2007, 2008 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_XML_BUILDERS_HXX
00018 # define VCSN_XML_BUILDERS_HXX
00019 
00020 # include <sstream>
00021 
00022 # include <vaucanson/algebra/concept/letter.hh>
00023 # include <vaucanson/algebra/implementation/series/rat/exp.hh>
00024 # include <vaucanson/design_pattern/element.hh>
00025 # include <vaucanson/xml/xml_exp_visitor.hh>
00026 # include <vaucanson/algebra/concept/monoid_base.hh>
00027 
00028 namespace vcsn
00029 {
00030   namespace xml
00031   {
00035     template <typename T>
00036     monGenAction<T>::monGenAction(const T&)
00037     {
00038       static_error(need_to_specialize_monGenAction_for_T)
00039     }
00040 
00041     template <typename T>
00042     monGenAction<vcsn::algebra::FreeMonoid<T> >::
00043     monGenAction(self_t& monoid)
00044     : alphabet_(monoid.alphabet())
00045     {
00046     }
00047 
00048     template <typename T, typename U, typename V>
00049     monGenAction<vcsn::Element<vcsn::algebra::Series<T, U>, V> >::
00050     monGenAction(self_t& s)
00051     : s_(s)
00052     {
00053     }
00054 
00055     // Real work done here (insertion).
00056     template <typename T>
00057     void
00058     monGenAction<vcsn::algebra::FreeMonoid<T> >::
00059     operator () (const std::string& str)
00060     {
00061       alphabet_.insert(str);
00062     }
00063 
00064     // Real work done here (concatanation).
00065     template <typename T, typename U, typename V>
00066     void
00067     monGenAction<vcsn::Element<vcsn::algebra::Series<T, U>, V> >::
00068     operator () (const std::string& str)
00069     {
00070       typename self_t::monoid_elt_t m(s_.structure().monoid(), str);
00071       self_t tmp(s_.structure(), m);
00072 
00073       s_ = s_ * tmp;
00074     }
00075 
00079     template <typename T, typename U>
00080     monGenHandler<T, U>::monGenHandler (xercesc::SAX2XMLReader* parser,
00081                                  Handler& root,
00082                                  const monGenAction<U>& action,
00083                                  const XMLCh* value)
00084       : Handler(parser, root),
00085         value_(value),
00086         action_(action)
00087     {
00088     }
00089 
00090     template <typename T, typename U>
00091     void
00092     monGenHandler<T, U>::start (const XMLCh* const,
00093                                  const XMLCh* const localname,
00094                                  const XMLCh* const,
00095                                  const xercesc::Attributes&)
00096     {
00097       error::token(localname);
00098     }
00099 
00100     template <typename T, typename U>
00101     void
00102     monGenHandler<T, U>::end (const XMLCh* const,
00103                                const XMLCh* const localname,
00104                                const XMLCh* const)
00105     {
00106       if (xercesc::XMLString::equals(eq_.monGen, localname))
00107       {
00108         if (value_)
00109         {
00110           std::string letter = xmlstr(value_);
00111           action_(letter);
00112           parser_->setContentHandler(&root_);
00113         }
00114         else
00115         {
00116           error::missattrs(localname, "value");
00117         }
00118       }
00119       else
00120         error::token(localname);
00121     }
00122 
00126     template <typename T, typename U>
00127     monGenTupleHandler<T, U>::monGenTupleHandler (xercesc::SAX2XMLReader* parser,
00128                                  Handler& root,
00129                                  const monGenAction<U>& action)
00130       : Handler(parser, root),
00131         value_("("),
00132         wait_begin_(true),
00133         count_(0),
00134         action_(action)
00135     {
00136     }
00137 
00138     template <typename T, typename U>
00139     void
00140     monGenTupleHandler<T, U>::start (const XMLCh* const,
00141                                  const XMLCh* const localname,
00142                                  const XMLCh* const,
00143                                  const xercesc::Attributes& attrs)
00144     {
00145       if (xercesc::XMLString::equals(eq_.monCompGen, localname) && wait_begin_)
00146       {
00147         wait_begin_ = false;
00148         const XMLCh* attr = tools::get_attribute(attrs, "value");
00149         if (!attr)
00150           error::missattrs(localname, "value");
00151         value_ += xmlstr(attr);
00152         if (count_ == algebra::letter_traits<typename T::alphabet_t::letter_t>::dim() - 2)
00153           value_ += ",";
00154       }
00155       else
00156         error::token(localname);
00157     }
00158 
00159     template <typename T, typename U>
00160     void
00161     monGenTupleHandler<T, U>::end (const XMLCh* const,
00162                                const XMLCh* const localname,
00163                                const XMLCh* const)
00164     {
00165       int dim = algebra::letter_traits<typename T::alphabet_t::letter_t>::
00166       dim();
00167 
00168       if (xercesc::XMLString::equals(eq_.monGen, localname)
00169           && count_ == dim)
00170       {
00171         value_ += ")";
00172         action_(value_);
00173         parser_->setContentHandler(&root_);
00174       }
00175       else if (xercesc::XMLString::equals(eq_.monCompGen, localname)
00176                && !wait_begin_ && count_ < dim)
00177       {
00178         wait_begin_ = true;
00179         count_++;
00180       }
00181       else
00182         error::token(localname);
00183     }
00184 
00188     template <typename T>
00189     FreeMonoidHandler<T>::FreeMonoidHandler (xercesc::SAX2XMLReader* parser,
00190                                  Handler& root,
00191                                  T& monoid)
00192       : Handler(parser, root),
00193         monoid_(monoid),
00194         mongenh_(0),
00195         unsuph_(parser, *this)
00196     {
00197     }
00198 
00199     template <typename T>
00200     void
00201     FreeMonoidHandler<T>::start (const XMLCh* const,
00202                                  const XMLCh* const localname,
00203                                  const XMLCh* const,
00204                                  const xercesc::Attributes& attrs)
00205     {
00206       using namespace xercesc;
00207 
00208       if (XMLString::equals(eq_.monGen, localname))
00209       {
00210         // When we have a monGen, we will insert it in the monoid alphabet.
00211         monGenAction<T> action(monoid_);
00212 
00213         // Delete the old handler.
00214         if (mongenh_)
00215           delete mongenh_;
00216 
00217         // Choose statically the kind of generator.
00218         if (algebra::letter_traits<typename T::alphabet_t::letter_t>::kind() == "simple")
00219         {
00220           const XMLCh* value = tools::get_attribute(attrs, "value");
00221           mongenh_ = new monGenHandler<T, T>(parser_, *this, action, value);
00222         }
00223         else
00224           mongenh_ = new monGenTupleHandler<T, T>(parser_, *this, action);
00225 
00226         // Setup the new handler.
00227         parser_->setContentHandler(mongenh_);
00228       }
00229       else if (XMLString::equals(eq_.genSort, localname))
00230       {
00231         // FIXME: we should store the informations of genSort to ensure monoid consistency.
00232         parser_->setContentHandler(&unsuph_);
00233       }
00234       else if (XMLString::equals(eq_.writingData, localname))
00235         parser_->setContentHandler(&unsuph_);
00236       else
00237         error::token(localname);
00238     }
00239 
00240     template <typename T>
00241     void
00242     FreeMonoidHandler<T>::end (const XMLCh* const,
00243                                const XMLCh* const localname,
00244                                const XMLCh* const)
00245     {
00246       using namespace xercesc;
00247 
00248       if (XMLString::equals(eq_.monoid, localname))
00249       {
00250         // We are done with the monoid, so delete remaining data.
00251         if (mongenh_)
00252           delete mongenh_;
00253 
00254         // Go up one level.
00255         parser_->setContentHandler(&root_);
00256       }
00257       else if (!XMLString::equals(eq_.monGen, localname))
00258         error::token(localname);
00259     }
00260 
00261     namespace builders
00262     {
00263       template <typename T>
00264       typename T::monoid_t*
00265       create_monoid (T& param,
00266                      const XMLCh* const localname,
00267                      const xercesc::Attributes& attrs)
00268       {
00269         typename T::monoid_t::alphabet_t        at;
00270         typedef typename T::monoid_t            monoid_t;
00271 
00272         monoid_t*       monoid = new monoid_t(at);
00273         builders::check_monoid_consistency(param, localname, attrs);
00274         return monoid;
00275       }
00276 
00277       template <typename T>
00278       Handler*
00279       create_monoidh (T& monoid,
00280                       const xercesc::Attributes&,
00281                       xercesc::SAX2XMLReader* parser,
00282                       Handler& root)
00283       {
00284         return new vcsn::xml::FreeMonoidHandler<T>(parser, root, monoid);
00285       }
00286 
00287     } // !builders
00291     template <typename T>
00292     NumSemiringHandler<T>::NumSemiringHandler (xercesc::SAX2XMLReader* parser,
00293                                                Handler& root,
00294                                                T& semiring)
00295     : Handler(parser, root),
00296       semiring_(semiring),
00297       unsuph_(parser, *this)
00298     {
00299     }
00300 
00301     template <typename T>
00302     void
00303     NumSemiringHandler<T>::start (const XMLCh* const,
00304                                  const XMLCh* const localname,
00305                                  const XMLCh* const,
00306                                  const xercesc::Attributes&)
00307     {
00308       if (xercesc::XMLString::equals(eq_.writingData, localname))
00309         parser_->setContentHandler(&unsuph_);
00310       else
00311         error::token(localname);
00312     }
00313 
00314     template <typename T>
00315     void
00316     NumSemiringHandler<T>::end (const XMLCh* const,
00317                                const XMLCh* const localname,
00318                                const XMLCh* const)
00319     {
00320       if (xercesc::XMLString::equals(eq_.semiring, localname))
00321         parser_->setContentHandler(&root_);
00322       else
00323         error::token(localname);
00324     }
00325 
00326     namespace builders
00327     {
00328       template <typename T>
00329       typename T::semiring_t*
00330       create_semiring (T&,
00331                        const XMLCh* const localname,
00332                        const xercesc::Attributes& attrs)
00333       {
00334         typedef typename T::semiring_t semiring_t;
00335         semiring_t*     semiring = new semiring_t();
00336 
00337         typedef typename T::semiring_elt_t semiring_elt_t;
00338         semiring_elt_t  elt;
00339         builders::check_semiring_consistency(elt, localname, attrs);
00340 
00341         return semiring;
00342       }
00343 
00344       template <typename T>
00345       Handler*
00346       create_semiringh(T& semiring,
00347                        const xercesc::Attributes&,
00348                        xercesc::SAX2XMLReader* parser,
00349                        Handler& root)
00350       {
00351         return new NumSemiringHandler<T>(parser, root, semiring);
00352       }
00353 
00354     } // !builders
00355 
00359     template <typename T>
00360     class MonElmtHandler;
00361 
00362     template <typename T>
00363     class WeightHandler;
00364 
00365     namespace builders
00366     {
00367 
00368       template <typename S, typename T>
00369       RegexpHandler<S>*
00370       create_monElmth(xercesc::SAX2XMLReader* parser,
00371                       RegexpHandler<T>& root,
00372                       S param)
00373       {
00374         return new MonElmtHandler<S>(parser, root, param);
00375       }
00376 
00377       template <typename T>
00378       RegexpHandler<T>*
00379       create_weighth(xercesc::SAX2XMLReader* parser,
00380                      RegexpHandler<T>& root,
00381                      T param,
00382                      const xercesc::Attributes& attrs)
00383       {
00384         typename T::monoid_elt_value_t m =
00385           vcsn::algebra::identity_as<typename T::monoid_elt_value_t>::of(param.structure().monoid()).value();
00386         const std::string val(xmlstr(tools::get_attribute(attrs, "value")));
00387         std::string::const_iterator i = val.begin();
00388         typename T::semiring_elt_t w(param.structure().semiring());
00389         if (!parse_weight(w, val, i))
00390           error::attrs(tools::get_attribute(attrs, "localname"), "value", val);
00391         param.assoc(m, w.value());
00392         return new WeightHandler<T>(parser, root, param);
00393       }
00394     } // !builders
00395 
00399     namespace builders
00400     {
00401       // Default.
00402       template <class T>
00403       const char* get_semiring_set(const T&)
00404       { return "undefined"; }
00405 
00406 # define GET_SEMIRING_SET(T, Value)                     \
00407       const char* get_semiring_set(const T&)    \
00408       { return Value; }
00409 
00410       GET_SEMIRING_SET(bool, "B")
00411       GET_SEMIRING_SET(double, "R")
00412       GET_SEMIRING_SET(float, "R")
00413       GET_SEMIRING_SET(int, "Z")
00414 # undef GET_SEMIRING_SET
00415 
00416       template <class S>
00417       const char* get_semiring_operations(const S&)
00418       { return "classical"; }
00419 
00420       template <typename T>
00421       void
00422       check_monoid_consistency (T&,
00423                                 const XMLCh* const localname,
00424                                 const xercesc::Attributes& attrs)
00425       {
00426         std::string val(xmlstr(tools::get_attribute(attrs, "type")));
00427         if (val != "free")
00428           error::attrs(localname, "type", val);
00429       };
00430 
00431       template <typename T>
00432       void
00433       check_semiring_consistency (T& param,
00434                                   const XMLCh* const localname,
00435                                   const xercesc::Attributes& attrs)
00436       {
00437         std::string set(xmlstr(tools::get_attribute(attrs, "set")));
00438         if (builders::get_semiring_set(param.value()) != set)
00439           error::attrs(localname, "set", set);
00440         std::string op(xmlstr(tools::get_attribute(attrs, "operations")));
00441         if (builders::get_semiring_operations(param.structure()) != op)
00442           error::attrs(localname, "operations", op);
00443       };
00444 
00445       template <class T>
00446       const char* get_monoid_gen_sort(const T&)
00447       { return "undefined"; }
00448 # define GET_MONOID_GEN_SORT(T, Value) \
00449       const char* get_monoid_gen_sort(const T&) \
00450       { return Value; }
00451 
00452       GET_MONOID_GEN_SORT(char, "letters")
00453       GET_MONOID_GEN_SORT(int, "integers")
00454 # undef GET_MONOID_GEN_SORT
00455 
00456       template <class T>
00457       const char* get_monoid_gen_sort(const T&, int)
00458       { return "undefined"; }
00459 
00460       template <class U, class V>
00461       const char* get_monoid_gen_sort(const std::pair<U,V>& a, int i)
00462       {
00463         return i ? get_monoid_gen_sort(a.second) : get_monoid_gen_sort(a.first);
00464       }
00465     } // !builders
00466 
00467     namespace builders
00468     {
00469       template <typename T>
00470       void
00471       create_semiring_node(const T& aut,
00472                            xercesc::DOMDocument* doc,
00473                            xercesc::DOMElement* root)
00474       {
00475         typedef typename T::semiring_elt_t semiring_elt_t;
00476         semiring_elt_t semiring(aut.structure().series().semiring());
00477         xercesc::DOMElement* node = tools::create_element(doc, "semiring");
00478         tools::set_attribute(node, "type", "numerical");
00479         tools::set_attribute(node, "set", get_semiring_set(semiring.value()));
00480         tools::set_attribute(node, "operations", get_semiring_operations(semiring.structure()));
00481         root->appendChild(node);
00482       }
00483       template <typename T>
00484       void
00485       create_monoid_node(const T& aut,
00486                          xercesc::DOMDocument* doc,
00487                          xercesc::DOMElement* root)
00488       {
00489         std::string letter_kind = algebra::letter_traits<typename T::monoid_t::alphabet_t::letter_t>::kind();
00490         xercesc::DOMElement* node = tools::create_element(doc, "monoid");
00491         tools::set_attribute(node, "type", "free");
00492         tools::set_attribute(node, "genDescrip", "enum");
00493         tools::set_attribute(node, "genKind", letter_kind);
00494         root->appendChild(node);
00495 
00496         typedef typename T::monoid_t::alphabet_t::const_iterator alphabet_iterator;
00497 
00498         if (letter_kind == "simple")
00499           tools::set_attribute(node, "genSort", get_monoid_gen_sort(*(aut.structure().series().monoid().alphabet().begin())));
00500         else
00501         {
00502           std::stringstream genDim;
00503           int dim = algebra::letter_traits<typename T::monoid_t::alphabet_t::letter_t>::dim();
00504           genDim << dim;
00505           tools::set_attribute(node, "genDim", genDim.str());
00506           xercesc::DOMElement* genSort = tools::create_element(doc, "genSort");
00507           node->appendChild(genSort);
00508           xercesc::DOMElement* genCompSort;
00509           for (int i = 0; i != dim; i++)
00510           {
00511             genCompSort = tools::create_element(doc, "genCompSort");
00512             tools::set_attribute(genCompSort, "value", get_monoid_gen_sort(*(aut.structure().series().monoid().alphabet().begin()), i));
00513             genSort->appendChild(genCompSort);
00514           }
00515         }
00516 
00517         create_monGen_node<typename T::monoid_t::alphabet_t::letter_t> monGen_maker;
00518         for_all_letters(l, aut.structure().series().monoid().alphabet())
00519           monGen_maker(*l, doc, node);
00520 
00521       }
00522 
00523       template <typename T>
00524       void
00525       create_regexp_node(const T& e,
00526                          xercesc::DOMDocument* doc,
00527                          xercesc::DOMElement* root)
00528       {
00529         typedef typename T::value_t::monoid_elt_value_t monoid_elt_value_t;
00530         typedef typename T::value_t::semiring_elt_value_t       semiring_elt_value_t;
00531         typedef typename rat::exp<monoid_elt_value_t, semiring_elt_value_t> krat_exp_impl_t;
00532 
00533         typedef Element<typename T::set_t, krat_exp_impl_t > krat_exp_t;
00534 
00535         krat_exp_t res(e);
00536         rat::XmlExpVisitor<monoid_elt_value_t, semiring_elt_value_t> v(doc, "label");
00537         res.value().accept(v);
00538         root->appendChild(v.get());
00539       }
00540 
00541       template <typename U>
00542       void
00543       create_monElmt_node(const U& word,
00544                           xercesc::DOMDocument* doc,
00545                           xercesc::DOMElement* root)
00546       {
00547         xercesc::DOMElement* node;
00548 
00549         if (word.empty())
00550           node = tools::create_element(doc, "one");
00551         else
00552         {
00553           node = tools::create_element(doc, "monElmt");
00554           create_monGen_node<typename U::value_type> monGen_maker;
00555           for (typename U::const_iterator i = word.begin(); i != word.end(); ++i)
00556             monGen_maker(*i, doc, node);
00557         }
00558 
00559         root->appendChild(node);
00560       }
00561 
00562       // FIXME: We should be able to specialize for all type U,
00563       // whose letter_traits::kind() is "simple".
00564       template <typename U>
00565       struct create_monGen_node
00566       {
00567         void
00568         operator()(const U& letter,
00569                    xercesc::DOMDocument* doc,
00570                    xercesc::DOMElement* root)
00571         {
00572           xercesc::DOMElement* gen = tools::create_element(doc, "monGen");
00573 
00574           tools::set_attribute(gen, "value",
00575                                algebra::letter_traits<U>::
00576                                letter_to_literal(letter));
00577 
00578           root->appendChild(gen);
00579         }
00580       };
00581 
00582       // FIXME: We should be able to specialize for all type U,
00583       // whose kind() is "tuple" and dim() is 2 and has_first is
00584       // true and has_second is true.
00585       template <typename U, typename V>
00586       struct create_monGen_node<std::pair<U, V> >
00587       {
00588         void
00589         operator()(const std::pair<U, V>& letter,
00590                    xercesc::DOMDocument* doc,
00591                    xercesc::DOMElement* root)
00592         {
00593           xercesc::DOMElement* gen = tools::create_element(doc, "monGen");
00594 
00595           std::stringstream sstr_first;
00596           std::stringstream sstr_second;
00597           xercesc::DOMElement* first = tools::create_element(doc, "monCompGen");
00598           xercesc::DOMElement* second = tools::create_element(doc, "monCompGen");
00599           sstr_first << letter.first;
00600           sstr_second << letter.second;
00601           tools::set_attribute(first, "value", sstr_first.str());
00602           tools::set_attribute(second, "value", sstr_second.str());
00603           gen->appendChild(first);
00604           gen->appendChild(second);
00605 
00606           root->appendChild(gen);
00607         }
00608       };
00609 
00610     } // ! builders
00611 
00612   } // ! xml
00613 
00614 } // ! vcsn
00615 
00616 #endif // ! VCSN_XML_BUILDERS_HXX

Generated on Thu Oct 9 20:22:34 2008 for Vaucanson by  doxygen 1.5.1