node.hxx

Go to the documentation of this file.
00001 // node.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 The Vaucanson Group.
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 //
00012 // The complete GNU General Public Licence Notice can be found as the
00013 // `COPYING' file in the root directory.
00014 //
00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
00016 //
00017 #ifndef VCSN_XML_NODE_HXX
00018 # define VCSN_XML_NODE_HXX
00019 
00032 namespace vcsn
00033 {
00034   namespace xml
00035   {
00036 
00037     template <class T>
00038     Node<T>::~Node()
00039     {
00040     }
00041 
00042 # define PROCESS_NODE(Name)                                             \
00043     template <class T>                                                  \
00044     void Name ## Node<T>::process(xercesc::DOMElement* node, T& aut,    \
00045                                   typename Node<T>::map_t& m,           \
00046                                   typename Node<T>::factory_t& f)       \
00047     {                                                                   \
00048       using namespace xercesc;                                          \
00049       for (DOMNode* n = node->getFirstChild(); n; n = n->getNextSibling()) \
00050         if (n->getNodeType() == DOMNode::ELEMENT_NODE)                  \
00051         {                                                               \
00052           DOMElement* elt = static_cast<DOMElement*>(n);                \
00053           Node<T>* node = f.create_object(xml2str(elt->getNodeName())); \
00054           node->process(elt, aut, m, f);                                \
00055         }                                                               \
00056     }
00057 
00058     PROCESS_NODE(content)
00059     PROCESS_NODE(labelType)
00060     PROCESS_NODE(states)
00061     PROCESS_NODE(transitions)
00062 
00063 # undef PROCESS_NODE
00064 
00065 # define PROCESS_ROOT_NODE(Name)                                        \
00066     template <class T>                                                  \
00067     void                                                                \
00068     Name ## Node<T>::process(xercesc::DOMElement* node, T& aut,         \
00069                              typename Node<T>::map_t& m,                \
00070                              typename Node<T>::factory_t& f)            \
00071     {                                                                   \
00072       using namespace xercesc;                                          \
00073       bool type_done = false;                                           \
00074       if (node->hasAttribute(transcode("name")))                        \
00075         aut.geometry().name() =                                         \
00076           xml2str(node->getAttribute(transcode("name")));               \
00077       for (DOMNode* n = node->getFirstChild();                          \
00078            n;                                                           \
00079            n = n->getNextSibling())                                     \
00080         if (n->getNodeType() == DOMNode::ELEMENT_NODE)                  \
00081         {                                                               \
00082           DOMElement* elt = static_cast<DOMElement*>(n);                \
00083           if (! type_done)                                              \
00084           {                                                             \
00085             if (XMLString::compareIString(n->getNodeName(),             \
00086                                           transcode("labelType")))      \
00087             {                                                           \
00088               labelTypeNode<T>* node = new labelTypeNode<T>;            \
00089               node->process(0, aut, m, f);                              \
00090             }                                                           \
00091             type_done = true;                                           \
00092           }                                                             \
00093           Node<T>* node = f.create_object(xml2str(elt->getNodeName())); \
00094           node->process(elt, aut, m, f);                                \
00095         }                                                               \
00096     }
00097 
00098     PROCESS_ROOT_NODE(automaton)
00099     PROCESS_ROOT_NODE(transducer)
00100 
00101 # undef PROCESS_ROOT_NODE
00102 
00103 # define PROCESS_TYPE_NODE(TempParam, AutType)                          \
00104     TempParam                                                           \
00105     void                                                                \
00106     labelTypeNode<AutType >::process(xercesc::DOMElement* node,         \
00107                                      AutType& aut,                      \
00108                                      typename Node<AutType >::map_t& m, \
00109                                      typename Node<AutType >::factory_t& f) \
00110     {                                                                   \
00111       using namespace xercesc;                                          \
00112       bool monoid_done = false, semiring_done = false;                  \
00113                                                                         \
00114       if (! node)                                                       \
00115         process_type(node, aut, m, f, monoid_done, semiring_done);      \
00116       else                                                              \
00117         for (DOMNode* n = node->getFirstChild(); n; n = n->getNextSibling()) \
00118           if (n->getNodeType() == DOMNode::ELEMENT_NODE)                \
00119           {                                                             \
00120             DOMElement* elt = static_cast<DOMElement*>(n);              \
00121             process_type(elt, aut, m, f, monoid_done, semiring_done);   \
00122           }                                                             \
00123     }
00124 
00125     PROCESS_TYPE_NODE(TParm,    AUTtype)
00126     PROCESS_TYPE_NODE(TParm,    TRANStype)
00127     PROCESS_TYPE_NODE(TParmFMP, FMPtype)
00128 
00129 # undef PROCESS_TYPE_NODE
00130 
00131 
00132     /*------------.
00133     | <labelType> |
00134     `------------*/
00135     template <class T>
00136     void process_type(xercesc::DOMElement* node, T& aut,
00137                       typename Node<T>::map_t& m,
00138                       typename Node<T>::factory_t& f,
00139                       bool& monoid_done,
00140                       bool& semiring_done)
00141     {
00142       std::string arg;
00143       xercesc::DOMElement* elt;
00144       if (! monoid_done)
00145       {
00146         std::string monoid("monoid");
00147         if (node && xml2str(node->getNodeName()) == monoid)
00148           elt = node;
00149         else
00150           elt = 0;
00151         monoidNode<T>* nd = new monoidNode<T>;
00152         typename T::monoid_t::alphabet_t at;
00153         typename T::monoid_t md(at);
00154         nd->process(elt, aut, md, m, f);
00155         typename T::series_set_t
00156           series(aut.structure().series().semiring(), md);
00157         aut.attach(series);
00158         monoid_done = true;
00159       }
00160       else
00161         if (! semiring_done)
00162         {
00163           std::string semiring("semiring");
00164           if (node && xml2str(node->getNodeName()) == semiring)
00165             elt = node;
00166           else
00167             elt = 0;
00168           semiringNode<T>* nd = new semiringNode<T>;
00169           typename T::semiring_t sg;
00170           nd->process(elt, aut, sg, m, f);
00171           typename T::series_set_t
00172             series(sg, aut.structure().series().monoid());
00173           aut.attach(series);
00174           semiring_done = true;
00175         }
00176     }
00177 
00178 
00179     TParm
00180     void process_type(xercesc::DOMElement* node, TRANStype& aut,
00181                       typename Node<TRANStype>::map_t& m,
00182                       typename Node<TRANStype>::factory_t& f,
00183                       bool& monoid_done,
00184                       bool& semiring_done)
00185     {
00186       std::string arg;
00187       xercesc::DOMElement* elt;
00188       if (! monoid_done)
00189       {
00190         std::string monoid("monoid");
00191         if (node && xml2str(node->getNodeName()) == monoid)
00192           elt = node;
00193         else
00194           elt = 0;
00195         monoidNode<TRANStype>* nd = new monoidNode<TRANStype>;
00196         typename TRANStype::monoid_t::alphabet_t at;
00197         typename TRANStype::monoid_t md(at);
00198         nd->process(elt, aut, md, m, f);
00199         typename TRANStype::series_set_t
00200           series(aut.structure().series().semiring(), md);
00201         aut.attach(series);
00202         monoid_done = true;
00203       }
00204       else
00205         if (! semiring_done)
00206         {
00207           std::string semiring("semiring");
00208           if (node && xml2str(node->getNodeName()) == semiring)
00209             elt = node;
00210           else
00211             elt = 0;
00212           semiringNode<TRANStype>* nd = new semiringNode<TRANStype>;
00213           typename TRANStype::semiring_t::monoid_t::alphabet_t at;
00214           typename TRANStype::semiring_t::monoid_t md(at);
00215           typename TRANStype::semiring_t::semiring_t ssg;
00216           typename TRANStype::semiring_t sg(ssg, md);
00217           nd->process(elt, aut, sg, m, f);
00218           typename TRANStype::series_set_t
00219             series(sg, aut.structure().series().monoid());
00220           aut.attach(series);
00221           semiring_done = true;
00222         }
00223     }
00224 
00225 
00226     TParmFMP
00227     void process_type(xercesc::DOMElement* node, FMPtype& aut,
00228                       typename Node<FMPtype>::map_t& m,
00229                       typename Node<FMPtype>::factory_t& f,
00230                       bool& monoid_done,
00231                       bool& semiring_done)
00232     {
00233       std::string arg;
00234       xercesc::DOMElement* elt;
00235       if (! monoid_done)
00236       {
00237         std::string monoid("monoid");
00238         if (node && xml2str(node->getNodeName()) == monoid)
00239           elt = node;
00240         else
00241           elt = 0;
00242         monoidNode<FMPtype>* nd = new monoidNode<FMPtype>;
00243         typename FMPtype::monoid_t::first_monoid_t::alphabet_t at1;
00244         typename FMPtype::monoid_t::second_monoid_t::alphabet_t at2;
00245         typename FMPtype::monoid_t::first_monoid_t md1(at1);
00246         typename FMPtype::monoid_t::second_monoid_t md2(at2);
00247         typename FMPtype::monoid_t md(md1, md2);
00248         nd->process(elt, aut, md, m, f);
00249         typename FMPtype::series_set_t
00250           series(aut.structure().series().semiring(), md);
00251         aut.attach(series);
00252         monoid_done = true;
00253       }
00254       else
00255         if (! semiring_done)
00256         {
00257           std::string semiring("semiring");
00258           if (node && xml2str(node->getNodeName()) == semiring)
00259             elt = node;
00260           else
00261             elt = 0;
00262           semiringNode<FMPtype>* nd = new semiringNode<FMPtype>;
00263           typename FMPtype::semiring_t sg;
00264           nd->process(elt, aut, sg, m, f);
00265           typename FMPtype::series_set_t
00266             series(sg, aut.structure().series().monoid());
00267           aut.attach(series);
00268           semiring_done = true;
00269         }
00270     }
00271 
00272 
00273     /*--------.
00274     | <state> |
00275     `--------*/
00276     template <class T>
00277     void
00278     stateNode<T>::process(xercesc::DOMElement* node, T& aut,
00279                           typename Node<T>::map_t& m,
00280                           typename Node<T>::factory_t& f)
00281     {
00282       hstate_t state = aut.add_state();
00283       m[xml2str(node->getAttribute(transcode("name")))] = state;
00284       typename Node<T>::map_state_pair_t p(aut.geometry().states(), state);
00285       handle_geometry(node, aut, p, m, f);
00286     }
00287 
00288 
00289     /*-------------.
00290     | <transition> |
00291     `-------------*/
00292     template <class T>
00293     void
00294     transitionNode<T>::process(xercesc::DOMElement* node, T& aut,
00295                                typename Node<T>::map_t& m,
00296                                typename Node<T>::factory_t& f)
00297     {
00298       hstate_t src = m[xml2str(node->getAttribute(transcode("src")))];
00299       hstate_t dst = m[xml2str(node->getAttribute(transcode("dst")))];
00300       typename T::series_set_elt_t s = tools::get_series(node, aut);
00301       htransition_t e = aut.add_series_transition(src, dst, s);
00302       typename Node<T>::map_transition_pair_t p(aut.geometry().transitions(), e);
00303       handle_geometry(node, aut, p, m, f);
00304     }
00305 
00306 
00307     /*----------.
00308     | <initial> |
00309     `----------*/
00310     template <class T>
00311     void
00312     initialNode<T>::process(xercesc::DOMElement* node, T& aut,
00313                             typename Node<T>::map_t& m,
00314                             typename Node<T>::factory_t& f)
00315     {
00316       hstate_t state = m[xml2str(node->getAttribute(transcode("state")))];
00317       typename T::series_set_elt_t s = tools::get_series(node, aut);
00318       aut.set_initial(state, s);
00319       typename Node<T>::map_state_pair_t p(aut.geometry().initials(), state);
00320       handle_geometry(node, aut, p, m, f);
00321     }
00322 
00323 
00324     /*--------.
00325     | <final> |
00326     `--------*/
00327     template <class T>
00328     void
00329     finalNode<T>::process(xercesc::DOMElement* node, T& aut,
00330                           typename Node<T>::map_t& m,
00331                           typename Node<T>::factory_t& f)
00332     {
00333       hstate_t state = m[xml2str(node->getAttribute(transcode("state")))];
00334       typename T::series_set_elt_t s = tools::get_series(node, aut);
00335       aut.set_final(state, s);
00336       typename Node<T>::map_state_pair_t p(aut.geometry().finals(), state);
00337       handle_geometry(node, aut, p, m, f);
00338     }
00339 
00340 
00341     /*-----------.
00342     | <semiring> |
00343     `-----------*/
00344     template <class T>
00345     template <class U>
00346     void
00347     semiringNode<T>::process(xercesc::DOMElement* node, T& a,
00348                              U& param,
00349                              typename Node<T>::map_t&,
00350                              typename Node<T>::factory_t&)
00351     {
00352       tools::ensure_semiring_type(node, a, param);
00353     }
00354 
00355 
00356     TParm
00357     template <class U>
00358     void
00359     semiringNode<TRANStype>::process(xercesc::DOMElement* node, TRANStype& a,
00360                                      U& param,
00361                                      typename Node<TRANStype>::map_t& m,
00362                                      typename Node<TRANStype>::factory_t& f)
00363     {
00364       process_semiring(node, a, param, m, f);
00365     }
00366 
00367 
00368     TParm
00369     void
00370     process_semiring(xercesc::DOMElement* node, TRANStype& a,
00371                      typename TRANStype::semiring_t::semiring_t& param,
00372                      typename Node<TRANStype>::map_t&,
00373                      typename Node<TRANStype>::factory_t&)
00374     {
00375       tools::ensure_semiring_type(node, a, param);
00376     }
00377 
00378     TParm
00379     void
00380     process_semiring(xercesc::DOMElement* node, TRANStype& a,
00381                      typename TRANStype::semiring_t& param,
00382                      typename Node<TRANStype>::map_t& m,
00383                      typename Node<TRANStype>::factory_t& f)
00384     {
00385       using namespace xercesc;
00386       tools::ensure_semiring_type(node, a, param);
00387 
00388       monoidNode<TRANStype>* nd = new monoidNode<TRANStype>;
00389 
00391       if (! node || ! node->getFirstChild())
00392         nd->process(0, a, const_cast<typename TRANStype::semiring_t::monoid_t&>
00393                     (param.monoid()), m, f);
00394       else
00395         for (DOMNode* n = node->getFirstChild(); n; n = n->getNextSibling())
00396           if (n->getNodeType() == DOMNode::ELEMENT_NODE)
00397           {
00398             if (! XMLString::compareIString(n->getNodeName(),
00399                                             transcode("monoid")))
00400               nd->process(static_cast<DOMElement*>(n), a,
00401                           const_cast
00402                           <typename TRANStype::semiring_t::monoid_t&>
00403                           (param.monoid()), m, f);
00404             else
00405             {
00406               semiringNode<TRANStype>* sg = new semiringNode<TRANStype>;
00407               sg->process(static_cast<DOMElement*>(n), a,
00408                           const_cast
00409                           <typename TRANStype::semiring_t::semiring_t&>
00410                           (param.semiring()), m, f);
00411             }
00412           }
00413     }
00414 
00415 
00416     /*---------.
00417     | <monoid> |
00418     `---------*/
00419     // This is only called when param is a free monoid.
00420     template <class T, class U>
00421     void process_monoid(xercesc::DOMElement* node, T& aut,
00422                         U& param,
00423                         typename Node<T>::map_t& m,
00424                         typename Node<T>::factory_t& f)
00425     {
00426       using namespace xercesc;
00427 
00428       tools::ensure_monoid_type(node, param);
00429 
00430       // Default case, if there is no label tag.
00431       // Here, implicitAlphabet range case is the default.
00432       if (! node)
00433       {
00434         for (unsigned int i = 'a'; i <= 'z'; ++i)
00435           param.alphabet().insert(i);
00436         for (unsigned int i = 'A'; i <= 'Z'; ++i)
00437           param.alphabet().insert(i);
00438       }
00439       else
00440         for (DOMNode* n = node->getFirstChild(); n; n = n->getNextSibling())
00441           if (n->getNodeType() == DOMNode::ELEMENT_NODE)
00442           {
00443             DOMElement* elt = static_cast<DOMElement*>(n);
00444 
00445             // Fill the alphabet if a range attribute exists.
00446             if (elt->hasAttribute(transcode("range")))
00447             {
00448               if (xml2str(elt->getAttribute(transcode("range"))) == "implicitAlphabet")
00449               {
00450                 for (unsigned int i = 'a'; i <= 'z'; ++i)
00451                   param.alphabet().insert(i);
00452                 for (unsigned int i = 'A'; i <= 'Z'; ++i)
00453                   param.alphabet().insert(i);
00454               }
00455               if (xml2str(elt->getAttribute(transcode("range"))) == "digits")
00456                 for (unsigned int i = '0'; i <= '9'; ++i)
00457                   param.alphabet().insert(i);
00458               if (xml2str(elt->getAttribute(transcode("range"))) == "ascii")
00459                 for (unsigned char c = 0; c <= 127; ++c)
00460                   param.alphabet().insert(c);
00461             }
00462             // Else, add single letters.
00463             else
00464             {
00465               generatorNode<T>* nd = static_cast<generatorNode<T>*>
00466                 (f.create_object(xml2str(elt->getNodeName())));
00467               nd->process(elt, aut, param.alphabet(), m, f);
00468             }
00469           }
00470     }
00471 
00472     template <class T>
00473     template <class U>
00474     void
00475     monoidNode<T>::process(xercesc::DOMElement* node, T& aut,
00476                            U& param,
00477                            typename Node<T>::map_t& m,
00478                            typename Node<T>::factory_t& f)
00479     {
00480       process_monoid(node, aut, param, m, f);
00481     }
00482 
00483 
00484     template <class T>
00485     template <class U>
00486     void
00487     freemonoidNode<T>::process(xercesc::DOMElement* node, T& aut,
00488                                U& param,
00489                                typename Node<T>::map_t& m,
00490                                typename Node<T>::factory_t& f)
00491     {
00492       process_monoid(node, aut, param, m, f);
00493     }
00494 
00495 
00496     TParmFMP
00497     template <class U>
00498     void
00499     monoidNode<FMPtype>::process(xercesc::DOMElement* node, FMPtype& aut,
00500                                  U& param,
00501                                  typename Node<FMPtype>::map_t& m,
00502                                  typename Node<FMPtype>::factory_t& f)
00503     {
00504       using namespace xercesc;
00505       bool first = true;
00506 
00507       tools::ensure_monoid_type(node, param);
00508 
00509       if (! node || ! node->getFirstChild())
00510       {
00511         freemonoidNode<FMPtype>* nd_first = new freemonoidNode<FMPtype>;
00512         freemonoidNode<FMPtype>* nd_snd = new freemonoidNode<FMPtype>;
00513         nd_first->process(0, aut, param.first_monoid(), m, f);
00514         nd_snd->process(0, aut, param.second_monoid(), m, f);
00515       }
00516       else
00517         for (DOMNode* n = node->getFirstChild(); n; n = n->getNextSibling())
00518           if (n->getNodeType() == DOMNode::ELEMENT_NODE)
00519           {
00520             DOMElement* elt = static_cast<DOMElement*>(n);
00521             freemonoidNode<FMPtype>* nd = new freemonoidNode<FMPtype>;
00522             if (first)
00523             {
00524               nd->process(elt, aut, param.first_monoid(), m, f);
00525               first = false;
00526             }
00527             else
00528               nd->process(elt, aut, param.second_monoid(), m, f);
00529           }
00530     }
00531 
00532 
00533     /*------------.
00534     | <generator> |
00535     `------------*/
00536     template <class T>
00537     template <class U>
00538     void
00539     generatorNode<T>::process(xercesc::DOMElement* node, T&,
00540                               U& param,
00541                               typename Node<T>::map_t&,
00542                               typename Node<T>::factory_t&)
00543     {
00544       tools::insert_letter(param,
00545                            xml2str(node->getAttribute(transcode("value"))));
00546     }
00547 
00548 
00549     /*-----------.
00550     | <geometry> |
00551     `-----------*/
00552     template <class T>
00553     template <class U>
00554     void
00555     geometryNode<T>::process(xercesc::DOMElement* node, T&,
00556                              U& param,
00557                              typename Node<T>::map_t&,
00558                              typename Node<T>::factory_t&)
00559     {
00560       double x, y;
00561       if (node->hasAttribute(transcode("x")) && node->hasAttribute(transcode("y")))
00562       {
00563         std::istringstream xstr(xml2str(node->getAttribute(transcode("x"))));
00564         std::istringstream ystr(xml2str(node->getAttribute(transcode("y"))));
00565         xstr >> x;
00566         ystr >> y;
00567         param.first[param.second] = std::make_pair(x, y);
00568       }
00570     }
00571 
00572 
00573     /*----------.
00574     | <drawing> |
00575     `----------*/
00576     template <class T>
00577     template <class U>
00578     void
00579     drawingNode<T>::process(xercesc::DOMElement* node, T&,
00580                             U& param,
00581                             typename Node<T>::map_t&,
00582                             typename Node<T>::factory_t&)
00583     {
00584       double x, y;
00585       if (node->hasAttribute(transcode("labelPositionX")) &&
00586           node->hasAttribute(transcode("labelPositionY")))
00587       {
00590         std::istringstream
00591           xstr(xml2str(node->getAttribute(transcode("labelPositionX"))));
00592         std::istringstream
00593           ystr(xml2str(node->getAttribute(transcode("labelPositionY"))));
00594         xstr >> x;
00595         ystr >> y;
00596         param.first[param.second] = std::make_pair(x, y);
00597       }
00598     }
00599 
00600 
00601     template <class T, class U>
00602     void
00603     handle_geometry(xercesc::DOMElement* node, T& aut,
00604                     U& param,
00605                     typename Node<T>::map_t& m,
00606                     typename Node<T>::factory_t& f)
00607     {
00608       std::string geometry("geometry");
00609       std::string drawing("drawing");
00610 
00611       using namespace xercesc;
00612       for (DOMNode* n = node->getFirstChild(); n; n = n->getNextSibling())
00613         if (n->getNodeType() == DOMNode::ELEMENT_NODE)
00614         {
00615           if (xml2str(n->getNodeName()) == geometry)
00616           {
00617             geometryNode<T>* nd = new geometryNode<T>;
00618             nd->process(static_cast<DOMElement*>(n), aut, param, m, f);
00619           }
00620           else if (xml2str(n->getNodeName()) == drawing)
00621           {
00622             drawingNode<T>* nd = new drawingNode<T>;
00623             nd->process(static_cast<DOMElement*>(n), aut, param, m, f);
00624           }
00625         }
00626     }
00627 
00628 
00629   } // ! xml
00630 
00631 } // !vcsn
00632 
00633 #endif // ! VCSN_XML_NODE_HXX

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