tools.hxx

Go to the documentation of this file.
00001 // tools.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2005, 2006, 2007 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 
00018 #ifndef VCSN_XML_TOOLS_HXX
00019 # define VCSN_XML_TOOLS_HXX
00020 
00021 # include <vaucanson/xml/xml_xerces_stream.hh>
00022 
00034 namespace vcsn
00035 {
00036   namespace xml
00037   {
00038 
00039     namespace tools
00040     {
00041 
00042     /*--------------------------------------.
00043     | Extract information about the types.  |
00044     `--------------------------------------*/
00045 
00051       // Default.
00052       template <class S, class T>
00053       const char* get_semiring_set(const S&, const T&)
00054       { return "undefined"; }
00055 
00056 # define GET_SEMIRING_SET(T, Value)                     \
00057       template <class S>                                \
00058       const char* get_semiring_set(const S&, const T&)  \
00059       { return Value; }
00060 
00061       GET_SEMIRING_SET(bool, "B")
00062       GET_SEMIRING_SET(double, "R")
00063       GET_SEMIRING_SET(float, "R")
00064       GET_SEMIRING_SET(int, "Z")
00065 # undef GET_SEMIRING_SET
00066 
00067       // Transducer on P(B*).
00068       template <class S, class U, class V>
00069       const char* get_semiring_set(const S&,
00070                                    const vcsn::rat::exp<U, V>&)
00071       { return "ratSeries"; }
00072 
00073 
00074 
00075       // Deals with the "operation" attribute of <semiring> tag.
00076       // Default.
00077       template <class S>
00078       const char* get_semiring_operations(const S&)
00079       { return "undefined"; }
00080 
00081 # define GET_SEMIRING_OPERATIONS(S, Value)                      \
00082       template <>                                               \
00083       inline const char* get_semiring_operations<S>(const S&)   \
00084       { return Value; }
00085 
00086       GET_SEMIRING_OPERATIONS(vcsn::algebra::NumericalSemiring,
00087                               "classical")
00088       GET_SEMIRING_OPERATIONS(vcsn::z_max_plus_automaton::semiring_t,
00089                               "maxPlus")
00090       GET_SEMIRING_OPERATIONS(vcsn::z_min_plus_automaton::semiring_t,
00091                               "minPlus")
00092 # undef GET_SEMIRING_OPERATIONS
00093 
00094 
00095 
00096       // Deal with the "type" attribute of <monoid> tag.
00097       // Default.
00098       template <class S>
00099       const char* get_monoid_type(const S&)
00100       { return "undefined"; }
00101 
00102       template <class S>
00103       const char* get_monoid_type(const vcsn::algebra::FreeMonoid<S>&)
00104       { return "free"; }
00105 
00106       template <class S1, class S2>
00107       const char*
00108       get_monoid_type(const vcsn::algebra::FreeMonoidProduct<S1, S2>&)
00109       { return "product"; }
00110 
00111 
00112 
00113     /*-----------------------------------------.
00114     | Sugar for Xerces functions on elements.  |
00115     `-----------------------------------------*/
00116 
00117       inline
00118       xercesc::DOMElement*
00119       create_element(xercesc::DOMDocument* doc,
00120                      const std::string& e)
00121       {
00122         return doc->createElement(transcode(e));
00123       }
00124 
00125 
00126       inline
00127       void
00128       set_attribute (xercesc::DOMElement* e,
00129                      const std::string& k, const std::string& v)
00130       {
00131         e->setAttribute (transcode(k), transcode(v));
00132       }
00133 
00134       inline
00135       void
00136       xset_attribute (xercesc::DOMElement* e,
00137                       const std::string& k, const std::string& v)
00138       {
00139         if (v != "")
00140           set_attribute (e, k, v);
00141       }
00142 
00143       inline
00144       bool
00145       has_attribute (const xercesc::DOMElement* e,
00146                      const std::string& k)
00147       {
00148         return e->hasAttribute(transcode(k));
00149       }
00150 
00151       inline
00152       std::string
00153       get_attribute (const xercesc::DOMElement* e,
00154                      const std::string& k)
00155       {
00156         return xml2str(e->getAttribute(transcode(k)));
00157       }
00158 
00159     /*---------.
00160     | Automata |
00161     `---------*/
00162 
00163       // Add the label as a string attribute.
00164       template <class S, class T, class U>
00165       void add_label(xercesc::DOMElement* elt,
00166                      const Element<S, T>&,
00167                      const U& series)
00168       {
00169         xset_attribute(elt, "label", get_label(series));
00170       }
00171 
00172       // Add the label as an xml node
00173       template <class S, class T, class U>
00174       void add_xml_label(xercesc::DOMDocument* doc,
00175                          xercesc::DOMElement* elt,
00176                          const Element<S, T>& a,
00177                          const U& series)
00178       {
00179         typedef Element<S,T> automaton_t;
00180         typedef typename
00181           rat::exp<typename automaton_t::monoid_elt_value_t,
00182           typename automaton_t::semiring_elt_value_t> krat_exp_impl_t;
00183         typedef Element<typename automaton_t::series_set_t, krat_exp_impl_t> krat_exp_t;
00184 
00185 
00186         std::string label = get_label(series);
00187         if (label.size())
00188         {
00189           krat_exp_t res (a.structure().series());
00190           parse(label, res);
00191           elt->appendChild(res.value().xml_tree(doc, "label"));
00192         }
00193       }
00194 
00195 
00196       /*----------------.
00197       | FMP Transducers |
00198       `----------------*/
00199 
00200 # define FMPtype                                                          \
00201     Element<                                                              \
00202       Automata<                                                           \
00203       vcsn::algebra::Series<S, vcsn::algebra::FreeMonoidProduct<M1, M2> > \
00204       >, T                                                                \
00205     >
00206       // Add the label as a string attribute
00207       template <class S, class T, class U, class M1, class M2>
00208       void add_label(xercesc::DOMElement* elt,
00209                      const FMPtype&,
00210                      const U& series)
00211       {
00212         if (series.supp().size() != 1)
00213         {
00214           xset_attribute(elt, "label", get_label(series));
00215         }
00216         else
00217         {
00218           std::string in_word = get_label((*(series.supp().begin())).first);
00219           std::string out_word = get_label((*(series.supp().begin())).second);
00220           std::string mult = get_label(series.get(*(series.supp().begin())));
00221           std::string out;
00222           if (mult.size())
00223             out = mult;
00224           if (out != "" && out_word.size())
00225             out += " ";
00226           if (out_word.size())
00227             out += out_word;
00228 
00229           xset_attribute(elt, "in", in_word);
00230           xset_attribute(elt, "out", out);
00231         }
00232       }
00233 
00234       // Add the label as an xml node
00235       template <class S, class T, class U, class M1, class M2>
00236       void add_xml_label(xercesc::DOMDocument* doc,
00237                          xercesc::DOMElement* elt,
00238                          const FMPtype& a,
00239                          const U& series)
00240       {
00241         std::string out;
00242         if (series.supp().size() != 1)
00243         {
00244           xset_attribute(elt, "label", get_label(series));
00245         }
00246         else
00247         {
00248           std::string in_word = get_label((*series.supp()).first);
00249           std::string out_word = get_label((*series.supp()).second);
00250           std::string mult = get_label(series.get(*series.supp().begin()));
00251 
00252           if (in_word.size() && in_word != "1")
00253           {
00254             using namespace vcsn::r_automaton;
00255             automaton_t bin = make_automaton(
00256               a.structure().series().monoid().first_monoid().alphabet());
00257             rat_exp_t res_in(bin.structure().series());
00258             parse(in_word, res_in);
00259             elt->appendChild(res_in.value().xml_tree(doc, "in"));
00260           }
00261           if (out_word.size() && out_word != "1")
00262           {
00263             using namespace vcsn::r_automaton;
00264             automaton_t bout = make_automaton(
00265               a.structure().series().monoid().second_monoid().alphabet());
00266             rat_exp_t res_out(bout.structure().series());
00267             parse(out_word, res_out);
00268             xercesc::DOMElement* out_node =
00269               res_out.value().xml_tree(doc, "out");
00270             xset_attribute(out_node, "weight", mult);
00271             elt->appendChild(out_node);
00272           }
00273         }
00274       }
00275 
00276 
00277       /*---------------------.
00278       | Transducers on P(B*) |
00279       `---------------------*/
00280 
00281       // Add the label as a string attribute
00282       template <class S, class T, class U>
00283       void add_label(xercesc::DOMElement* elt,
00284                      const Element<Transducer<S>, T>&,
00285                      const U& series)
00286       {
00287         if (series.supp().size())
00288         {
00289           std::string in = get_label(*(series.supp().begin()));
00290           std::string out = get_label(series.get(*(series.supp().begin())));
00291 
00292           if (in.size() && in != "1")
00293             set_attribute(elt, "in", in);
00294           if (out.size() && out != "1")
00295             set_attribute(elt, "out", out);
00296         }
00297       }
00298 
00299       // Add the label as an xml node
00300       template <class S, class T, class U>
00301       void add_xml_label(xercesc::DOMDocument* doc,
00302                          xercesc::DOMElement* elt,
00303                          const Element<Transducer<S>, T>& a,
00304                          const U& series)
00305       {
00306         if (series.supp().size())
00307         {
00308           std::string in = get_label(*(series.supp().begin()));
00309           std::string out = get_label(series.get(*(series.supp().begin())));
00310 
00311           if (in.size() && in != "1")
00312           {
00313             using namespace vcsn::r_automaton;
00314             automaton_t bin = make_automaton(
00315               a.structure().series().monoid().alphabet());
00316             rat_exp_t res_in(bin.structure().series());
00317             parse(in, res_in);
00318             elt->appendChild(res_in.value().xml_tree(doc, "in"));
00319           }
00320           if (out.size() && out != "1")
00321           {
00322             using namespace vcsn::r_automaton;
00323             automaton_t bout = make_automaton(
00324               a.structure().series().semiring().monoid().alphabet());
00325             rat_exp_t res_out(bout.structure().series());
00326             parse(out, res_out);
00327             elt->appendChild(res_out.value().xml_tree(doc, "out"));
00328           }
00329         }
00330       }
00331 
00332 
00333       template <class L>
00334       const std::string get_label(const L& l)
00335       {
00336         std::ostringstream os;
00337         os << l;
00338         return os.str();
00339       }
00340 
00341       inline const std::string get_label(const bool& l)
00342       {
00343         if (l)
00344           return "";
00345         return "0";
00346       }
00347 
00348 
00349       inline
00350       const std::string
00351       get_label(const std::pair<std::string, std::string>& l)
00352       {
00353         std::ostringstream os;
00354         os << "(" << l.first << ", " << l.second << ")";
00355         return os.str().c_str();
00356       }
00357 
00358       template <class S, class Series>
00359       const std::string get_label(const Element<Series,
00360                                   vcsn::algebra::polynom<S, bool> >& l)
00361       {
00362         std::ostringstream os;
00363         os << l;
00364         if (os.str() == "1")
00365           return "";
00366         return os.str();
00367       }
00368 
00369 
00370       template <class A>
00371       void create_alphabet(const A& alphabet, xercesc::DOMDocument* doc,
00372                            xercesc::DOMElement* root)
00373       {
00374         typedef typename A::const_iterator alphabet_iterator;
00375         for_all_letters(l, alphabet)
00376         {
00377           std::ostringstream letter;
00378           xercesc::DOMElement* gen = create_element(doc, "generator");
00379           letter << *l;
00380           set_attribute(gen, "value", letter.str());
00381           root->appendChild(gen);
00382         }
00383       }
00384 
00385       template <class M>
00386       xercesc::DOMElement*
00387       create_monoid(const M& monoid,
00388                     xercesc::DOMDocument* doc,
00389                     xercesc::DOMElement* elt)
00390       {
00391         xercesc::DOMElement* m = create_element(doc, "monoid");
00392         set_attribute(m, "type", get_monoid_type(monoid));
00393         set_attribute(m, "generatorType", "letters");
00394         elt->appendChild(m);
00395 
00396         return m;
00397       }
00398 
00399       template <class A, class S>
00400       xercesc::DOMElement* create_semiring(const A&,
00401                                            const S& semiring,
00402                                            xercesc::DOMDocument* doc,
00403                                            xercesc::DOMElement* elt)
00404       {
00405         typedef typename A::series_set_elt_t::semiring_elt_t::value_t value_t;
00406         xercesc::DOMElement* s = NULL;
00407 
00408         if (get_semiring_set(semiring, value_t()) != "ratSeries")
00409         {
00410           s = create_element(doc, "semiring");
00411           set_attribute(s, "operations", get_semiring_operations(semiring));
00412           set_attribute(s, "set", get_semiring_set(semiring, value_t()));
00413         }
00414         else
00415           s = create_element(doc, "numericalSemiring");
00416 
00417         elt->appendChild(s);
00418         return s;
00419       }
00420 
00421       template <class S, class T>
00422       xercesc::DOMElement*
00423       create_semiring(const Element<Transducer<S>, T>&,
00424                       const vcsn::algebra::NumericalSemiring& semiring,
00425                       xercesc::DOMDocument* doc,
00426                       xercesc::DOMElement* elt)
00427       {
00428         typedef typename
00429           Element<Transducer<S>, T>::series_set_elt_t::semiring_elt_t::semiring_elt_t::value_t
00430           value_t;
00431 
00432         xercesc::DOMElement* s = create_element(doc, "semiring");
00433         set_attribute(s, "operations", "classical");
00434         set_attribute(s, "set", get_semiring_set(semiring, value_t()));
00435         elt->appendChild(s);
00436 
00437         return s;
00438       }
00439 
00440       // Used by get_rec_xml_series to get the eventual weigths of an expression
00441       // element.
00442       template <class T>
00443       void get_weight_attribute(typename T::semiring_elt_value_t& weight,
00444                                 xercesc::DOMElement* element,
00445                                 const char* attribute_name)
00446       {
00447         if (has_attribute(element, attribute_name))
00448         {
00449           std::stringstream ss;
00450           ss << get_attribute(element, attribute_name);
00451           ss >> weight;
00452         }
00453       }
00454 
00455       // Used by get_rec_xml_series to set the weights to the krat_exp that will
00456       // be returned.
00457       template <class T>
00458       Element<typename T::series_set_t,
00459               rat::exp<typename T::monoid_elt_value_t,
00460                        typename T::semiring_elt_value_t> >
00461       weighted_krat_exp(Element<typename T::series_set_t,
00462                         rat::exp<typename T::monoid_elt_value_t,
00463                         typename T::semiring_elt_value_t> >& krat_exp,
00464                         typename T::semiring_elt_value_t& weight,
00465                         typename T::semiring_elt_value_t& rweight)
00466       {
00467         if (weight != typename T::semiring_elt_t ())
00468           krat_exp = typename T::semiring_elt_t (weight) * krat_exp;
00469         if (rweight != typename T::semiring_elt_t ())
00470           krat_exp = krat_exp * (typename T::semiring_elt_t) rweight;
00471         return krat_exp;
00472       }
00473 
00474 
00475       template <class T>
00476       Element<typename T::series_set_t,
00477               rat::exp<typename T::monoid_elt_value_t,
00478                        typename T::semiring_elt_value_t> >
00479       get_rec_xml_series(xercesc::DOMNode* n, T& aut)
00480       {
00481         typedef  rat::exp<typename T::monoid_elt_value_t,
00482                           typename T::semiring_elt_value_t> krat_exp_impl_t;
00483         typedef Element<typename T::series_set_t, krat_exp_impl_t> krat_exp_t;
00484         krat_exp_t krat_exp (aut.structure().series());
00485         typename T::semiring_elt_value_t weight =
00486           typename T::semiring_elt_value_t();
00487         typename T::semiring_elt_value_t rweight =
00488           typename T::semiring_elt_value_t();
00489 
00490         xercesc::DOMElement* element_n;
00491         xercesc::DOMNode* ntmp;
00492 
00493         if (!n)
00494           return vcsn::algebra::identity_as<krat_exp_impl_t>::
00495 	    of(krat_exp.structure());
00496 
00497         for (; n ; n = n->getNextSibling())
00498         {
00499           if (n->getNodeType() == xercesc::DOMNode::ELEMENT_NODE)
00500           {
00501             element_n = (static_cast<xercesc::DOMElement*>(n));
00502 
00503             if ((xml2str(n->getNodeName()) == "label") ||
00504                 (xml2str(n->getNodeName()) == "in") ||
00505                 (xml2str(n->getNodeName()) == "out"))
00506               return get_rec_xml_series(n->getFirstChild(), aut);
00507 
00508             // Add weights. It is a weight (leafs) or left and right weights
00509             // (nodes).
00510             get_weight_attribute<T>(weight, element_n, "weight");
00511             get_weight_attribute<T>(weight, element_n, "leftWeight");
00512             get_weight_attribute<T>(rweight, element_n, "rightWeight");
00513 
00514             // Explore the terms of a sum
00515             if (xml2str(n->getNodeName()) == "sum")
00516             {
00517               ntmp = n->getFirstChild()->getNextSibling();
00518               krat_exp = get_rec_xml_series(ntmp, aut);
00519               if (ntmp)
00520                 for (ntmp = ntmp->getNextSibling();
00521                      ntmp && ntmp->getNextSibling();
00522                      ntmp = ntmp->getNextSibling()->getNextSibling())
00523                   krat_exp += get_rec_xml_series(ntmp, aut);
00524               return weighted_krat_exp<T>(krat_exp, weight, rweight);
00525             }
00526 
00527             // Explore the terms of a product
00528             if (xml2str(n->getNodeName()) == "product")
00529             {
00530               ntmp = n->getFirstChild()->getNextSibling();
00531               krat_exp = get_rec_xml_series(ntmp, aut);
00532               if (ntmp)
00533                 for (ntmp = ntmp->getNextSibling();
00534                      ntmp && ntmp->getNextSibling();
00535                      ntmp = ntmp->getNextSibling()->getNextSibling())
00536                   krat_exp *= get_rec_xml_series(ntmp, aut);
00537               return weighted_krat_exp<T>(krat_exp, weight, rweight);
00538             }
00539 
00540             // Word, zero or identity
00541             if (xml2str(n->getNodeName()) == "word")
00542               krat_exp = typename T::monoid_elt_t (
00543                 krat_exp.structure().monoid(),
00544                 get_attribute(element_n, "value"));
00545 
00546             if (xml2str(n->getNodeName()) == "zero")
00547               krat_exp = vcsn::algebra::
00548 		zero_as<krat_exp_impl_t>::of(krat_exp.structure());
00549 
00550             if (xml2str(n->getNodeName()) == "identity")
00551               krat_exp =  vcsn::algebra::
00552 		identity_as<krat_exp_impl_t>::of(krat_exp.structure());
00553 
00554             // Add star
00555             if (xml2str(n->getNodeName()) == "star")
00556               krat_exp = (get_rec_xml_series(n->getFirstChild(), aut)).star();
00557 
00558             return weighted_krat_exp<T>(krat_exp, weight, rweight);
00559           }
00560         }
00561         return krat_exp;
00562       }
00563 
00564 
00565       template <class T>
00566       typename T::series_set_elt_t
00567       get_series(xercesc::DOMElement* node, T& aut)
00568       {
00569         typedef typename
00570           rat::exp<typename T::monoid_elt_value_t,
00571           typename T::semiring_elt_value_t> krat_exp_impl_t;
00572         typedef Element<typename T::series_set_t, krat_exp_impl_t> krat_exp_t;
00573         krat_exp_t res (aut.structure().series());
00574         xercesc::DOMNode* n = node->getFirstChild();
00575         if (n && n->getNextSibling()
00576             && (xml2str(n->getNextSibling()->getNodeName()) == "label"))
00577           res = get_rec_xml_series(n, aut);
00578         if (res == vcsn::algebra::
00579             zero_as<krat_exp_impl_t>::of(res.structure()))
00580         {
00581           if (get_attribute(node, "label") == "")
00582             return
00583               vcsn::algebra::identity_as<typename T::series_set_elt_t::value_t>
00584               ::of(aut.structure().series());
00585           else
00586             parse(get_attribute(node, "label"), res);
00587         }
00588         return res;
00589       }
00590 
00591 
00592       template <class S, class T, class M1, class M2>
00593       typename FMPtype::series_set_elt_t
00594       get_series(xercesc::DOMElement* node, FMPtype& a)
00595       {
00596         typename FMPtype::series_set_elt_t res(a.structure().series());
00597 
00598         parse_label(node, a,
00599                     a.structure().series().monoid().first_monoid().alphabet(),
00600                     a.structure().series().monoid().second_monoid().alphabet(),
00601                     res);
00602 
00603         return res;
00604       }
00605 
00606 
00607 # define TRANStype                              \
00608     Element<Transducer<S>, T>
00609 
00610       template <class S, class T>
00611       typename TRANStype::series_set_elt_t
00612       get_series(xercesc::DOMElement* node,
00613                  TRANStype& a)
00614       {
00615         typename TRANStype::series_set_elt_t res(a.structure().series());
00616 
00617         parse_label(node, a,
00618                     a.structure().series().monoid().alphabet(),
00619                     a.structure().series().semiring().monoid().alphabet(),
00620                     res);
00621 
00622         return res;
00623       }
00624 
00625 
00626       template <class S, class T, class E1, class E2, class R>
00627       void assoc_exp(TRANStype& a, E1& i_exp, E2& o_exp, R& res,
00628                      bool i_res, bool o_res)
00629       {
00630         typedef typename TRANStype::monoid_elt_t::value_t md_value_t;
00631         typedef typename TRANStype::semiring_elt_t::value_t sg_value_t;
00632         typename TRANStype::monoid_elt_t m(a.structure().series().monoid());
00633 
00634         if (! i_res && i_exp.supp().size())
00635           m = *(i_exp.supp().begin());
00636         else
00637           m = vcsn::algebra::identity_as<md_value_t>
00638 	    ::of(a.structure().series().monoid());
00639 
00640         if (! o_res && ! o_exp.supp().size())
00641           res.assoc(m,
00642                     vcsn::algebra::identity_as<sg_value_t>
00643                     ::of(a.structure().series().semiring()));
00644         else
00645           res.assoc(m, o_exp);
00646       }
00647 
00648 
00649       template <class S, class T, class M1, class M2,
00650                 class E1, class E2, class R>
00651       void assoc_exp(FMPtype& a, E1& i_exp, E2& o_exp, R& res,
00652                      bool i_res, bool o_res)
00653       {
00654         typename FMPtype::monoid_elt_t m(a.structure().series().monoid());
00655         typename FMPtype::monoid_elt_t::first_monoid_elt_value_t m1("");
00656         typename FMPtype::monoid_elt_t::second_monoid_elt_value_t m2("");
00657         typename FMPtype::semiring_elt_value_t sem = 1;
00658         typedef typename FMPtype::monoid_elt_t::first_monoid_elt_t::value_t
00659           md_value_t;
00660         typedef typename FMPtype::semiring_elt_value_t sg_value_t;
00661 
00662         if (! i_res && i_exp.supp().size())
00663           m1 = *(i_exp.supp().begin());
00664         else
00665           m1 = vcsn::algebra::identity_as<md_value_t>
00666 	    ::of(a.structure().series().monoid().first_monoid()).value();
00667 
00668         if (! o_res && o_exp.supp().size())
00669         {
00670           m2 = *(o_exp.supp().begin());
00671           sem = o_exp.get(m2);
00672         }
00673         else
00674         {
00675           m2 = vcsn::algebra::identity_as<md_value_t>
00676 	    ::of(a.structure().series().monoid().second_monoid()).value();
00677           sem = vcsn::algebra::identity_as<sg_value_t>
00678 	    ::of(a.structure().series().semiring()).value();
00679         }
00680         m = std::make_pair(m1, m2);
00681         res.assoc(m, sem);
00682       }
00683 
00684 
00685       template <class A, class A1, class A2, class S>
00686       void parse_label(xercesc::DOMElement* node, A& a,
00687                        const A1& alphabet1, const A2& alphabet2, S& res)
00688       {
00689         using namespace vcsn::r_automaton;
00690         automaton_t bin = make_automaton(alphabet1);
00691         automaton_t bout = make_automaton(alphabet2);
00692         rat_exp_t i_exp(bin.structure().series());
00693         rat_exp_t o_exp(bout.structure().series());
00694         std::string in, out;
00695 
00696         std::pair<bool, std::string> i_res;
00697         std::pair<bool, std::string> o_res;
00698 
00699         xercesc::DOMNode* n = node->getFirstChild();
00700 
00701         if (n)
00702           for (; n; n = n->getNextSibling())
00703           {
00704             if (xml2str(n->getNodeName()) == "in" && n->getFirstChild())
00705               i_exp = get_rec_xml_series(n->getFirstChild(), bin);
00706             if (xml2str(n->getNodeName()) == "out" && n->getFirstChild())
00707               o_exp = get_rec_xml_series(n->getFirstChild(), bout);
00708           }
00709         // No expression tag
00710         else
00711         {
00712           if (has_attribute(node, "label"))
00713           {
00714             std::string label = get_attribute(node, "label");
00715             unsigned int pos = label.find("|");
00716             if (pos != std::string::npos)
00717             {
00718               in = label.substr(0, pos);
00719               out = label.substr(pos + 1);
00720               i_res = parse(in, i_exp);
00721               o_res = parse(out, o_exp);
00722             }
00723             else
00724             {
00725               i_res = parse(label, i_exp);
00726               if (label == "0")
00727                 return;
00728             }
00729             if (has_attribute(node, "weight"))
00730               o_res = parse(get_attribute(node, "weight"), o_exp);
00731           }
00732           // No expression tag, no label attribute.
00733           else
00734           {
00735             if (has_attribute(node, "in"))
00736               i_res = parse(get_attribute(node, "in"), i_exp);
00737             if (has_attribute(node, "out"))
00738               o_res = parse(get_attribute(node, "out"), o_exp);
00739           }
00740         }
00741         assoc_exp(a, i_exp, o_exp, res, i_res.first, o_res.first);
00742       }
00743 
00744 
00745       template <class U, class V>
00746       void insert_letter(Element<vcsn::algebra::AlphabetSet<U>, V>&,
00747                          const std::string&)
00748       {
00749         FAIL("No available implementation for this type of letter");
00750       }
00751 
00752       template <class V>
00753       void insert_letter(Element<vcsn::algebra::AlphabetSet<char>, V>& a,
00754                          const std::string& str)
00755       {
00756         a.insert(str[0]);
00757       }
00758 
00759 
00769       void
00770       check_consistency (const xercesc::DOMElement* node,
00771                          const std::string& kind,
00772                          const char* key, const std::string& deflt,
00773                          const std::string& expected)
00774       {
00775         std::string observed;
00776         if (expected == "ratSeries")
00777           return;
00778         if (node && has_attribute(node, key))
00779           observed = get_attribute(node, key);
00780         else
00781           observed = deflt;
00782         if (expected != observed)
00783           FAIL(std::string ("invalid ") + kind + ": " + observed
00784                + ", expected: " + expected);
00785       }
00786 
00787 
00788       template <class T, class U>
00789       void ensure_semiring_type(const xercesc::DOMElement* node,
00790                                 const T&, const U& param)
00791       {
00792         typedef typename T::series_set_elt_t::semiring_elt_t::value_t value_t;
00793         check_consistency (node, "semiring",
00794                            "set", "B",
00795                            tools::get_semiring_set(param, value_t()));
00796       }
00797 
00798 
00799       template <class S, class T>
00800       void ensure_semiring_type(const xercesc::DOMElement* node,
00801                                 const Element<Transducer<S>, T>&,
00802                                 const typename Element<Transducer<S>, T>
00803                                 ::semiring_t::semiring_t& param)
00804       {
00805         typedef Element<Transducer<S>, T> trans_t;
00806         typedef typename
00807           trans_t::series_set_elt_t::semiring_elt_t::semiring_elt_t::value_t
00808           value_t;
00809         check_consistency (node, "semiring",
00810                            "set", "B",
00811                            tools::get_semiring_set(param, value_t()));
00812       }
00813 
00814 
00815       template <class S, class T, class U>
00816       void ensure_semiring_type(const xercesc::DOMElement* node,
00817                                 const Element<Transducer<S>, T>&,
00818                                 const typename Element<Transducer<S>, T>
00819                                 ::semiring_t& param)
00820       {
00821         typedef Element<Transducer<S>, T> trans_t;
00822         typedef typename
00823           trans_t::series_set_elt_t::semiring_elt_t::value_t value_t;
00824 
00825         check_consistency (node, "semiring", "set", "ratSeries",
00826                            tools::get_semiring_set(param, value_t()));
00827       }
00828 
00829 
00830       template <class U>
00831       void ensure_monoid_type(const xercesc::DOMElement* node, const U& param)
00832       {
00833         check_consistency (node,
00834                            "monoid", "type", "free",
00835                            tools::get_monoid_type(param));
00836       }
00837 
00838 
00839       template <class S, class T, class U, class M1, class M2>
00840       void ensure_monoid_type(const xercesc::DOMElement* node,
00841                               const FMPtype& param)
00842       {
00843         check_consistency (node,
00844                            "monoid", "type", "product",
00845                            tools::get_monoid_type(param));
00846       }
00847 
00848       template <class OStream>
00849       void print_document(xercesc::DOMImplementationLS* impl,
00850                           xercesc::DOMElement* node,
00851                           OStream& os)
00852       {
00853         using namespace xercesc;
00854 
00855         XMLXercesStream<OStream>* target = new XMLXercesStream<OStream>(os);
00856         DOMWriter* writer = (impl)->createDOMWriter();
00857 
00858         if (writer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true))
00859           writer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true);
00860         writer->writeNode(target, *node);
00861         writer->release();
00862         os << std::endl;
00863       }
00864 
00865     } // ! tools
00866 
00867   } // ! xml
00868 
00869 } // ! vcsn
00870 
00871 
00872 # undef TRANStype
00873 # undef FMPtype
00874 
00875 #endif // ! VCSN_XML_TOOLS_HXX

Generated on Wed Jun 13 17:00:30 2007 for Vaucanson by  doxygen 1.5.1