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

# 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