- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

# 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