Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/yacs.git] / src / yacsloader / loopParsers.hxx
1 // Copyright (C) 2006-2012  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #ifndef _LOOPPARSER_HXX_
21 #define _LOOPPARSER_HXX_
22
23 #include "parserBase.hxx"
24
25 #include "Bloc.hxx"
26 #include "Proc.hxx"
27 #include "Logger.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"
36 #include "Switch.hxx"
37 #include "ForEachLoop.hxx"
38 #include "OptimizerLoop.hxx"
39
40 #include <vector>
41 #include <string>
42 #include <sstream>
43
44 namespace YACS
45 {
46
47 template <class T=ENGINE::Loop*>
48 struct looptypeParser:parser
49 {
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);
53   virtual void pre ();
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 optimizer (ENGINE::OptimizerLoop* const& b);
66   virtual void while_ (ENGINE::WhileLoop* const& b);
67   virtual void switch_ (ENGINE::Switch* const& b);
68   virtual void bloc (ENGINE::Bloc* const& b);
69   virtual void datalink (const mylink& l);
70   std::string _state;
71   T _cnode;
72   std::vector<T> _cnodes;
73 };
74
75 }
76
77 namespace YACS
78 {
79   // A loop can contain forloop, whileloop or foreachloop
80   // We must respect the order : definition of loop, then while, for, .. and then onStart, onEnd for loop !!!
81   //
82   static std::string t3[]={"inline","sinline","service","server", "remote", "node","forloop","foreach","optimizer","while","switch","bloc",""};
83
84 template <class T>
85 void looptypeParser<T>::buildAttr(const XML_Char** attr)
86     {
87       this->required("name",attr);
88       for (int i = 0; attr[i]; i += 2) 
89         {
90           if(std::string(attr[i]) == "name")name(attr[i+1]);
91           if(std::string(attr[i]) == "state")state(attr[i+1]);
92         }
93     }
94 template <class T>
95 void looptypeParser<T>::pre ()
96     {
97       _state="";
98       _cnode=0;
99     }
100 template <class T>
101 void looptypeParser<T>::name (const std::string& name)
102     {
103       DEBTRACE( "bloc_name: " << name );
104     }
105 template <class T>
106 void looptypeParser<T>::state (const std::string& name)
107     {
108       DEBTRACE( "bloc_state: " << name );
109       _state=name;
110     }
111 template <class T>
112 void looptypeParser<T>::property (const myprop& prop)
113     {
114       DEBTRACE( "property_set" << prop._name << prop._value );
115     }
116
117 template <class T>
118 void looptypeParser<T>::inline_ (ENGINE::InlineNode* const& n)
119     {
120       DEBTRACE( "loop_inline" << n->getName() );
121       _cnode->edSetNode(n);
122       std::string fullname=currentProc->names.back()+ n->getName();
123       currentProc->nodeMap[fullname]=n;
124       currentProc->inlineMap[fullname]=n;
125     }
126 template <class T>
127 void looptypeParser<T>::sinline (ENGINE::ServiceInlineNode* const& n)
128     {
129       DEBTRACE( "loop_sinline" << n->getName() )             
130       _cnode->edSetNode(n);
131       std::string fullname=currentProc->names.back()+ n->getName();
132       currentProc->nodeMap[fullname]=n;
133       currentProc->serviceMap[fullname]=n;
134     }
135 template <class T>
136 void looptypeParser<T>::service (ENGINE::ServiceNode* const& n)
137     {
138       DEBTRACE( "loop_service" << n->getName() )             
139       _cnode->edSetNode(n);
140       std::string fullname=currentProc->names.back()+ n->getName();
141       currentProc->nodeMap[fullname]=n;
142       currentProc->serviceMap[fullname]=n;
143     }
144 template <class T>
145 void looptypeParser<T>::server (ENGINE::ServerNode* const& n)
146     {
147       DEBTRACE( "loop_server" << n->getName() )             
148       _cnode->edSetNode(n);
149       std::string fullname=currentProc->names.back()+ n->getName();
150       currentProc->nodeMap[fullname]=n;
151       currentProc->inlineMap[fullname]=n;
152     }
153
154 template <class T>
155 void looptypeParser<T>::remote (YACS::ENGINE::InlineNode* const& n)
156     {
157       DEBTRACE( "loop_remote: " << n->getName() )
158       _cnode->edSetNode(n);
159       std::string fullname = currentProc->names.back()+n->getName();
160       currentProc->nodeMap[fullname]=n;
161       currentProc->inlineMap[fullname]=n;
162     }
163
164 template <class T>
165 void looptypeParser<T>::node (ENGINE::InlineNode* const& n)
166     {
167       DEBTRACE( "loop_node" << n->getName() )             
168       _cnode->edSetNode(n);
169       std::string fullname=currentProc->names.back()+ n->getName();
170       currentProc->nodeMap[fullname]=n;
171       currentProc->inlineMap[fullname]=n;
172     }
173 template <class T>
174 void looptypeParser<T>::forloop (ENGINE::ForLoop* const& b)
175     {
176       DEBTRACE( "loop_forloop" << b->getName() )             
177       _cnode->edSetNode(b);
178       std::string fullname=currentProc->names.back()+ b->getName();
179       currentProc->nodeMap[fullname]=b;
180     }
181 template <class T>
182 void looptypeParser<T>::foreach (ENGINE::ForEachLoop* const& b)
183     {
184       DEBTRACE("loop_foreach" << b->getName())
185       _cnode->edSetNode(b);
186       std::string fullname=currentProc->names.back()+ b->getName();
187       currentProc->nodeMap[fullname]=b;
188       fullname += ".splitter";
189       currentProc->nodeMap[fullname]=b->getChildByShortName("splitter");
190     }
191 template <class T>
192 void looptypeParser<T>::optimizer (ENGINE::OptimizerLoop* const& b)
193   {
194     DEBTRACE( "loop_optimizer: " << b->getName() );
195     _cnode->edSetNode(b);
196     std::string fullname = currentProc->names.back()+b->getName();
197     currentProc->nodeMap[fullname]=b;
198     //fullname += ".splitter";
199     //currentProc->nodeMap[fullname]=b->getChildByShortName("splitter");
200   }
201 template <class T>
202 void looptypeParser<T>::while_ (ENGINE::WhileLoop* const& b)
203     {
204       DEBTRACE( "loop_while: " << b->getName() )             
205       _cnode->edSetNode(b);
206       std::string fullname=currentProc->names.back()+ b->getName();
207       currentProc->nodeMap[fullname]=b;
208     }
209 template <class T>
210 void looptypeParser<T>::switch_ (ENGINE::Switch* const& b)
211     {
212       DEBTRACE( "loop_switch: " << b->getName() )             
213       _cnode->edSetNode(b);
214       std::string fullname=currentProc->names.back()+ b->getName();
215       currentProc->nodeMap[fullname]=b;
216     }
217 template <class T>
218 void looptypeParser<T>::bloc (ENGINE::Bloc* const& b)
219     {
220       DEBTRACE( "loop_bloc " << b->getName() )             
221       _cnode->edSetNode(b);
222       std::string fullname=currentProc->names.back()+ b->getName();
223       currentProc->nodeMap[fullname]=b;
224     }
225
226 template <class T>
227 void looptypeParser<T>::datalink (const mylink& l)
228     {
229       DEBTRACE( "loop_datalink: " << l.fromnode() << l.fromport() << l.tonode() << l.toport())
230       std::string msg;
231
232       //Try only relative name for from node
233       std::string fromname = currentProc->names.back()+l.fromnode();
234       if(currentProc->nodeMap.count(fromname) == 0)
235         {
236           msg="from node " + l.fromnode() + " does not exist in data link: ";
237           msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")";
238           this->logError(msg);
239           return;
240         }
241       //Try relative name for to node and then absolute one
242       std::string toname = currentProc->names.back()+l.tonode();
243       if(currentProc->nodeMap.count(toname) == 0)
244         {
245           //It's not a relative name. Try an absolute one (I think it's not possible)
246           toname=l.tonode();
247           if(currentProc->nodeMap.count(toname) == 0)
248             {
249               // The TO node does not exist -> error
250               msg="to node " + l.tonode() + " does not exist in data link: ";
251               msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")";
252               this->logError(msg);
253               return;
254             }
255         }
256       // We only link local node and other nodes (relative or absolute name in this order)
257       DEBTRACE(fromname <<":"<<l.fromport()<<toname<<":"<<l.toport());
258       try
259         {
260           if (l.withControl())
261             _cnode->edAddDFLink(currentProc->nodeMap[fromname]->getOutputPort(l.fromport()),
262                                 currentProc->nodeMap[toname]->getInputPort(l.toport()));
263           else
264             _cnode->edAddLink(currentProc->nodeMap[fromname]->getOutputPort(l.fromport()),
265                               currentProc->nodeMap[toname]->getInputPort(l.toport()));
266         }
267       catch(Exception& e)
268         {
269             this->logError(e.what());
270         }
271     }
272
273
274 }
275
276 namespace YACS
277 {
278
279   // While loop specialization
280
281 template <class T=ENGINE::WhileLoop*>
282 struct whilelooptypeParser:looptypeParser<T>
283 {
284   static whilelooptypeParser<T> whileloopParser;
285   virtual void name (const std::string& name);
286   virtual T post();
287 };
288
289 template <class T> whilelooptypeParser<T> whilelooptypeParser<T>::whileloopParser;
290
291 template <class T>
292 void whilelooptypeParser<T>::name (const std::string& name)
293     {
294       DEBTRACE( "while_name: " << name )             
295       std::string fullname=currentProc->names.back()+name;
296       this->_cnode=theRuntime->createWhileLoop(name);
297       currentProc->nodeMap[fullname]=this->_cnode;
298       this->_cnodes.push_back(this->_cnode);
299       currentProc->names.push_back(fullname+'.');
300     }
301
302 template <class T>
303 T whilelooptypeParser<T>::post()
304     {
305       DEBTRACE( "while_post" << this->_cnode->getName() )             
306       ENGINE::InputPort *cond=this->_cnode->edGetConditionPort();
307       cond->edInit(true);
308       T b=this->_cnode;
309       this->_cnodes.pop_back();
310       currentProc->names.pop_back();
311       this->_cnode=this->_cnodes.back();
312       return b;
313     }
314 }
315
316
317
318
319 namespace YACS
320 {
321   // For loop specialization
322
323 template <class T=ENGINE::ForLoop*>
324 struct forlooptypeParser:looptypeParser<T>
325 {
326   static forlooptypeParser<T> forloopParser;
327   virtual void buildAttr(const XML_Char** attr);
328   virtual void name (const std::string& name);
329   virtual void nsteps (const int& n);
330   virtual T post();
331   int _nsteps;
332 };
333
334 template <class T> forlooptypeParser<T> forlooptypeParser<T>::forloopParser;
335
336 template <class T>
337 void forlooptypeParser<T>::buildAttr(const XML_Char** attr)
338     {
339       this->required("name",attr);
340       for (int i = 0; attr[i]; i += 2) 
341         {
342           if(std::string(attr[i]) == "name")name(attr[i+1]);
343           if(std::string(attr[i]) == "state")this->state(attr[i+1]);
344           if(std::string(attr[i]) == "nsteps")nsteps(atoi(attr[i+1]));
345         }
346     }
347
348 template <class T>
349   void forlooptypeParser<T>::name (const std::string& name)
350     {
351       DEBTRACE( "forloop_name: " << name );
352       std::string fullname=currentProc->names.back()+name;
353       this->_cnode=theRuntime->createForLoop(name);
354       currentProc->nodeMap[fullname]=this->_cnode;
355       this->_cnodes.push_back(this->_cnode);
356       currentProc->names.push_back(fullname+'.');
357       _nsteps=0;
358     }
359
360 template <class T>
361 void forlooptypeParser<T>::nsteps (const int& n)
362     {
363       DEBTRACE( "forloop_nsteps: " << n )             
364       if(!this->_cnode)
365           throw Exception("Node name must be defined before nsteps");
366       ENGINE::InputPort *iNbTimes=this->_cnode->edGetNbOfTimesInputPort();
367       iNbTimes->edInit(n);
368     }
369
370 template <class T>
371    T forlooptypeParser<T>::post()
372     {
373       DEBTRACE( "forloop_post" )             
374       T b=this->_cnode;
375       this->_cnodes.pop_back();
376       currentProc->names.pop_back();
377       this->_cnode=this->_cnodes.back();
378       return b;
379     }
380
381 }
382
383 namespace YACS
384 {
385 // pseudo composed node, used to store the init or finalize node of a DynParaLoop
386 class PseudoComposedNode
387 {
388 public:
389   void edSetNode(ENGINE::Node * node) { _node = node; }
390   ENGINE::Node * getNode() { return _node; }
391
392   // Those two methods should never be called
393   bool edAddLink(ENGINE::OutPort *start, ENGINE::InPort *end) throw(Exception) { YASSERT(false); }
394   bool edAddDFLink(ENGINE::OutPort *start, ENGINE::InPort *end) throw(Exception) { YASSERT(false); }
395
396 protected:
397   ENGINE::Node * _node;
398 };
399
400 // pseudo composed node parser specialization for DynParaLoop init and finalize nodes
401 template <class T=PseudoComposedNode*>
402 struct pseudocomposednodetypeParser:looptypeParser<T>
403 {
404   static pseudocomposednodetypeParser<T> pseudocomposednodeParser;
405
406   virtual void buildAttr(const XML_Char** attr)
407     {
408       this->_cnode = new PseudoComposedNode();
409       this->_cnodes.push_back(this->_cnode);
410     }
411
412   virtual T post()
413     {
414       DEBTRACE("pseudocomposednode_post" << this->_cnode->getNode()->getName())
415       T b = this->_cnode;
416       this->_cnodes.pop_back();
417       if(this->_cnodes.size() == 0)
418         this->_cnode = 0;
419       else
420         this->_cnode = this->_cnodes.back();
421       return b;
422     }
423
424   virtual void datalink(const mylink & l)
425     {
426       throw YACS::Exception("Unexpected datalink element in DynParaLoop init or finalize node");
427     }
428
429 };
430
431 template <class T> pseudocomposednodetypeParser<T> pseudocomposednodetypeParser<T>::pseudocomposednodeParser;
432
433 }
434
435 namespace YACS
436 {
437 // dynparaloop specialization
438
439 template <class T=ENGINE::DynParaLoop*>
440 struct dynparalooptypeParser:looptypeParser<T>
441 {
442   virtual void onStart(const XML_Char* el, const XML_Char** attr)
443     {
444       DEBTRACE( "dynparalooptypeParser::onStart: " << el )
445       std::string element(el);
446       this->maxcount("initnode",1,element);
447       this->maxcount("finalizenode",1,element);
448       if (element == "initnode" || element == "finalizenode")
449         {
450           parser* pp = &pseudocomposednodetypeParser<>::pseudocomposednodeParser;
451           this->SetUserDataAndPush(pp);
452           pp->init();
453           pp->pre();
454           pp->buildAttr(attr);
455         }
456       else
457         {
458           this->looptypeParser<T>::onStart(el, attr);
459         }
460     }
461
462   virtual void onEnd(const char *el, parser* child)
463     {
464       DEBTRACE( "dynparalooptypeParser::onEnd: " << el )
465       std::string element(el);
466       if (element == "initnode") initnode(((pseudocomposednodetypeParser<>*)child)->post());
467       else if (element == "finalizenode") finalizenode(((pseudocomposednodetypeParser<>*)child)->post());
468       else this->looptypeParser<T>::onEnd(el, child);
469     }
470
471   virtual void initnode(PseudoComposedNode * const& n)
472     {
473       DEBTRACE( "dynparaloop_initnode: " << n->getNode()->getName() )
474       this->_cnode->edSetInitNode(n->getNode());
475       delete n;
476     }
477
478   virtual void finalizenode(PseudoComposedNode * const& n)
479     {
480       DEBTRACE( "dynparaloop_finalizenode: " << n->getNode()->getName() )
481       this->_cnode->edSetFinalizeNode(n->getNode());
482       delete n;
483     }
484 };
485
486 }
487
488 namespace YACS
489 {
490   // Foreach loop specialization
491
492 template <class T=ENGINE::ForEachLoop*>
493 struct foreachlooptypeParser:dynparalooptypeParser<T>
494 {
495   static foreachlooptypeParser<T> foreachloopParser;
496
497   virtual void buildAttr(const XML_Char** attr)
498     {
499       this->required("name",attr);
500       this->required("type",attr);
501       for (int i = 0; attr[i]; i += 2) 
502         {
503           if(std::string(attr[i]) == "name")name(attr[i+1]);
504           if(std::string(attr[i]) == "state")this->state(attr[i+1]);
505           if(std::string(attr[i]) == "nbranch")nbranch(atoi(attr[i+1]));
506           if(std::string(attr[i]) == "type")datatype(attr[i+1]);
507         }
508       postAttr();
509     }
510   virtual void pre ()
511     {
512       _nbranch=0;
513       this->looptypeParser<T>::pre();
514     }
515   virtual void name (const std::string& name)
516     {
517       DEBTRACE("foreach_name: " << name)
518       _name=name;
519       _fullname=currentProc->names.back()+name;
520     }
521   virtual void nbranch (const int& n)
522     {
523       DEBTRACE("foreach_nbranch: " << n )
524       _nbranch=n;
525     }
526   virtual void datatype (const std::string& type)
527     {
528       DEBTRACE("foreach_datatype: "<< type)
529       _datatype=type;
530     }
531   virtual void postAttr()
532     {
533       if(currentProc->typeMap.count(_datatype)==0)
534       {
535         //Check if the typecode is defined in the runtime
536         YACS::ENGINE::TypeCode* t=theRuntime->getTypeCode(_datatype);
537         if(t==0)
538         {
539           std::stringstream msg;
540           msg << "Type "<< _datatype <<" does not exist"<<" ("<<__FILE__<<":"<<__LINE__<< ")";
541           throw Exception(msg.str());
542         }
543         else
544         {
545           currentProc->typeMap[_datatype]=t;
546           t->incrRef();
547         }
548       }
549       this->_cnode=theRuntime->createForEachLoop(_name,currentProc->typeMap[_datatype]);
550       //set number of branches
551       if(_nbranch > 0)this->_cnode->edGetNbOfBranchesPort()->edInit(_nbranch);
552       this->_cnodes.push_back(this->_cnode);
553       currentProc->names.push_back(_fullname + '.');
554     }
555   virtual T post()
556     {
557       DEBTRACE("foreach_post" << this->_cnode->getName())
558       T b=this->_cnode;
559       this->_cnodes.pop_back();
560       currentProc->names.pop_back();
561       if(this->_cnodes.size() == 0)
562         this->_cnode=0;
563       else
564         this->_cnode=this->_cnodes.back();
565       return b;
566     }
567   int _nbranch;
568   std::string _fullname;
569   std::string _name;
570   std::string _datatype;
571 };
572
573 template <class T> foreachlooptypeParser<T> foreachlooptypeParser<T>::foreachloopParser;
574
575 }
576
577 namespace YACS
578 {
579   // optimizer loop specialization
580
581 template <class T=ENGINE::OptimizerLoop*>
582 struct optimizerlooptypeParser:dynparalooptypeParser<T>
583 {
584   static optimizerlooptypeParser<T> optimizerloopParser;
585
586   virtual void buildAttr(const XML_Char** attr)
587     {
588       this->required("name",attr);
589       this->required("lib",attr);
590       this->required("entry",attr);
591       for (int i = 0; attr[i]; i += 2)
592         {
593           if(std::string(attr[i]) == "name")name(attr[i+1]);
594           if(std::string(attr[i]) == "state")this->state(attr[i+1]);
595           if(std::string(attr[i]) == "nbranch")nbranch(atoi(attr[i+1]));
596           if(std::string(attr[i]) == "lib")lib(attr[i+1]);
597           if(std::string(attr[i]) == "entry")entry(attr[i+1]);
598           if(std::string(attr[i]) == "kind")kind(attr[i+1]);
599         }
600       postAttr();
601     }
602   virtual void pre ()
603     {
604       _nbranch=0;
605       this->looptypeParser<T>::pre();
606     }
607   virtual void name (const std::string& name)
608     {
609       DEBTRACE("optimizer_name: " << name)
610       _name=name;
611       _fullname=currentProc->names.back()+name;
612     }
613   virtual void lib (const std::string& name)
614     {
615       _lib=name;
616     }
617   virtual void entry (const std::string& name)
618     {
619       _entry=name;
620     }
621   virtual void nbranch (const int& n)
622     {
623       DEBTRACE("optimizer_nbranch: " << n )
624       _nbranch=n;
625     }
626   virtual void kind (const std::string& name)
627     {
628       _kind=name;
629     }
630   virtual void postAttr()
631     {
632       this->_cnode=theRuntime->createOptimizerLoop(_name,_lib,_entry,true,_kind, currentProc);
633       //set number of branches
634       if(_nbranch > 0)this->_cnode->edGetNbOfBranchesPort()->edInit(_nbranch);
635       this->_cnodes.push_back(this->_cnode);
636       currentProc->names.push_back(_fullname + '.');
637     }
638   virtual T post()
639     {
640       DEBTRACE("optimizer_post" << this->_cnode->getName())
641       T b=this->_cnode;
642       this->_cnodes.pop_back();
643       currentProc->names.pop_back();
644       if(this->_cnodes.size() == 0)
645         this->_cnode=0;
646       else
647         this->_cnode=this->_cnodes.back();
648       return b;
649     }
650
651   int _nbranch;
652   std::string _fullname;
653   std::string _name;
654   std::string _entry;
655   std::string _kind;
656   std::string _lib;
657
658 };
659
660 template <class T> optimizerlooptypeParser<T> optimizerlooptypeParser<T>::optimizerloopParser;
661
662 }
663
664 #include "blocParsers.hxx"
665 #include "switchParsers.hxx"
666
667 namespace YACS
668 {
669
670 template <class T>
671 void looptypeParser<T>::onStart(const XML_Char* el, const XML_Char** attr)
672 {
673   DEBTRACE( "looptypeParser::onStart: " << el )
674   std::string element(el);
675   this->maxcount("inline",1,element);
676   this->maxcount("sinline",1,element);
677   this->maxcount("service",1,element);
678   this->maxcount("server",1,element);
679   this->maxcount("remote",1,element);
680   this->maxcount("node",1,element);
681   this->maxcount("forloop",1,element);
682   this->maxcount("foreach",1,element);
683   this->maxcount("optimizer",1,element);
684   this->maxcount("while",1,element);
685   this->maxcount("switch",1,element);
686   this->maxcount("bloc",1,element);
687   this->maxchoice(t3,1,element);
688   parser* pp=&parser::main_parser;
689   if(element == "property")pp=&propertytypeParser::propertyParser;
690   else if(element == "inline")pp=&inlinetypeParser<>::inlineParser;
691   else if(element == "sinline")pp=&sinlinetypeParser<>::sinlineParser;
692   else if(element == "service")pp=&servicetypeParser<>::serviceParser;
693   else if(element == "server")pp=&servertypeParser<>::serverParser;
694   else if(element == "remote")pp=&remotetypeParser<>::remoteParser;
695   else if(element == "node")pp=&nodetypeParser<>::nodeParser;
696
697   else if(element == "forloop")pp=&forlooptypeParser<>::forloopParser;
698   else if(element == "foreach")pp=&foreachlooptypeParser<>::foreachloopParser;
699   else if(element == "optimizer")pp=&optimizerlooptypeParser<>::optimizerloopParser;
700   else if(element == "while")pp=&whilelooptypeParser<>::whileloopParser;
701   else if(element == "switch")pp=&switchtypeParser::switchParser;
702   else if(element == "bloc")pp=&bloctypeParser<>::blocParser;
703   else if(element == "datalink")pp=&linktypeParser<>::linkParser;
704   this->SetUserDataAndPush(pp);
705   pp->init();
706   pp->pre();
707   pp->buildAttr(attr);
708 }
709
710 template <class T>
711 void looptypeParser<T>::onEnd(const char *el,parser* child)
712 {
713   DEBTRACE( "looptypeParser::onEnd: " << el )
714   std::string element(el);
715   if(element == "property")property(((propertytypeParser*)child)->post());
716   else if(element == "inline")inline_(((inlinetypeParser<>*)child)->post());
717   else if(element == "sinline")sinline(((sinlinetypeParser<>*)child)->post());
718   else if(element == "service")service(((servicetypeParser<>*)child)->post());
719   else if(element == "server")server(((servertypeParser<>*)child)->post());
720   else if(element == "remote")remote(((remotetypeParser<>*)child)->post());
721   else if(element == "node")node(((nodetypeParser<>*)child)->post());
722
723   else if(element == "forloop")forloop(((forlooptypeParser<>*)child)->post());
724   else if(element == "foreach")foreach(((foreachlooptypeParser<>*)child)->post());
725   else if(element == "optimizer")optimizer(((optimizerlooptypeParser<>*)child)->post());
726   else if(element == "while")while_(((whilelooptypeParser<>*)child)->post());
727   else if(element == "switch")switch_(((switchtypeParser*)child)->post());
728   else if(element == "bloc")bloc(((bloctypeParser<>*)child)->post());
729
730   else if(element == "datalink") datalink(((linktypeParser<>*)child)->post());
731 }
732
733 }
734 #endif