1 // Copyright (C) 2006-2019 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #ifndef _LOOPPARSER_HXX_
21 #define _LOOPPARSER_HXX_
23 #include "parserBase.hxx"
28 #include "Exception.hxx"
29 #include "InlineNode.hxx"
30 #include "ServiceNode.hxx"
31 #include "ServiceInlineNode.hxx"
32 #include "OutputDataStreamPort.hxx"
33 #include "InputDataStreamPort.hxx"
34 #include "ForLoop.hxx"
35 #include "WhileLoop.hxx"
37 #include "ForEachLoop.hxx"
38 #include "OptimizerLoop.hxx"
47 template <class T=ENGINE::Loop*>
48 struct looptypeParser:parser
50 virtual void onStart(const XML_Char* el, const XML_Char** attr);
51 virtual void onEnd(const char *el,parser* child);
52 virtual void buildAttr(const XML_Char** attr);
54 virtual void name (const std::string& name);
55 virtual void state (const std::string& name);
56 virtual void property (const myprop& prop);
57 virtual void inline_ (ENGINE::InlineNode* const& n);
58 virtual void sinline (ENGINE::ServiceInlineNode* const& n);
59 virtual void service (ENGINE::ServiceNode* const& n);
60 virtual void server (ENGINE::ServerNode* const& n);
61 virtual void remote (ENGINE::InlineNode* const& n);
62 virtual void node (ENGINE::InlineNode* const& n);
63 virtual void forloop (ENGINE::ForLoop* const& b);
64 virtual void foreach (ENGINE::ForEachLoop* const& b);
65 virtual void foreachdyn (ENGINE::ForEachLoopDyn* const& b);
66 virtual void optimizer (ENGINE::OptimizerLoop* const& b);
67 virtual void while_ (ENGINE::WhileLoop* const& b);
68 virtual void switch_ (ENGINE::Switch* const& b);
69 virtual void bloc (ENGINE::Bloc* const& b);
70 virtual void datalink (const mylink& l);
73 std::vector<T> _cnodes;
80 // A loop can contain forloop, whileloop or foreachloop
81 // We must respect the order : definition of loop, then while, for, .. and then onStart, onEnd for loop !!!
83 static std::string t3[]={"inline","sinline","service","server", "remote", "node","forloop","foreach","optimizer","while","switch","bloc",""};
86 void looptypeParser<T>::buildAttr(const XML_Char** attr)
90 this->required("name",attr);
91 for (int i = 0; attr[i]; i += 2)
93 if(std::string(attr[i]) == "name")name(attr[i+1]);
94 if(std::string(attr[i]) == "state")state(attr[i+1]);
98 void looptypeParser<T>::pre ()
104 void looptypeParser<T>::name (const std::string& name)
106 DEBTRACE( "bloc_name: " << name );
109 void looptypeParser<T>::state (const std::string& name)
111 DEBTRACE( "bloc_state: " << name );
115 void looptypeParser<T>::property (const myprop& prop)
117 DEBTRACE( "property_set" << prop._name << prop._value );
121 void looptypeParser<T>::inline_ (ENGINE::InlineNode* const& n)
123 DEBTRACE( "loop_inline" << n->getName() );
124 _cnode->edSetNode(n);
125 std::string fullname=currentProc->names.back()+ n->getName();
126 currentProc->nodeMap[fullname]=n;
127 currentProc->inlineMap[fullname]=n;
130 void looptypeParser<T>::sinline (ENGINE::ServiceInlineNode* const& n)
132 DEBTRACE( "loop_sinline" << n->getName() )
133 _cnode->edSetNode(n);
134 std::string fullname=currentProc->names.back()+ n->getName();
135 currentProc->nodeMap[fullname]=n;
136 currentProc->serviceMap[fullname]=n;
139 void looptypeParser<T>::service (ENGINE::ServiceNode* const& n)
141 DEBTRACE( "loop_service" << n->getName() )
142 _cnode->edSetNode(n);
143 std::string fullname=currentProc->names.back()+ n->getName();
144 currentProc->nodeMap[fullname]=n;
145 currentProc->serviceMap[fullname]=n;
148 void looptypeParser<T>::server (ENGINE::ServerNode* const& n)
150 DEBTRACE( "loop_server" << n->getName() )
151 _cnode->edSetNode(n);
152 std::string fullname=currentProc->names.back()+ n->getName();
153 currentProc->nodeMap[fullname]=n;
154 currentProc->inlineMap[fullname]=n;
158 void looptypeParser<T>::remote (YACS::ENGINE::InlineNode* const& n)
160 DEBTRACE( "loop_remote: " << n->getName() )
161 _cnode->edSetNode(n);
162 std::string fullname = currentProc->names.back()+n->getName();
163 currentProc->nodeMap[fullname]=n;
164 currentProc->inlineMap[fullname]=n;
168 void looptypeParser<T>::node (ENGINE::InlineNode* const& n)
170 DEBTRACE( "loop_node" << n->getName() )
171 _cnode->edSetNode(n);
172 std::string fullname=currentProc->names.back()+ n->getName();
173 currentProc->nodeMap[fullname]=n;
174 currentProc->inlineMap[fullname]=n;
177 void looptypeParser<T>::forloop (ENGINE::ForLoop* const& b)
179 DEBTRACE( "loop_forloop" << b->getName() )
180 _cnode->edSetNode(b);
181 std::string fullname=currentProc->names.back()+ b->getName();
182 currentProc->nodeMap[fullname]=b;
185 void looptypeParser<T>::foreach (ENGINE::ForEachLoop* const& b)
187 DEBTRACE("loop_foreach" << b->getName())
188 _cnode->edSetNode(b);
189 std::string fullname=currentProc->names.back()+ b->getName();
190 currentProc->nodeMap[fullname]=b;
191 fullname += ".splitter";
192 currentProc->nodeMap[fullname]=b->getChildByShortName("splitter");
195 void looptypeParser<T>::foreachdyn (ENGINE::ForEachLoopDyn* const& b)
197 DEBTRACE("loop_foreachdyn" << b->getName())
198 _cnode->edSetNode(b);
199 std::string fullname=currentProc->names.back()+ b->getName();
200 currentProc->nodeMap[fullname]=b;
201 fullname += ".splitter";
202 currentProc->nodeMap[fullname]=b->getChildByShortName("splitter");
205 void looptypeParser<T>::optimizer (ENGINE::OptimizerLoop* const& b)
207 DEBTRACE( "loop_optimizer: " << b->getName() );
208 _cnode->edSetNode(b);
209 std::string fullname = currentProc->names.back()+b->getName();
210 currentProc->nodeMap[fullname]=b;
211 //fullname += ".splitter";
212 //currentProc->nodeMap[fullname]=b->getChildByShortName("splitter");
215 void looptypeParser<T>::while_ (ENGINE::WhileLoop* const& b)
217 DEBTRACE( "loop_while: " << b->getName() )
218 _cnode->edSetNode(b);
219 std::string fullname=currentProc->names.back()+ b->getName();
220 currentProc->nodeMap[fullname]=b;
223 void looptypeParser<T>::switch_ (ENGINE::Switch* const& b)
225 DEBTRACE( "loop_switch: " << b->getName() )
226 _cnode->edSetNode(b);
227 std::string fullname=currentProc->names.back()+ b->getName();
228 currentProc->nodeMap[fullname]=b;
231 void looptypeParser<T>::bloc (ENGINE::Bloc* const& b)
233 DEBTRACE( "loop_bloc " << b->getName() )
234 _cnode->edSetNode(b);
235 std::string fullname=currentProc->names.back()+ b->getName();
236 currentProc->nodeMap[fullname]=b;
240 void looptypeParser<T>::datalink (const mylink& l)
242 DEBTRACE( "loop_datalink: " << l.fromnode() << l.fromport() << l.tonode() << l.toport())
245 //Try only relative name for from node
246 std::string fromname = currentProc->names.back()+l.fromnode();
247 if(currentProc->nodeMap.count(fromname) == 0)
249 msg="from node " + l.fromnode() + " does not exist in data link: ";
250 msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")";
254 //Try relative name for to node and then absolute one
255 std::string toname = currentProc->names.back()+l.tonode();
256 if(currentProc->nodeMap.count(toname) == 0)
258 //It's not a relative name. Try an absolute one (I think it's not possible)
260 if(currentProc->nodeMap.count(toname) == 0)
262 // The TO node does not exist -> error
263 msg="to node " + l.tonode() + " does not exist in data link: ";
264 msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")";
269 // We only link local node and other nodes (relative or absolute name in this order)
270 DEBTRACE(fromname <<":"<<l.fromport()<<toname<<":"<<l.toport());
274 _cnode->edAddDFLink(currentProc->nodeMap[fromname]->getOutputPort(l.fromport()),
275 currentProc->nodeMap[toname]->getInputPort(l.toport()));
277 _cnode->edAddLink(currentProc->nodeMap[fromname]->getOutputPort(l.fromport()),
278 currentProc->nodeMap[toname]->getInputPort(l.toport()));
282 this->logError(e.what());
292 // While loop specialization
294 template <class T=ENGINE::WhileLoop*>
295 struct whilelooptypeParser:looptypeParser<T>
297 static whilelooptypeParser<T> whileloopParser;
298 virtual void name (const std::string& name);
302 template <class T> whilelooptypeParser<T> whilelooptypeParser<T>::whileloopParser;
305 void whilelooptypeParser<T>::name (const std::string& name)
307 DEBTRACE( "while_name: " << name )
308 std::string fullname=currentProc->names.back()+name;
309 this->_cnode=theRuntime->createWhileLoop(name);
310 currentProc->nodeMap[fullname]=this->_cnode;
311 this->_cnodes.push_back(this->_cnode);
312 currentProc->names.push_back(fullname+'.');
316 T whilelooptypeParser<T>::post()
318 DEBTRACE( "while_post" << this->_cnode->getName() )
319 ENGINE::InputPort *cond=this->_cnode->edGetConditionPort();
322 this->_cnodes.pop_back();
323 currentProc->names.pop_back();
324 this->_cnode=this->_cnodes.empty() ? 0 : this->_cnodes.back();
334 // For loop specialization
336 template <class T=ENGINE::ForLoop*>
337 struct forlooptypeParser:looptypeParser<T>
339 static forlooptypeParser<T> forloopParser;
340 virtual void buildAttr(const XML_Char** attr);
341 virtual void name (const std::string& name);
342 virtual void nsteps (const int& n);
347 template <class T> forlooptypeParser<T> forlooptypeParser<T>::forloopParser;
350 void forlooptypeParser<T>::buildAttr(const XML_Char** attr)
354 this->required("name",attr);
355 for (int i = 0; attr[i]; i += 2)
357 if(std::string(attr[i]) == "name")name(attr[i+1]);
358 if(std::string(attr[i]) == "state")this->state(attr[i+1]);
359 if(std::string(attr[i]) == "nsteps")nsteps(atoi(attr[i+1]));
364 void forlooptypeParser<T>::name (const std::string& name)
366 DEBTRACE( "forloop_name: " << name );
367 std::string fullname=currentProc->names.back()+name;
368 this->_cnode=theRuntime->createForLoop(name);
369 currentProc->nodeMap[fullname]=this->_cnode;
370 this->_cnodes.push_back(this->_cnode);
371 currentProc->names.push_back(fullname+'.');
376 void forlooptypeParser<T>::nsteps (const int& n)
378 DEBTRACE( "forloop_nsteps: " << n )
380 throw Exception("Node name must be defined before nsteps");
381 ENGINE::InputPort *iNbTimes=this->_cnode->edGetNbOfTimesInputPort();
386 T forlooptypeParser<T>::post()
388 DEBTRACE( "forloop_post" )
390 this->_cnodes.pop_back();
391 currentProc->names.pop_back();
392 this->_cnode=this->_cnodes.empty() ? 0 : this->_cnodes.back();
400 // pseudo composed node, used to store the init or finalize node of a DynParaLoop
401 class PseudoComposedNode
404 void edSetNode(ENGINE::Node * node) { _node = node; }
405 ENGINE::Node * getNode() { return _node; }
407 // Those two methods should never be called
408 bool edAddLink(ENGINE::OutPort *start, ENGINE::InPort *end) throw(Exception) { YASSERT(false); }
409 bool edAddDFLink(ENGINE::OutPort *start, ENGINE::InPort *end) throw(Exception) { YASSERT(false); }
412 ENGINE::Node * _node;
415 // pseudo composed node parser specialization for DynParaLoop init and finalize nodes
416 template <class T=PseudoComposedNode*>
417 struct pseudocomposednodetypeParser:looptypeParser<T>
419 static pseudocomposednodetypeParser<T> pseudocomposednodeParser;
421 virtual void buildAttr(const XML_Char** attr)
423 this->_cnode = new PseudoComposedNode();
424 this->_cnodes.push_back(this->_cnode);
429 DEBTRACE("pseudocomposednode_post" << this->_cnode->getNode()->getName())
431 this->_cnodes.pop_back();
432 this->_cnode=this->_cnodes.empty() ? 0 : this->_cnodes.back();
436 virtual void datalink(const mylink & l)
438 throw YACS::Exception("Unexpected datalink element in DynParaLoop init or finalize node");
443 template <class T> pseudocomposednodetypeParser<T> pseudocomposednodetypeParser<T>::pseudocomposednodeParser;
449 // dynparaloop specialization
451 template <class T=ENGINE::DynParaLoop*>
452 struct dynparalooptypeParser:looptypeParser<T>
454 virtual void onStart(const XML_Char* el, const XML_Char** attr)
456 DEBTRACE( "dynparalooptypeParser::onStart: " << el )
457 std::string element(el);
458 this->maxcount("initnode",1,element);
459 this->maxcount("finalizenode",1,element);
460 if (element == "initnode" || element == "finalizenode")
462 parser* pp = &pseudocomposednodetypeParser<>::pseudocomposednodeParser;
463 this->SetUserDataAndPush(pp);
470 this->looptypeParser<T>::onStart(el, attr);
474 virtual void onEnd(const char *el, parser* child)
476 DEBTRACE( "dynparalooptypeParser::onEnd: " << el )
477 std::string element(el);
478 if (element == "initnode") initnode(((pseudocomposednodetypeParser<>*)child)->post());
479 else if (element == "finalizenode") finalizenode(((pseudocomposednodetypeParser<>*)child)->post());
480 else this->looptypeParser<T>::onEnd(el, child);
483 virtual void initnode(PseudoComposedNode * const& n)
485 DEBTRACE( "dynparaloop_initnode: " << n->getNode()->getName() )
486 this->_cnode->edSetInitNode(n->getNode());
490 virtual void finalizenode(PseudoComposedNode * const& n)
492 DEBTRACE( "dynparaloop_finalizenode: " << n->getNode()->getName() )
493 this->_cnode->edSetFinalizeNode(n->getNode());
502 // Foreach loop specialization
504 template <class T=ENGINE::ForEachLoop*>
505 struct foreachlooptypeParser:dynparalooptypeParser<T>
507 static foreachlooptypeParser<T> foreachloopParser;
509 virtual void buildAttr(const XML_Char** attr)
513 this->required("name",attr);
514 this->required("type",attr);
515 for (int i = 0; attr[i]; i += 2)
517 if(std::string(attr[i]) == "name")name(attr[i+1]);
518 if(std::string(attr[i]) == "state")this->state(attr[i+1]);
519 if(std::string(attr[i]) == "nbranch")nbranch(atoi(attr[i+1]));
520 if(std::string(attr[i]) == "loopWeight")weight(atof(attr[i+1]));
521 if(std::string(attr[i]) == "type")datatype(attr[i+1]);
529 this->looptypeParser<T>::pre();
531 virtual void name (const std::string& name)
533 DEBTRACE("foreach_name: " << name)
535 _fullname=currentProc->names.back()+name;
537 virtual void nbranch (const int& n)
539 DEBTRACE("foreach_nbranch: " << n )
542 virtual void weight (const double& x)
544 DEBTRACE("foreach_weight: " << x )
547 virtual void datatype (const std::string& type)
549 DEBTRACE("foreach_datatype: "<< type)
552 virtual void postAttr()
554 if(currentProc->typeMap.count(_datatype)==0)
556 //Check if the typecode is defined in the runtime
557 YACS::ENGINE::TypeCode* t=theRuntime->getTypeCode(_datatype);
560 std::stringstream msg;
561 msg << "Type "<< _datatype <<" does not exist"<<" ("<<__FILE__<<":"<<__LINE__<< ")";
562 throw Exception(msg.str());
566 currentProc->typeMap[_datatype]=t;
570 this->_cnode=theRuntime->createForEachLoop(_name,currentProc->typeMap[_datatype]);
571 //set number of branches
572 if(_nbranch > 0)this->_cnode->edGetNbOfBranchesPort()->edInit(_nbranch);
573 if(_weight > 0)this->_cnode->setWeight(_weight);
574 this->_cnodes.push_back(this->_cnode);
575 currentProc->names.push_back(_fullname + '.');
579 DEBTRACE("foreach_post" << this->_cnode->getName())
581 this->_cnodes.pop_back();
582 currentProc->names.pop_back();
583 this->_cnode=this->_cnodes.empty() ? 0 : this->_cnodes.back();
588 std::string _fullname;
590 std::string _datatype;
593 template <class T> foreachlooptypeParser<T> foreachlooptypeParser<T>::foreachloopParser;
596 template <class T=ENGINE::ForEachLoopDyn*>
597 struct foreachloopdyntypeParser:dynparalooptypeParser<T>
599 static foreachloopdyntypeParser<T> foreachloopdynParser;
601 virtual void buildAttr(const XML_Char** attr)
605 this->required("name",attr);
606 this->required("type",attr);
607 for (int i = 0; attr[i]; i += 2)
609 if(std::string(attr[i]) == "name")name(attr[i+1]);
610 if(std::string(attr[i]) == "state")this->state(attr[i+1]);
611 if(std::string(attr[i]) == "nbranch")nbranch(atoi(attr[i+1]));
612 if(std::string(attr[i]) == "loopWeight")weight(atof(attr[i+1]));
613 if(std::string(attr[i]) == "type")datatype(attr[i+1]);
621 this->looptypeParser<T>::pre();
623 virtual void name (const std::string& name)
625 DEBTRACE("foreach_name: " << name)
627 _fullname=currentProc->names.back()+name;
629 virtual void nbranch (const int& n)
631 DEBTRACE("foreach_nbranch: " << n )
634 virtual void weight (const double& x)
636 DEBTRACE("foreach_weight: " << x )
639 virtual void datatype (const std::string& type)
641 DEBTRACE("foreach_datatype: "<< type)
644 virtual void postAttr()
646 if(currentProc->typeMap.count(_datatype)==0)
648 //Check if the typecode is defined in the runtime
649 YACS::ENGINE::TypeCode* t=theRuntime->getTypeCode(_datatype);
652 std::stringstream msg;
653 msg << "Type "<< _datatype <<" does not exist"<<" ("<<__FILE__<<":"<<__LINE__<< ")";
654 throw Exception(msg.str());
658 currentProc->typeMap[_datatype]=t;
662 this->_cnode=theRuntime->createForEachLoopDyn(_name,currentProc->typeMap[_datatype]);
663 //set number of branches
664 if(_nbranch > 0)this->_cnode->edGetNbOfBranchesPort()->edInit(_nbranch);
665 if(_weight > 0)this->_cnode->setWeight(_weight);
666 this->_cnodes.push_back(this->_cnode);
667 currentProc->names.push_back(_fullname + '.');
671 DEBTRACE("foreach_post" << this->_cnode->getName())
673 this->_cnodes.pop_back();
674 currentProc->names.pop_back();
675 this->_cnode=this->_cnodes.empty() ? 0 : this->_cnodes.back();
680 std::string _fullname;
682 std::string _datatype;
685 template <class T> foreachloopdyntypeParser<T> foreachloopdyntypeParser<T>::foreachloopdynParser;
690 // optimizer loop specialization
692 template <class T=ENGINE::OptimizerLoop*>
693 struct optimizerlooptypeParser:dynparalooptypeParser<T>
695 static optimizerlooptypeParser<T> optimizerloopParser;
697 virtual void buildAttr(const XML_Char** attr)
701 this->required("name",attr);
702 this->required("lib",attr);
703 this->required("entry",attr);
704 for (int i = 0; attr[i]; i += 2)
706 if(std::string(attr[i]) == "name")name(attr[i+1]);
707 if(std::string(attr[i]) == "state")this->state(attr[i+1]);
708 if(std::string(attr[i]) == "nbranch")nbranch(atoi(attr[i+1]));
709 if(std::string(attr[i]) == "loopWeight")weight(atof(attr[i+1]));
710 if(std::string(attr[i]) == "lib")lib(attr[i+1]);
711 if(std::string(attr[i]) == "entry")entry(attr[i+1]);
712 if(std::string(attr[i]) == "kind")kind(attr[i+1]);
720 this->looptypeParser<T>::pre();
722 virtual void name (const std::string& name)
724 DEBTRACE("optimizer_name: " << name)
726 _fullname=currentProc->names.back()+name;
728 virtual void lib (const std::string& name)
732 virtual void entry (const std::string& name)
736 virtual void nbranch (const int& n)
738 DEBTRACE("optimizer_nbranch: " << n )
741 virtual void weight (const double& x)
743 DEBTRACE("foreach_weight: " << x )
746 virtual void kind (const std::string& name)
750 virtual void postAttr()
752 this->_cnode=theRuntime->createOptimizerLoop(_name,_lib,_entry,true,_kind, currentProc);
753 //set number of branches
754 if(_nbranch > 0)this->_cnode->edGetNbOfBranchesPort()->edInit(_nbranch);
755 if(_weight > 0)this->_cnode->setWeight(_weight);
756 this->_cnodes.push_back(this->_cnode);
757 currentProc->names.push_back(_fullname + '.');
761 DEBTRACE("optimizer_post" << this->_cnode->getName())
763 this->_cnodes.pop_back();
764 currentProc->names.pop_back();
765 this->_cnode=this->_cnodes.empty() ? 0 : this->_cnodes.back();
771 std::string _fullname;
779 template <class T> optimizerlooptypeParser<T> optimizerlooptypeParser<T>::optimizerloopParser;
783 #include "blocParsers.hxx"
784 #include "switchParsers.hxx"
790 void looptypeParser<T>::onStart(const XML_Char* el, const XML_Char** attr)
792 DEBTRACE( "looptypeParser::onStart: " << el )
793 std::string element(el);
794 this->maxcount("inline",1,element);
795 this->maxcount("sinline",1,element);
796 this->maxcount("service",1,element);
797 this->maxcount("server",1,element);
798 this->maxcount("remote",1,element);
799 this->maxcount("node",1,element);
800 this->maxcount("forloop",1,element);
801 this->maxcount("foreach",1,element);
802 this->maxcount("foreachdyn",1,element);
803 this->maxcount("optimizer",1,element);
804 this->maxcount("while",1,element);
805 this->maxcount("switch",1,element);
806 this->maxcount("bloc",1,element);
807 this->maxchoice(t3,1,element);
808 parser* pp=&parser::main_parser;
809 if(element == "property")pp=&propertytypeParser::propertyParser;
810 else if(element == "inline")pp=&inlinetypeParser<>::inlineParser;
811 else if(element == "sinline")pp=&sinlinetypeParser<>::sinlineParser;
812 else if(element == "service")pp=&servicetypeParser<>::serviceParser;
813 else if(element == "server")pp=&servertypeParser<>::serverParser;
814 else if(element == "remote")pp=&remotetypeParser<>::remoteParser;
815 else if(element == "node")pp=&nodetypeParser<>::nodeParser;
817 else if(element == "forloop")pp=&forlooptypeParser<>::forloopParser;
818 else if(element == "foreach")pp=&foreachlooptypeParser<>::foreachloopParser;
819 else if(element == "foreachdyn")pp=&foreachloopdyntypeParser<>::foreachloopdynParser;
820 else if(element == "optimizer")pp=&optimizerlooptypeParser<>::optimizerloopParser;
821 else if(element == "while")pp=&whilelooptypeParser<>::whileloopParser;
822 else if(element == "switch")pp=&switchtypeParser::switchParser;
823 else if(element == "bloc")pp=&bloctypeParser<>::blocParser;
824 else if(element == "datalink")pp=&linktypeParser<>::linkParser;
825 this->SetUserDataAndPush(pp);
832 void looptypeParser<T>::onEnd(const char *el,parser* child)
834 DEBTRACE( "looptypeParser::onEnd: " << el )
835 std::string element(el);
836 if(element == "property")property(((propertytypeParser*)child)->post());
837 else if(element == "inline")inline_(((inlinetypeParser<>*)child)->post());
838 else if(element == "sinline")sinline(((sinlinetypeParser<>*)child)->post());
839 else if(element == "service")service(((servicetypeParser<>*)child)->post());
840 else if(element == "server")server(((servertypeParser<>*)child)->post());
841 else if(element == "remote")remote(((remotetypeParser<>*)child)->post());
842 else if(element == "node")node(((nodetypeParser<>*)child)->post());
844 else if(element == "forloop")forloop(((forlooptypeParser<>*)child)->post());
845 else if(element == "foreach")foreach(((foreachlooptypeParser<>*)child)->post());
846 else if(element == "foreachdyn")foreachdyn(((foreachloopdyntypeParser<>*)child)->post());
847 else if(element == "optimizer")optimizer(((optimizerlooptypeParser<>*)child)->post());
848 else if(element == "while")while_(((whilelooptypeParser<>*)child)->post());
849 else if(element == "switch")switch_(((switchtypeParser*)child)->post());
850 else if(element == "bloc")bloc(((bloctypeParser<>*)child)->post());
852 else if(element == "datalink") datalink(((linktypeParser<>*)child)->post());