Vaucanson 1.4
fmp.hxx
00001 // fmp.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, 2010 The Vaucanson Group.
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 //
00012 // The complete GNU General Public Licence Notice can be found as the
00013 // `COPYING' file in the root directory.
00014 //
00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
00016 //
00017 
00018 #ifndef VCSN_XML_CONTEXTS_FMP_HXX
00019 # define VCSN_XML_CONTEXTS_FMP_HXX
00020 
00021 # include <vaucanson/xml/builders.hh>
00022 
00023 namespace vcsn
00024 {
00025   namespace xml
00026   {
00030     template <typename T>
00031     FreeMonoidProductHandler<T>::FreeMonoidProductHandler (xercesc::SAX2XMLReader* parser,
00032                                  Handler& root,
00033                                  T& monoid)
00034       : Handler(parser, root),
00035         monoid_(monoid),
00036         unsuph_(parser, *this),
00037         first_(true)
00038     {
00039     }
00040 
00041     template <typename T>
00042     void
00043     FreeMonoidProductHandler<T>::start (const XMLCh* const,
00044                                  const XMLCh* const localname,
00045                                  const XMLCh* const,
00046                                  const xercesc::Attributes& attrs)
00047     {
00048       if (xercesc::XMLString::equals(eq_.monoid, localname))
00049       {
00050         if (first_)
00051         {
00052           monoidh_ = builders::create_monoidh(monoid_.first_monoid(), attrs, parser_, *this);
00053           first_ = false;
00054         }
00055         else
00056         {
00057           delete monoidh_;
00058           monoidh_ = builders::create_monoidh(monoid_.second_monoid(), attrs, parser_, *this);
00059         }
00060         parser_->setContentHandler(monoidh_);
00061       }
00062       else if (xercesc::XMLString::equals(eq_.writingData, localname))
00063       {
00064         algebra::MonoidRep<T> rep;
00065         if (tools::has_attribute(attrs, eq_.identitySymbol))
00066           rep.empty = xmlstr(tools::get_attribute(attrs, eq_.identitySymbol));
00067         if (tools::has_attribute(attrs, eq_.concat))
00068           rep.concat = xmlstr(tools::get_attribute(attrs, eq_.concat));
00069         monoid_.set_representation(rep);
00070         parser_->setContentHandler(&unsuph_);
00071       }
00072       else
00073         error::token(localname);
00074     }
00075 
00076     template <typename T>
00077     void
00078     FreeMonoidProductHandler<T>::end (const XMLCh* const,
00079                                const XMLCh* const localname,
00080                                const XMLCh* const)
00081     {
00082       delete monoidh_;
00083       if (xercesc::XMLString::equals(eq_.monoid, localname))
00084         parser_->setContentHandler(&root_);
00085       else
00086         error::token(localname);
00087     }
00088 
00092     template <typename S, typename M1, typename M2>
00093     SeriesRepresentationHandler<FMPsreptype>::
00094     SeriesRepresentationHandler(xercesc::SAX2XMLReader* parser,
00095                                 Handler& root,
00096                                 FMPsreptype& srep)
00097       : Handler(parser, root),
00098         rep_(srep),
00099         reph_(0),
00100         unsuph_(parser, *this),
00101         first_(true)
00102     {
00103     }
00104 
00105     template <typename S, typename M1, typename M2>
00106     void
00107     SeriesRepresentationHandler<FMPsreptype>::start(const XMLCh* const,
00108                                                     const XMLCh* const localname,
00109                                                     const XMLCh* const,
00110                                                     const xercesc::Attributes& attrs)
00111     {
00112       if (xercesc::XMLString::equals(eq_.writingData, localname))
00113       {
00114         if (first_)
00115         {
00116           reph_ = builders::create_series_representationh(rep_.first_representation(), attrs, parser_, *this, eq_);
00117           first_ = false;
00118         }
00119         else
00120         {
00121           delete reph_;
00122           reph_ = builders::create_series_representationh(rep_.second_representation(), attrs, parser_, *this, eq_);
00123         }
00124         parser_->setContentHandler(reph_);
00125       }
00126       else
00127         error::token(localname);
00128     }
00129 
00130     template <typename S, typename M1, typename M2>
00131     void
00132     SeriesRepresentationHandler<FMPsreptype>::end(const XMLCh* const,
00133                                                   const XMLCh* const localname,
00134                                                   const XMLCh* const)
00135     {
00136       using namespace xercesc;
00137 
00138       delete reph_;
00139       if (XMLString::equals(eq_.writingData, localname))
00140         parser_->setContentHandler(&root_);
00141       else
00142         error::token(localname);
00143     }
00144 
00145     namespace builders
00146     {
00147       TParamFMP
00148       typename FMPtype::monoid_t*
00149       create_monoid (FMPtype& param,
00150                      const XMLCh* const localname,
00151                      const xercesc::Attributes& attrs,
00152                      XMLEq& eq)
00153       {
00154         typename FMPtype::monoid_t::first_monoid_t::alphabet_t  at1;
00155         typename FMPtype::monoid_t::second_monoid_t::alphabet_t at2;
00156         typename FMPtype::monoid_t::first_monoid_t      md1(at1);
00157         typename FMPtype::monoid_t::second_monoid_t     md2(at2);
00158         typedef typename FMPtype::monoid_t              monoid_t;
00159 
00160         monoid_t* monoid = new monoid_t(md1, md2);
00161         builders::check_monoid_consistency(param, localname, attrs, eq);
00162         return monoid;
00163       }
00164 
00165       template <typename M1, typename M2>
00166       Handler*
00167       create_monoidh (vcsn::algebra::FreeMonoidProduct<M1, M2>& monoid,
00168                       const xercesc::Attributes&,
00169                       xercesc::SAX2XMLReader* parser,
00170                       Handler& root)
00171       {
00172         typedef typename vcsn::algebra::FreeMonoidProduct<M1, M2> monoid_t;
00173         return new FreeMonoidProductHandler<monoid_t>(parser, root, monoid);
00174       }
00175     } // !builders
00176 
00177     /*
00178      * ProdMonElmtHandler
00179      */
00180     template <typename T>
00181     ProdMonElmtHandler<T>::ProdMonElmtHandler (xercesc::SAX2XMLReader* parser,
00182                                Handler& root,
00183                                T param)
00184       : RegexpHandler<T>(parser, root, param),
00185         in_(1),
00186         count_(1),
00187         m1_(param.structure().monoid().first_monoid()),
00188         m2_(param.structure().monoid().second_monoid())
00189     {
00190       end_ = eq_.monElmt;
00191     }
00192 
00193     template <typename T>
00194     void
00195     ProdMonElmtHandler<T>::start(const XMLCh* const,
00196                                  const XMLCh* const localname,
00197                                  const XMLCh* const,
00198                                  const xercesc::Attributes& attrs)
00199     {
00200       using namespace xercesc;
00201 
00202       typedef typename T::set_t::monoid_t               monoid_t;
00203       typedef typename monoid_t::first_monoid_t         first_monoid_t;
00204       typedef typename monoid_t::second_monoid_t        second_monoid_t;
00205       typedef typename first_monoid_t::alphabet_t       first_alphabet_t;
00206       typedef typename second_monoid_t::alphabet_t      second_alphabet_t;
00207       typedef typename first_alphabet_t::letter_t       first_letter_t;
00208       typedef typename second_alphabet_t::letter_t      second_letter_t;
00209 
00210       if (XMLString::equals(eq_.monElmt, localname))
00211       {
00212         in_++;
00213         count_++;
00214         if (in_ > 2)
00215           error::token(localname);
00216       }
00217       else if (XMLString::equals(eq_.one, localname) && (in_ == 1))
00218       {
00219         in_++;
00220         count_++;
00221         if (count_ == 2)
00222           m1_ = algebra::identity_as<typename T::monoid_elt_t::first_monoid_elt_value_t>
00223             ::of(param_.structure().monoid().first_monoid());
00224         else if (count_ == 3)
00225           m2_ = algebra::identity_as<typename T::monoid_elt_t::second_monoid_elt_value_t>
00226             ::of(param_.structure().monoid().second_monoid());
00227         else
00228           error::token(localname);
00229       }
00230       else if (XMLString::equals(eq_.monGen, localname))
00231       {
00232         const std::string val(xmlstr(tools::get_attribute(attrs, "value")));
00233         if (in_ == 2 && count_ == 2)
00234         {
00235           std::pair<bool, first_letter_t> tmp =
00236                 parse_letter(m1_.structure().alphabet(), val);
00237           if (tmp.first)
00238             m1_ *= tmp.second;
00239           else
00240             error::attrs(localname, "value", val);
00241         }
00242         else if (in_ == 2 && count_ == 3)
00243         {
00244           std::pair<bool, second_letter_t> tmp =
00245                 parse_letter(m2_.structure().alphabet(), val);
00246           if (tmp.first)
00247             m2_ *= tmp.second;
00248           else
00249             error::attrs(localname, "value", val);
00250         }
00251         else
00252           error::token(localname);
00253       }
00254       else
00255         error::token(localname);
00256     }
00257 
00258     template <typename T>
00259     void
00260     ProdMonElmtHandler<T>::end (const XMLCh* const,
00261                                const XMLCh* const localname,
00262                                const XMLCh* const)
00263     {
00264       using namespace xercesc;
00265       if (XMLString::equals(end_, localname))
00266       {
00267         if (in_ == 1 && count_ == 3)
00268         {
00269           // FIXME awful... but didn't find an easier way.
00270           typename T::monoid_elt_value_t m(m1_.value(), m2_.value());
00271           typename T::semiring_elt_value_t w =
00272             algebra::identity_as<typename T::semiring_elt_value_t>::of(param_.structure().semiring()).value();
00273           param_.assoc(m, w);
00274           parser_->setContentHandler(&root_);
00275         }
00276         in_--;
00277       }
00278       else if (XMLString::equals(eq_.one, localname))
00279         in_--;
00280       else if (!XMLString::equals(eq_.monGen, localname))
00281         error::token(localname);
00282     }
00283 
00284 
00285     namespace builders
00286     {
00287       SParamFMP
00288       RegexpHandler<FMPseries >*
00289       create_monElmth(xercesc::SAX2XMLReader* parser,
00290                       RegexpHandler<FMPseries >& root,
00291                       FMPseries param)
00292       {
00293         return new ProdMonElmtHandler<FMPseries >(parser, root,
00294             algebra::zero_as<typename FMPseries::value_t>::of(param.structure()));
00295       }
00296     } // !builders
00297 
00301     namespace builders
00302     {
00303       TParamFMP
00304       void
00305       check_monoid_consistency (FMPtype&,
00306                                 const XMLCh* const localname,
00307                                 const xercesc::Attributes& attrs,
00308                                 XMLEq&)
00309       {
00310         std::string val(xmlstr(tools::get_attribute(attrs, "type")));
00311         if (val != "product")
00312           error::attrs(localname, "type", val);
00313         val = xmlstr(tools::get_attribute(attrs, "prodDim"));
00314         if (val != "2")
00315           error::attrs(localname, "prodDim", val);
00316       };
00317     } // !builders
00318 
00322     namespace builders
00323     {
00324 
00325 
00326       template <typename S>
00327       void
00328       do_create_type_writingData_node(const S& s,
00329                                       xercesc::DOMDocument* doc,
00330                                       xercesc::DOMElement* root)
00331       {
00332         xercesc::DOMElement* writingData = tools::create_element(doc, "writingData");
00333         tools::set_attribute(writingData, "plusSym", s.representation()->plus);
00334         tools::set_attribute(writingData, "timesSym", s.representation()->times);
00335         tools::set_attribute(writingData, "starSym", s.representation()->star);
00336         tools::set_attribute(writingData, "zeroSym", s.representation()->zero);
00337         tools::set_attribute(writingData, "weightOpening", s.representation()->open_weight);
00338         tools::set_attribute(writingData, "weightClosing", s.representation()->close_weight);
00339         tools::set_attribute(writingData, "openPar", s.representation()->open_par);
00340         tools::set_attribute(writingData, "closePar", s.representation()->close_par);
00341         tools::set_attribute(writingData, "spacesSym", s.representation()->spaces.front());
00342 
00343         xercesc::DOMElement* firstWritingData = tools::create_element(doc, "writingData");
00344         tools::set_attribute(firstWritingData, "plusSym",
00345                              s.representation()->first_representation().plus);
00346         tools::set_attribute(firstWritingData, "timesSym",
00347                              s.representation()->first_representation().times);
00348         tools::set_attribute(firstWritingData, "starSym",
00349                              s.representation()->first_representation().star);
00350         tools::set_attribute(firstWritingData, "zeroSym",
00351                              s.representation()->first_representation().zero);
00352         tools::set_attribute(firstWritingData, "weightOpening",
00353                              s.representation()->first_representation().open_weight);
00354         tools::set_attribute(firstWritingData, "weightClosing",
00355                              s.representation()->first_representation().close_weight);
00356         tools::set_attribute(firstWritingData, "openPar",
00357                              s.representation()->first_representation().open_par);
00358         tools::set_attribute(firstWritingData, "closePar",
00359                              s.representation()->first_representation().close_par);
00360         tools::set_attribute(firstWritingData, "spacesSym",
00361                              s.representation()->first_representation().spaces.front());
00362         writingData->appendChild(firstWritingData);
00363 
00364         xercesc::DOMElement* secondWritingData = tools::create_element(doc, "writingData");
00365         tools::set_attribute(secondWritingData, "plusSym",
00366                              s.representation()->second_representation().plus);
00367         tools::set_attribute(secondWritingData, "timesSym",
00368                              s.representation()->second_representation().times);
00369         tools::set_attribute(secondWritingData, "starSym",
00370                              s.representation()->second_representation().star);
00371         tools::set_attribute(secondWritingData, "zeroSym",
00372                              s.representation()->second_representation().zero);
00373         tools::set_attribute(secondWritingData, "weightOpening",
00374                              s.representation()->second_representation().open_weight);
00375         tools::set_attribute(secondWritingData, "weightClosing",
00376                              s.representation()->second_representation().close_weight);
00377         tools::set_attribute(secondWritingData, "openPar",
00378                              s.representation()->second_representation().open_par);
00379         tools::set_attribute(secondWritingData, "closePar",
00380                              s.representation()->second_representation().close_par);
00381         tools::set_attribute(secondWritingData, "spacesSym",
00382                              s.representation()->second_representation().spaces.front());
00383         writingData->appendChild(secondWritingData);
00384 
00385         root->appendChild(writingData);
00386       }
00387 
00388       TParamFMP
00389       void
00390       create_type_writingData_node(const FMPtype& aut,
00391                                    xercesc::DOMDocument* doc,
00392                                    xercesc::DOMElement* root)
00393       {
00394         do_create_type_writingData_node(aut.series(), doc, root);
00395       }
00396 
00397       TParamFMP
00398       void
00399       create_type_writingData_node(const FMPseries& s,
00400                                    xercesc::DOMDocument* doc,
00401                                    xercesc::DOMElement* root)
00402       {
00403         do_create_type_writingData_node(s.series(), doc, root);
00404       }
00405 
00406       TParamFMP
00407       void
00408       do_create_monoid_node(const vcsn::algebra::Series<S, vcsn::algebra::FreeMonoidProduct<M1, M2> >& s,
00409                             xercesc::DOMDocument* doc,
00410                             xercesc::DOMElement* root)
00411       {
00412         xercesc::DOMElement* node = tools::create_element(doc, "monoid");
00413         tools::set_attribute(node, "type", "product");
00414         tools::set_attribute(node, "prodDim", "2");
00415         root->appendChild(node);
00416 
00417         xercesc::DOMElement* writingData = tools::create_element(doc, "writingData");
00418         tools::set_attribute(writingData, "identitySym", s.monoid().representation()->empty);
00419         tools::set_attribute(writingData, "timesSym", s.monoid().representation()->concat);
00420         node->appendChild(writingData);
00421 
00422         xercesc::DOMElement* first = tools::create_element(doc, "monoid");
00423         tools::set_attribute(first, "type", "free");
00424         tools::set_attribute(first, "genDescrip", "enum");
00425         tools::set_attribute(first, "genKind", algebra::letter_traits<typename M1::alphabet_t::letter_t>::kind());
00426         node->appendChild(first);
00427 
00428         xercesc::DOMElement* writingData1 = tools::create_element(doc, "writingData");
00429         tools::set_attribute(writingData1, "identitySym", s.monoid().first_monoid().representation()->empty);
00430         tools::set_attribute(writingData1, "timesSym", s.monoid().first_monoid().representation()->concat);
00431         first->appendChild(writingData1);
00432 
00433         typedef typename M1::alphabet_t::const_iterator first_alphabet_iterator;
00434         for_all_letters_(first_, l, s.monoid().first_monoid().alphabet())
00435         {
00436           std::ostringstream letter;
00437           xercesc::DOMElement* gen = tools::create_element(doc, "monGen");
00438           letter << *l;
00439           tools::set_attribute(gen, "value", letter.str());
00440           first->appendChild(gen);
00441         }
00442         tools::set_attribute(first, "genSort", get_monoid_gen_sort(*(s.monoid().first_monoid().alphabet().begin())));
00443         xercesc::DOMElement* second = tools::create_element(doc, "monoid");
00444         tools::set_attribute(second, "type", "free");
00445         tools::set_attribute(second, "genDescrip", "enum");
00446         tools::set_attribute(second, "genKind", algebra::letter_traits<typename M2::alphabet_t::letter_t>::kind());
00447         node->appendChild(second);
00448 
00449         xercesc::DOMElement* writingData2 = tools::create_element(doc, "writingData");
00450         tools::set_attribute(writingData2, "identitySym", s.monoid().second_monoid().representation()->empty);
00451         tools::set_attribute(writingData2, "timesSym", s.monoid().second_monoid().representation()->concat);
00452         second->appendChild(writingData2);
00453 
00454         typedef typename M2::alphabet_t::const_iterator second_alphabet_iterator;
00455         for_all_letters_(second_, l, s.monoid().second_monoid().alphabet())
00456         {
00457           std::ostringstream letter;
00458           xercesc::DOMElement* gen = tools::create_element(doc, "monGen");
00459           letter << *l;
00460           tools::set_attribute(gen, "value", letter.str());
00461           second->appendChild(gen);
00462         }
00463         tools::set_attribute(second, "genSort", get_monoid_gen_sort(*(s.monoid().second_monoid().alphabet().begin())));
00464       }
00465 
00466       TParamFMP
00467       void
00468       create_monoid_node(const FMPtype& aut,
00469                          xercesc::DOMDocument* doc,
00470                          xercesc::DOMElement* root)
00471       {
00472         do_create_monoid_node<S,T,M1,M2>(aut.series(), doc, root);
00473       }
00474 
00475       TParamFMP
00476       void
00477       create_monoid_node(const FMPseries& s,
00478                          xercesc::DOMDocument* doc,
00479                          xercesc::DOMElement* root)
00480       {
00481         do_create_monoid_node<S,T,M1,M2>(s.series(), doc, root);
00482       }
00483 
00484 
00485 
00486       /* FIXME there should not be 2 but one function here... however,
00487       ** when we add a template T instead of int the function is not called
00488       ** anymore... there is a probleme in the dispatch */
00489       template <>
00490       void
00491       create_monElmt_node(const std::pair<std::string, std::string>& m,
00492                          xercesc::DOMDocument* doc,
00493                            xercesc::DOMElement* root)
00494       {
00495         xercesc::DOMElement* node;
00496         if (m.first.empty() && m.second.empty())
00497           node = tools::create_element(doc, "one");
00498         else
00499         {
00500           node = tools::create_element(doc, "monElmt");
00501           create_monElmt_node(m.first, doc, node);
00502           create_monElmt_node(m.second, doc, node);
00503         }
00504         root->appendChild(node);
00505       }
00506 
00507       template <>
00508       void
00509       create_monElmt_node(const std::pair<std::basic_string<int>, std::basic_string<int> >& m,
00510                          xercesc::DOMDocument* doc,
00511                            xercesc::DOMElement* root)
00512       {
00513         xercesc::DOMElement* node;
00514         if (m.first.empty() && m.second.empty())
00515           node = tools::create_element(doc, "one");
00516         else
00517         {
00518           node = tools::create_element(doc, "monElmt");
00519           create_monElmt_node(m.first, doc, node);
00520           create_monElmt_node(m.second, doc, node);
00521         }
00522         root->appendChild(node);
00523       }
00524     } // !builders
00525   } // !xml
00526 } // !vcsn
00527 
00528 #endif // !VCSN_XML_CONTEXTS_FMP_HXX