]> SALOME platform Git repositories - modules/yacs.git/blob - src/yacsloader/loopParsers.hxx
Salome HOME
XML load of ForEachLoopDyn is now OK
[modules/yacs.git] / src / yacsloader / loopParsers.hxx
1 // Copyright (C) 2006-2019  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::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);
71   std::string _state;
72   T _cnode;
73   std::vector<T> _cnodes;
74 };
75
76 }
77
78 namespace YACS
79 {
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 !!!
82   //
83   static std::string t3[]={"inline","sinline","service","server", "remote", "node","forloop","foreach","optimizer","while","switch","bloc",""};
84
85 template <class T>
86 void looptypeParser<T>::buildAttr(const XML_Char** attr)
87     {
88       if (!attr)
89         return;
90       this->required("name",attr);
91       for (int i = 0; attr[i]; i += 2) 
92         {
93           if(std::string(attr[i]) == "name")name(attr[i+1]);
94           if(std::string(attr[i]) == "state")state(attr[i+1]);
95         }
96     }
97 template <class T>
98 void looptypeParser<T>::pre ()
99     {
100       _state="";
101       _cnode=0;
102     }
103 template <class T>
104 void looptypeParser<T>::name (const std::string& name)
105     {
106       DEBTRACE( "bloc_name: " << name );
107     }
108 template <class T>
109 void looptypeParser<T>::state (const std::string& name)
110     {
111       DEBTRACE( "bloc_state: " << name );
112       _state=name;
113     }
114 template <class T>
115 void looptypeParser<T>::property (const myprop& prop)
116     {
117       DEBTRACE( "property_set" << prop._name << prop._value );
118     }
119
120 template <class T>
121 void looptypeParser<T>::inline_ (ENGINE::InlineNode* const& n)
122     {
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;
128     }
129 template <class T>
130 void looptypeParser<T>::sinline (ENGINE::ServiceInlineNode* const& n)
131     {
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;
137     }
138 template <class T>
139 void looptypeParser<T>::service (ENGINE::ServiceNode* const& n)
140     {
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;
146     }
147 template <class T>
148 void looptypeParser<T>::server (ENGINE::ServerNode* const& n)
149     {
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;
155     }
156
157 template <class T>
158 void looptypeParser<T>::remote (YACS::ENGINE::InlineNode* const& n)
159     {
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;
165     }
166
167 template <class T>
168 void looptypeParser<T>::node (ENGINE::InlineNode* const& n)
169     {
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;
175     }
176 template <class T>
177 void looptypeParser<T>::forloop (ENGINE::ForLoop* const& b)
178     {
179       DEBTRACE( "loop_forloop" << b->getName() )             
180       _cnode->edSetNode(b);
181       std::string fullname=currentProc->names.back()+ b->getName();
182       currentProc->nodeMap[fullname]=b;
183     }
184 template <class T>
185 void looptypeParser<T>::foreach (ENGINE::ForEachLoop* const& b)
186     {
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");
193     }
194 template <class T>
195 void looptypeParser<T>::foreachdyn (ENGINE::ForEachLoopDyn* const& b)
196 {
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");
203 }
204 template <class T>
205 void looptypeParser<T>::optimizer (ENGINE::OptimizerLoop* const& b)
206   {
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");
213   }
214 template <class T>
215 void looptypeParser<T>::while_ (ENGINE::WhileLoop* const& b)
216     {
217       DEBTRACE( "loop_while: " << b->getName() )             
218       _cnode->edSetNode(b);
219       std::string fullname=currentProc->names.back()+ b->getName();
220       currentProc->nodeMap[fullname]=b;
221     }
222 template <class T>
223 void looptypeParser<T>::switch_ (ENGINE::Switch* const& b)
224     {
225       DEBTRACE( "loop_switch: " << b->getName() )             
226       _cnode->edSetNode(b);
227       std::string fullname=currentProc->names.back()+ b->getName();
228       currentProc->nodeMap[fullname]=b;
229     }
230 template <class T>
231 void looptypeParser<T>::bloc (ENGINE::Bloc* const& b)
232     {
233       DEBTRACE( "loop_bloc " << b->getName() )             
234       _cnode->edSetNode(b);
235       std::string fullname=currentProc->names.back()+ b->getName();
236       currentProc->nodeMap[fullname]=b;
237     }
238
239 template <class T>
240 void looptypeParser<T>::datalink (const mylink& l)
241     {
242       DEBTRACE( "loop_datalink: " << l.fromnode() << l.fromport() << l.tonode() << l.toport())
243       std::string msg;
244
245       //Try only relative name for from node
246       std::string fromname = currentProc->names.back()+l.fromnode();
247       if(currentProc->nodeMap.count(fromname) == 0)
248         {
249           msg="from node " + l.fromnode() + " does not exist in data link: ";
250           msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")";
251           this->logError(msg);
252           return;
253         }
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)
257         {
258           //It's not a relative name. Try an absolute one (I think it's not possible)
259           toname=l.tonode();
260           if(currentProc->nodeMap.count(toname) == 0)
261             {
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()+")";
265               this->logError(msg);
266               return;
267             }
268         }
269       // We only link local node and other nodes (relative or absolute name in this order)
270       DEBTRACE(fromname <<":"<<l.fromport()<<toname<<":"<<l.toport());
271       try
272         {
273           if (l.withControl())
274             _cnode->edAddDFLink(currentProc->nodeMap[fromname]->getOutputPort(l.fromport()),
275                                 currentProc->nodeMap[toname]->getInputPort(l.toport()));
276           else
277             _cnode->edAddLink(currentProc->nodeMap[fromname]->getOutputPort(l.fromport()),
278                               currentProc->nodeMap[toname]->getInputPort(l.toport()));
279         }
280       catch(Exception& e)
281         {
282             this->logError(e.what());
283         }
284     }
285
286
287 }
288
289 namespace YACS
290 {
291
292   // While loop specialization
293
294 template <class T=ENGINE::WhileLoop*>
295 struct whilelooptypeParser:looptypeParser<T>
296 {
297   static whilelooptypeParser<T> whileloopParser;
298   virtual void name (const std::string& name);
299   virtual T post();
300 };
301
302 template <class T> whilelooptypeParser<T> whilelooptypeParser<T>::whileloopParser;
303
304 template <class T>
305 void whilelooptypeParser<T>::name (const std::string& name)
306     {
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+'.');
313     }
314
315 template <class T>
316 T whilelooptypeParser<T>::post()
317     {
318       DEBTRACE( "while_post" << this->_cnode->getName() )             
319       ENGINE::InputPort *cond=this->_cnode->edGetConditionPort();
320       cond->edInit(true);
321       T b=this->_cnode;
322       this->_cnodes.pop_back();
323       currentProc->names.pop_back();
324       this->_cnode=this->_cnodes.empty() ? 0 : this->_cnodes.back();
325       return b;
326     }
327 }
328
329
330
331
332 namespace YACS
333 {
334   // For loop specialization
335
336 template <class T=ENGINE::ForLoop*>
337 struct forlooptypeParser:looptypeParser<T>
338 {
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);
343   virtual T post();
344   int _nsteps;
345 };
346
347 template <class T> forlooptypeParser<T> forlooptypeParser<T>::forloopParser;
348
349 template <class T>
350 void forlooptypeParser<T>::buildAttr(const XML_Char** attr)
351     {
352       if (!attr)
353         return;
354       this->required("name",attr);
355       for (int i = 0; attr[i]; i += 2) 
356         {
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]));
360         }
361     }
362
363 template <class T>
364   void forlooptypeParser<T>::name (const std::string& name)
365     {
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+'.');
372       _nsteps=0;
373     }
374
375 template <class T>
376 void forlooptypeParser<T>::nsteps (const int& n)
377     {
378       DEBTRACE( "forloop_nsteps: " << n )             
379       if(!this->_cnode)
380           throw Exception("Node name must be defined before nsteps");
381       ENGINE::InputPort *iNbTimes=this->_cnode->edGetNbOfTimesInputPort();
382       iNbTimes->edInit(n);
383     }
384
385 template <class T>
386    T forlooptypeParser<T>::post()
387     {
388       DEBTRACE( "forloop_post" )             
389       T b=this->_cnode;
390       this->_cnodes.pop_back();
391       currentProc->names.pop_back();
392       this->_cnode=this->_cnodes.empty() ? 0 : this->_cnodes.back();
393       return b;
394     }
395
396 }
397
398 namespace YACS
399 {
400 // pseudo composed node, used to store the init or finalize node of a DynParaLoop
401 class PseudoComposedNode
402 {
403 public:
404   void edSetNode(ENGINE::Node * node) { _node = node; }
405   ENGINE::Node * getNode() { return _node; }
406
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); }
410
411 protected:
412   ENGINE::Node * _node;
413 };
414
415 // pseudo composed node parser specialization for DynParaLoop init and finalize nodes
416 template <class T=PseudoComposedNode*>
417 struct pseudocomposednodetypeParser:looptypeParser<T>
418 {
419   static pseudocomposednodetypeParser<T> pseudocomposednodeParser;
420
421   virtual void buildAttr(const XML_Char** attr)
422     {
423       this->_cnode = new PseudoComposedNode();
424       this->_cnodes.push_back(this->_cnode);
425     }
426
427   virtual T post()
428     {
429       DEBTRACE("pseudocomposednode_post" << this->_cnode->getNode()->getName())
430       T b = this->_cnode;
431       this->_cnodes.pop_back();
432       this->_cnode=this->_cnodes.empty() ? 0 : this->_cnodes.back();
433       return b;
434     }
435
436   virtual void datalink(const mylink & l)
437     {
438       throw YACS::Exception("Unexpected datalink element in DynParaLoop init or finalize node");
439     }
440
441 };
442
443 template <class T> pseudocomposednodetypeParser<T> pseudocomposednodetypeParser<T>::pseudocomposednodeParser;
444
445 }
446
447 namespace YACS
448 {
449 // dynparaloop specialization
450
451 template <class T=ENGINE::DynParaLoop*>
452 struct dynparalooptypeParser:looptypeParser<T>
453 {
454   virtual void onStart(const XML_Char* el, const XML_Char** attr)
455     {
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")
461         {
462           parser* pp = &pseudocomposednodetypeParser<>::pseudocomposednodeParser;
463           this->SetUserDataAndPush(pp);
464           pp->init();
465           pp->pre();
466           pp->buildAttr(attr);
467         }
468       else
469         {
470           this->looptypeParser<T>::onStart(el, attr);
471         }
472     }
473
474   virtual void onEnd(const char *el, parser* child)
475     {
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);
481     }
482
483   virtual void initnode(PseudoComposedNode * const& n)
484     {
485       DEBTRACE( "dynparaloop_initnode: " << n->getNode()->getName() )
486       this->_cnode->edSetInitNode(n->getNode());
487       delete n;
488     }
489
490   virtual void finalizenode(PseudoComposedNode * const& n)
491     {
492       DEBTRACE( "dynparaloop_finalizenode: " << n->getNode()->getName() )
493       this->_cnode->edSetFinalizeNode(n->getNode());
494       delete n;
495     }
496 };
497
498 }
499
500 namespace YACS
501 {
502   // Foreach loop specialization
503
504 template <class T=ENGINE::ForEachLoop*>
505 struct foreachlooptypeParser:dynparalooptypeParser<T>
506 {
507   static foreachlooptypeParser<T> foreachloopParser;
508
509   virtual void buildAttr(const XML_Char** attr)
510     {
511       if (!attr)
512         return;
513       this->required("name",attr);
514       this->required("type",attr);
515       for (int i = 0; attr[i]; i += 2) 
516         {
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]);
522         }
523       postAttr();
524     }
525   virtual void pre ()
526     {
527       _nbranch=0;
528       _weight=-1.;
529       this->looptypeParser<T>::pre();
530     }
531   virtual void name (const std::string& name)
532     {
533       DEBTRACE("foreach_name: " << name)
534       _name=name;
535       _fullname=currentProc->names.back()+name;
536     }
537   virtual void nbranch (const int& n)
538     {
539       DEBTRACE("foreach_nbranch: " << n )
540       _nbranch=n;
541     }
542   virtual void weight (const double& x)
543     {
544       DEBTRACE("foreach_weight: " << x )
545       _weight=x;
546     }
547   virtual void datatype (const std::string& type)
548     {
549       DEBTRACE("foreach_datatype: "<< type)
550       _datatype=type;
551     }
552   virtual void postAttr()
553     {
554       if(currentProc->typeMap.count(_datatype)==0)
555       {
556         //Check if the typecode is defined in the runtime
557         YACS::ENGINE::TypeCode* t=theRuntime->getTypeCode(_datatype);
558         if(t==0)
559         {
560           std::stringstream msg;
561           msg << "Type "<< _datatype <<" does not exist"<<" ("<<__FILE__<<":"<<__LINE__<< ")";
562           throw Exception(msg.str());
563         }
564         else
565         {
566           currentProc->typeMap[_datatype]=t;
567           t->incrRef();
568         }
569       }
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 + '.');
576     }
577   virtual T post()
578     {
579       DEBTRACE("foreach_post" << this->_cnode->getName())
580       T b=this->_cnode;
581       this->_cnodes.pop_back();
582       currentProc->names.pop_back();
583       this->_cnode=this->_cnodes.empty() ? 0 : this->_cnodes.back();
584       return b;
585     }
586   int _nbranch;
587   double _weight;
588   std::string _fullname;
589   std::string _name;
590   std::string _datatype;
591 };
592
593 template <class T> foreachlooptypeParser<T> foreachlooptypeParser<T>::foreachloopParser;
594
595 //FIXME
596 template <class T=ENGINE::ForEachLoopDyn*>
597 struct foreachloopdyntypeParser:dynparalooptypeParser<T>
598 {
599   static foreachloopdyntypeParser<T> foreachloopdynParser;
600
601   virtual void buildAttr(const XML_Char** attr)
602     {
603       if (!attr)
604         return;
605       this->required("name",attr);
606       this->required("type",attr);
607       for (int i = 0; attr[i]; i += 2) 
608         {
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]) == "loopWeight")weight(atof(attr[i+1]));
612           if(std::string(attr[i]) == "type")datatype(attr[i+1]);
613         }
614       postAttr();
615     }
616   virtual void pre ()
617     {
618       _weight=-1.;
619       this->looptypeParser<T>::pre();
620     }
621   virtual void name (const std::string& name)
622     {
623       DEBTRACE("foreach_name: " << name)
624       _name=name;
625       _fullname=currentProc->names.back()+name;
626     }
627   virtual void weight (const double& x)
628     {
629       DEBTRACE("foreach_weight: " << x )
630       _weight=x;
631     }
632   virtual void datatype (const std::string& type)
633     {
634       DEBTRACE("foreach_datatype: "<< type)
635       _datatype=type;
636     }
637   virtual void postAttr()
638     {
639       if(currentProc->typeMap.count(_datatype)==0)
640       {
641         //Check if the typecode is defined in the runtime
642         YACS::ENGINE::TypeCode* t=theRuntime->getTypeCode(_datatype);
643         if(t==0)
644         {
645           std::stringstream msg;
646           msg << "Type "<< _datatype <<" does not exist"<<" ("<<__FILE__<<":"<<__LINE__<< ")";
647           throw Exception(msg.str());
648         }
649         else
650         {
651           currentProc->typeMap[_datatype]=t;
652           t->incrRef();
653         }
654       }
655       this->_cnode=theRuntime->createForEachLoopDyn(_name,currentProc->typeMap[_datatype]);
656       //set number of branches
657       if(_weight > 0)this->_cnode->setWeight(_weight);
658       this->_cnodes.push_back(this->_cnode);
659       currentProc->names.push_back(_fullname + '.');
660     }
661   virtual T post()
662     {
663       DEBTRACE("foreach_post" << this->_cnode->getName())
664       T b=this->_cnode;
665       this->_cnodes.pop_back();
666       currentProc->names.pop_back();
667       this->_cnode=this->_cnodes.empty() ? 0 : this->_cnodes.back();
668       return b;
669     }
670   double _weight;
671   std::string _fullname;
672   std::string _name;
673   std::string _datatype;
674 };
675
676 template <class T> foreachloopdyntypeParser<T> foreachloopdyntypeParser<T>::foreachloopdynParser;
677 }
678
679 namespace YACS
680 {
681   // optimizer loop specialization
682
683 template <class T=ENGINE::OptimizerLoop*>
684 struct optimizerlooptypeParser:dynparalooptypeParser<T>
685 {
686   static optimizerlooptypeParser<T> optimizerloopParser;
687
688   virtual void buildAttr(const XML_Char** attr)
689     {
690       if (!attr)
691         return;
692       this->required("name",attr);
693       this->required("lib",attr);
694       this->required("entry",attr);
695       for (int i = 0; attr[i]; i += 2)
696         {
697           if(std::string(attr[i]) == "name")name(attr[i+1]);
698           if(std::string(attr[i]) == "state")this->state(attr[i+1]);
699           if(std::string(attr[i]) == "nbranch")nbranch(atoi(attr[i+1]));
700           if(std::string(attr[i]) == "loopWeight")weight(atof(attr[i+1]));
701           if(std::string(attr[i]) == "lib")lib(attr[i+1]);
702           if(std::string(attr[i]) == "entry")entry(attr[i+1]);
703           if(std::string(attr[i]) == "kind")kind(attr[i+1]);
704         }
705       postAttr();
706     }
707   virtual void pre ()
708     {
709       _nbranch=0;
710       _weight=-1.;
711       this->looptypeParser<T>::pre();
712     }
713   virtual void name (const std::string& name)
714     {
715       DEBTRACE("optimizer_name: " << name)
716       _name=name;
717       _fullname=currentProc->names.back()+name;
718     }
719   virtual void lib (const std::string& name)
720     {
721       _lib=name;
722     }
723   virtual void entry (const std::string& name)
724     {
725       _entry=name;
726     }
727   virtual void nbranch (const int& n)
728     {
729       DEBTRACE("optimizer_nbranch: " << n )
730       _nbranch=n;
731     }
732   virtual void weight (const double& x)
733     {
734       DEBTRACE("foreach_weight: " << x )
735       _weight=x;
736     }
737   virtual void kind (const std::string& name)
738     {
739       _kind=name;
740     }
741   virtual void postAttr()
742     {
743       this->_cnode=theRuntime->createOptimizerLoop(_name,_lib,_entry,true,_kind, currentProc);
744       //set number of branches
745       if(_nbranch > 0)this->_cnode->edGetNbOfBranchesPort()->edInit(_nbranch);
746       if(_weight > 0)this->_cnode->setWeight(_weight);
747       this->_cnodes.push_back(this->_cnode);
748       currentProc->names.push_back(_fullname + '.');
749     }
750   virtual T post()
751     {
752       DEBTRACE("optimizer_post" << this->_cnode->getName())
753       T b=this->_cnode;
754       this->_cnodes.pop_back();
755       currentProc->names.pop_back();
756       this->_cnode=this->_cnodes.empty() ? 0 : this->_cnodes.back();
757       return b;
758     }
759
760   int _nbranch;
761   double _weight;
762   std::string _fullname;
763   std::string _name;
764   std::string _entry;
765   std::string _kind;
766   std::string _lib;
767
768 };
769
770 template <class T> optimizerlooptypeParser<T> optimizerlooptypeParser<T>::optimizerloopParser;
771
772 }
773
774 #include "blocParsers.hxx"
775 #include "switchParsers.hxx"
776
777 namespace YACS
778 {
779
780 template <class T>
781 void looptypeParser<T>::onStart(const XML_Char* el, const XML_Char** attr)
782 {
783   DEBTRACE( "looptypeParser::onStart: " << el )
784   std::string element(el);
785   this->maxcount("inline",1,element);
786   this->maxcount("sinline",1,element);
787   this->maxcount("service",1,element);
788   this->maxcount("server",1,element);
789   this->maxcount("remote",1,element);
790   this->maxcount("node",1,element);
791   this->maxcount("forloop",1,element);
792   this->maxcount("foreach",1,element);
793   this->maxcount("foreachdyn",1,element);
794   this->maxcount("optimizer",1,element);
795   this->maxcount("while",1,element);
796   this->maxcount("switch",1,element);
797   this->maxcount("bloc",1,element);
798   this->maxchoice(t3,1,element);
799   parser* pp=&parser::main_parser;
800   if(element == "property")pp=&propertytypeParser::propertyParser;
801   else if(element == "inline")pp=&inlinetypeParser<>::inlineParser;
802   else if(element == "sinline")pp=&sinlinetypeParser<>::sinlineParser;
803   else if(element == "service")pp=&servicetypeParser<>::serviceParser;
804   else if(element == "server")pp=&servertypeParser<>::serverParser;
805   else if(element == "remote")pp=&remotetypeParser<>::remoteParser;
806   else if(element == "node")pp=&nodetypeParser<>::nodeParser;
807
808   else if(element == "forloop")pp=&forlooptypeParser<>::forloopParser;
809   else if(element == "foreach")pp=&foreachlooptypeParser<>::foreachloopParser;
810   else if(element == "foreachdyn")pp=&foreachloopdyntypeParser<>::foreachloopdynParser;
811   else if(element == "optimizer")pp=&optimizerlooptypeParser<>::optimizerloopParser;
812   else if(element == "while")pp=&whilelooptypeParser<>::whileloopParser;
813   else if(element == "switch")pp=&switchtypeParser::switchParser;
814   else if(element == "bloc")pp=&bloctypeParser<>::blocParser;
815   else if(element == "datalink")pp=&linktypeParser<>::linkParser;
816   this->SetUserDataAndPush(pp);
817   pp->init();
818   pp->pre();
819   pp->buildAttr(attr);
820 }
821
822 template <class T>
823 void looptypeParser<T>::onEnd(const char *el,parser* child)
824 {
825   DEBTRACE( "looptypeParser::onEnd: " << el )
826   std::string element(el);
827   if(element == "property")property(((propertytypeParser*)child)->post());
828   else if(element == "inline")inline_(((inlinetypeParser<>*)child)->post());
829   else if(element == "sinline")sinline(((sinlinetypeParser<>*)child)->post());
830   else if(element == "service")service(((servicetypeParser<>*)child)->post());
831   else if(element == "server")server(((servertypeParser<>*)child)->post());
832   else if(element == "remote")remote(((remotetypeParser<>*)child)->post());
833   else if(element == "node")node(((nodetypeParser<>*)child)->post());
834
835   else if(element == "forloop")forloop(((forlooptypeParser<>*)child)->post());
836   else if(element == "foreach")foreach(((foreachlooptypeParser<>*)child)->post());
837   else if(element == "foreachdyn")foreachdyn(((foreachloopdyntypeParser<>*)child)->post());
838   else if(element == "optimizer")optimizer(((optimizerlooptypeParser<>*)child)->post());
839   else if(element == "while")while_(((whilelooptypeParser<>*)child)->post());
840   else if(element == "switch")switch_(((switchtypeParser*)child)->post());
841   else if(element == "bloc")bloc(((bloctypeParser<>*)child)->post());
842
843   else if(element == "datalink") datalink(((linktypeParser<>*)child)->post());
844 }
845
846 }
847 #endif