builders.hxx

Go to the documentation of this file.
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) 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 BUILDERS_HXX
00019 # define BUILDERS_HXX
00020 
00032 # include <vaucanson/xml/handlers.hh>
00033 # include <vaucanson/xml/xmleq.hh>
00034 
00035 namespace vcsn
00036 {
00037   namespace xml
00038   {
00039     namespace builders
00040     {
00041       // Processing monoid
00042 
00043       template <typename T>
00044       inline
00045       typename T::monoid_t*
00046       create_monoid (T&,
00047                      const xercesc::Attributes&)
00048       {
00049         typename T::monoid_t::alphabet_t        at;
00050         typedef typename T::monoid_t    monoid_t;
00051 
00052         monoid_t*               monoid = new monoid_t(at);
00053         return monoid;
00054       }
00055 
00056       TParmFMP
00057       inline
00058       typename FMPtype::monoid_t*
00059       create_monoid (FMPtype&,
00060                      const xercesc::Attributes&)
00061       {
00062         typename FMPtype::monoid_t::first_monoid_t::alphabet_t  at1;
00063         typename FMPtype::monoid_t::second_monoid_t::alphabet_t at2;
00064         typename FMPtype::monoid_t::first_monoid_t      md1(at1);
00065         typename FMPtype::monoid_t::second_monoid_t     md2(at2);
00066         typedef typename FMPtype::monoid_t              monoid_t;
00067 
00068         monoid_t* monoid = new monoid_t(md1, md2);
00069         return monoid;
00070       }
00071 
00072       template <typename T>
00073       MonoidHandler*
00074       monoidh_factory(T& monoid,
00075                       const xercesc::Attributes& attrs,
00076                       xercesc::DefaultHandler& root,
00077                       xercesc::SAX2XMLReader* parser,
00078                       XMLEq& eq)
00079       {
00080         check_consistency (attrs, "monoid", "type",
00081                            tools::get_monoid_type(monoid));
00082         return new vcsn::xml::FreeMonoidHandler<T>(root, monoid, parser, eq);
00083       }
00084 
00085       template <typename T1, typename T2>
00086       MonoidHandler*
00087       monoidh_factory(vcsn::algebra::FreeMonoidProduct<T1, T2>& monoid,
00088                       const xercesc::Attributes& attrs,
00089                       xercesc::DefaultHandler& root,
00090                       xercesc::SAX2XMLReader* parser,
00091                       XMLEq& eq)
00092       {
00093         check_consistency (attrs, "monoid", "type",
00094                            tools::get_monoid_type(monoid));
00095         typedef typename vcsn::algebra::FreeMonoidProduct<T1, T2> monoid_t;
00096         return new ProdMonoidHandler<monoid_t>(root, monoid, parser, eq);
00097       }
00098 
00099       template <typename T>
00100       inline
00101       void
00102       insert_letter (T& monoid,
00103                      std::string letter)
00104       {
00105         tools::insert_letter(monoid.alphabet(), letter);
00106       }
00107 
00108       // Processing semiring
00109 
00110       template <typename T>
00111       inline
00112       typename T::semiring_t*
00113       create_semiring (T&,
00114                        const xercesc::Attributes&)
00115       {
00116         typedef typename T::semiring_t semiring_t;
00117         semiring_t*     semiring = new semiring_t();
00118         return semiring;
00119       }
00120 
00121       TParm
00122       inline
00123       typename TRANStype::semiring_t*
00124       create_semiring (TRANStype&,
00125                        const xercesc::Attributes&)
00126       {
00127         typename TRANStype::semiring_t::monoid_t::alphabet_t    at;
00128         typename TRANStype::semiring_t::monoid_t        md(at);
00129         typename TRANStype::semiring_t::semiring_t      ssg;
00130         typedef typename TRANStype::semiring_t  semiring_t;
00131 
00132         semiring_t*     semiring = new semiring_t(ssg, md);
00133         return semiring;
00134       }
00135 
00136       template <typename V, typename T>
00137       SemiringHandler*
00138       semiringh_factory(V&,
00139                         const xercesc::Attributes& attrs,
00140                         T& semiring,
00141                         xercesc::DefaultHandler& root,
00142                         xercesc::SAX2XMLReader* parser,
00143                         XMLEq& eq)
00144       {
00145         typedef typename V::series_set_elt_t::semiring_elt_t::value_t value_t;
00146         check_consistency (attrs, "semiring", "set",
00147                            tools::get_semiring_set(semiring, value_t()));
00148         return new NumSemiringHandler<T>(root, semiring, parser, eq);
00149       }
00150 
00151 #define SSEMIRINGtype \
00152       vcsn::algebra::Series<U, V>
00153 
00154       template <typename U, typename V, typename T>
00155       SemiringHandler*
00156       semiringh_factory(SSEMIRINGtype&,
00157                         const xercesc::Attributes&,
00158                         T& semiring,
00159                         xercesc::DefaultHandler& root,
00160                         xercesc::SAX2XMLReader* parser,
00161                         XMLEq& eq)
00162       {
00163         // FIXME Check_consistency of a semiring_t::semiring_t.
00164         // Need to find how to get the set of a semiring_t
00165 
00166         // typedef typename SSEMIRINGtype::semiring_t value_t;
00167         //check_consistency (attrs, "semiring", "set",
00168         //                 tools::get_semiring_set(semiring, value_t()));
00169         return new NumSemiringHandler<T>(root, semiring, parser, eq);
00170       }
00171 
00172 #undef SSEMIRINGtype
00173 
00174       TParm
00175       SemiringHandler*
00176       semiringh_factory(TRANStype& aut,
00177                         const xercesc::Attributes& attrs,
00178                         typename TRANStype::semiring_t& semiring,
00179                         xercesc::DefaultHandler& root,
00180                         xercesc::SAX2XMLReader* parser,
00181                         XMLEq& eq)
00182       {
00183         typedef typename TRANStype::series_set_elt_t::semiring_elt_t::value_t value_t;
00184         check_consistency (attrs, "semiring", "set",
00185                            tools::get_semiring_set(semiring, value_t()));
00186         typedef typename TRANStype::semiring_t  semiring_t;
00187         return new SeriesSemiringHandler<semiring_t>(root, semiring, parser, eq);
00188       }
00189 
00190       // Processing label attribute
00191 
00192       template<typename T>
00193       inline
00194       void
00195       get_weight(T& res,
00196                  std::map<std::string, std::string>& attrs)
00197       {
00198         typename std::map<std::string, std::string>::iterator i;
00199         if ((i = attrs.find("weight")) != attrs.end())
00200         {
00201           typename T::semiring_elt_t weight(res.structure().semiring());
00202           const std::string& str = i->second;
00203           std::string::const_iterator it = str.begin();
00204           if (parse_weight(weight, str, it))
00205             res = res * weight;
00206           else
00207             FAIL(std::string ("Weight in wrong format"));
00208         }
00209       }
00210 
00211       template <typename T>
00212       typename T::series_set_elt_t
00213       get_series (T& aut,
00214                   std::map<std::string, std::string>& attrs,
00215                   const char* token)
00216       {
00217         typedef typename
00218           rat::exp<typename T::monoid_elt_value_t,
00219           typename T::semiring_elt_value_t> krat_exp_impl_t;
00220         typedef Element<typename T::series_set_t, krat_exp_impl_t> krat_exp_t;
00221         krat_exp_t res (aut.structure().series());
00222         typename std::map<std::string, std::string>::iterator i;
00223         if ((i = attrs.find(token)) == attrs.end())
00224           return
00225             vcsn::algebra::identity_as<typename T::series_set_elt_t::value_t>
00226               ::of(aut.structure().series());
00227         else
00228         {
00229           std::pair<bool, std::string> err = parse(i->second, res);
00230           if (err.first)
00231             FAIL(std::string ("Error while parsing: ") + err.second + "\n");
00232         }
00233         get_weight(res, attrs);
00234         return res;
00235       }
00236 
00237       TParmFMP
00238       typename FMPtype::series_set_elt_t
00239       get_series (FMPtype& a,
00240                   std::map<std::string, std::string>& attrs,
00241                   const char*)
00242       {
00243         typename FMPtype::series_set_elt_t res(a.structure().series());
00244 
00245         parse_label(a,
00246                     a.structure().series().monoid().first_monoid().alphabet(),
00247                     a.structure().series().monoid().second_monoid().alphabet(),
00248                     attrs,
00249                     res);
00250         get_weight(res, attrs);
00251         return res;
00252       }
00253 
00254       TParm
00255       typename TRANStype::series_set_elt_t
00256       get_series (TRANStype& a,
00257                   std::map<std::string, std::string>& attrs,
00258                   const char*)
00259       {
00260         typename TRANStype::series_set_elt_t res(a.structure().series());
00261 
00262         parse_label(a,
00263                     a.structure().series().monoid().alphabet(),
00264                     a.structure().series().semiring().monoid().alphabet(),
00265                     attrs,
00266                     res);
00267         return res;
00268       }
00269 
00270       template <class Auto, class A1, class A2, class S>
00271       void
00272       parse_label (Auto& a,
00273                    const A1& al1,
00274                    const A2& al2,
00275                    std::map<std::string, std::string>& attrs,
00276                    S& res)
00277       {
00278         typedef typename std::map<std::string, std::string>::iterator   it_t;
00279         using namespace vcsn::r_automaton;
00280         automaton_t bin = make_automaton(al1);
00281         automaton_t bout = make_automaton(al2);
00282         rat_exp_t i_exp(bin.structure().series());
00283         rat_exp_t o_exp(bout.structure().series());
00284         std::string in, out;
00285 
00286         std::pair<bool, std::string> i_res;
00287         std::pair<bool, std::string> o_res;
00288 
00289         it_t it;
00290         if ((it = attrs.find("label")) != attrs.end())
00291         {
00292           std::string label = it->second;
00293           unsigned int pos = label.find("|");
00294           if (pos != std::string::npos)
00295           {
00296             in = label.substr(0, pos);
00297             out = label.substr(pos + 1);
00298             i_res = parse(in, i_exp);
00299             o_res = parse(out, o_exp);
00300           }
00301           else
00302           {
00303             i_res = parse(label, i_exp);
00304             if (label == "0")
00305               return;
00306           }
00307           if ((it = attrs.find("weight")) != attrs.end())
00308               o_res = parse(it->second, o_exp);
00309         }
00310         else // No expression tag, no label attribute.
00311         {
00312           if ((it = attrs.find("in")) != attrs.end())
00313             i_res = parse(it->second, i_exp);
00314           if ((it = attrs.find("out")) != attrs.end())
00315             o_res = parse(it->second, o_exp);
00316         }
00317         tools::assoc_exp(a, i_exp, o_exp, res, i_res.first, o_res.first);
00318       }
00319 
00320 
00321       // Ensuring correct attributes
00322 
00323       inline
00324       void
00325       check_consistency (const xercesc::Attributes& attrs,
00326                          const std::string& kind,
00327                          const char* key,
00328                          const std::string& expected)
00329       {
00330 
00331         // If SeriesSemiring is expected, we can't know what we
00332         // should except.
00333         if (expected == "ratSeries")
00334           return;
00335 
00336         std::string observed = xml2str(get_attribute(attrs, key));
00337 
00338         if (expected != observed)
00339           FAIL(std::string ("invalid ") + kind + ": " + observed
00340                + ", expected: " + expected);
00341       }
00342 
00343       // Getters
00344 
00345       inline
00346       bool
00347       has_attribute (const xercesc::Attributes& attrs,
00348                      const char* key,
00349                      const XMLCh* const uri)
00350       {
00351         return (get_attribute(attrs, key, uri) != 0);
00352       }
00353 
00354       inline
00355       const XMLCh*
00356       get_attribute (const xercesc::Attributes& attrs,
00357                      const char* key,
00358                      const XMLCh* const uri)
00359       {
00360         XMLCh* xkey = transcode(key);
00361         const XMLCh* tmp = attrs.getValue(uri, xkey);
00362         xercesc::XMLString::release(&xkey);
00363         return tmp;
00364       }
00365 
00366       // Labels
00367       template <typename T>
00368       RegExpHandler<T>*
00369       labelh_factory(xercesc::DefaultHandler& root,
00370                      T& aut,
00371                      xercesc::SAX2XMLReader* parser,
00372                      XMLEq& eq,
00373                      const XMLCh* const localname,
00374                      const xercesc::Attributes& attrs)
00375       {
00376         if (xercesc::XMLString::equals(eq.label, localname))
00377           return new LabelHandler<T>(root, aut, parser, eq);
00378 
00379         if (xercesc::XMLString::equals(eq.sum, localname))
00380           return new SumHandler<T>(root, aut, parser, eq);
00381         if (xercesc::XMLString::equals(eq.product, localname))
00382           return new ProdHandler<T>(root, aut, parser, eq);
00383         if (xercesc::XMLString::equals(eq.star, localname))
00384           return new StarHandler<T>(root, aut, parser, eq);
00385 
00386 
00387         if (xercesc::XMLString::equals(eq.word, localname))
00388         {
00389           std::map<std::string, std::string > m;
00390           for (unsigned int i = 0; i < attrs.getLength(); i++)
00391             m[xml2str(attrs.getLocalName(i))] =  xml2str(attrs.getValue(i));
00392           return new WordHandler<T>(root, aut, parser, eq, get_series(aut, m, "value"));
00393         }
00394 
00395         typename T::series_set_elt_t val(aut.structure().series());
00396         if (xercesc::XMLString::equals(eq.identity, localname))
00397           val = vcsn::algebra::identity_as<typename T::series_set_elt_t::value_t>::of(val.structure());
00398         if (xercesc::XMLString::equals(eq.zero, localname))
00399           val = vcsn::algebra::zero_as<typename T::series_set_elt_t::value_t>::of(val.structure());
00400         return new WordHandler<T>(root, aut, parser, eq, val);
00401       }
00402 
00403       template <typename T>
00404       typename T::series_set_elt_t
00405       get_series_transition(T& aut,
00406                             std::map<std::string, std::string>& attrs,
00407                             LabelHandler<T>& labelh)
00408       {
00409         std::map<std::string, std::string>::const_iterator i =
00410           attrs.find("label");
00411         // Uncommment for a future version.
00412         //if (labelh.used() == (i != attrs.end()))
00413         //  FAIL("No labels / or too many labels found.");
00414         return (i != attrs.end() || !labelh.used()) ?
00415           builders::get_series(aut, attrs, "label") :
00416           labelh.value();
00417       }
00418       TParm
00419       typename TRANStype::series_set_elt_t
00420       get_series_transition(TRANStype& aut,
00421                             std::map<std::string, std::string>& attrs,
00422                             LabelHandler<TRANStype>& labelh)
00423       {
00424         std::map<std::string, std::string>::const_iterator i =
00425           attrs.find("in");
00426         std::map<std::string, std::string>::const_iterator o =
00427           attrs.find("out");
00428         bool inout = ((i != attrs.end()) || (o != attrs.end()));
00429         // Uncommment for a future version.
00430         //if (labelh.used() == inout)
00431         //  FAIL("No labels / or too many labels found.");
00432         //if ((i != attrs.end() != (o != attrs.end())))
00433         //  FAIL("Missing in or out attribute.")
00434         return (inout || !labelh.used()) ?
00435           builders::get_series(aut, attrs, "label") :
00436           labelh.value();
00437       }
00438       TParmFMP
00439       typename FMPtype::series_set_elt_t
00440       get_series_transition(FMPtype& aut,
00441                             std::map<std::string, std::string>& attrs,
00442                             LabelHandler<FMPtype>& labelh)
00443       {
00444         std::map<std::string, std::string>::const_iterator i =
00445           attrs.find("in");
00446         std::map<std::string, std::string>::const_iterator o =
00447           attrs.find("out");
00448         bool inout = ((i != attrs.end()) || (o != attrs.end()));
00449         // Uncommment for a future version.
00450         //if (labelh.used() == inout)
00451         //  FAIL("No labels / or too many labels found.");
00452         //if ((i != attrs.end() != (o != attrs.end())))
00453         //  FAIL("Missing in or out attribute.")
00454         return (inout || !labelh.used()) ?
00455           builders::get_series(aut, attrs, "label") :
00456           labelh.value();
00457       }
00458     } // !builders
00459   } // !xml
00460 } // !vcsn
00461 
00462 #endif // !BUILDERS_HXX

Generated on Thu Dec 13 16:02:59 2007 for Vaucanson by  doxygen 1.5.4