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