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

Generated on Sat Jul 29 17:13:09 2006 for Vaucanson by  doxygen 1.4.6