Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/med.git] / src / INTERP_KERNEL / ExprEval / InterpKernelExprParser.cxx
1 // Copyright (C) 2007-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 #include "InterpKernelExprParser.hxx"
21 #include "InterpKernelValue.hxx"
22 #include "InterpKernelAsmX86.hxx"
23
24 #include <cctype>
25 #include <sstream>
26 #include <limits>
27 #include <vector>
28 #include <iterator>
29 #include <iostream>
30 #include <algorithm>
31
32 using namespace INTERP_KERNEL;
33
34 const char LeafExprVar::END_OF_RECOGNIZED_VAR[]="Vec";
35
36 const char ExprParser::WHITE_SPACES[]=" \n";
37
38 const char ExprParser::EXPR_PARSE_ERR_MSG[]="Invalid expression detected : ";
39
40 LeafExpr *LeafExpr::buildInstanceFrom(const std::string& expr) throw(INTERP_KERNEL::Exception)
41 {
42   std::istringstream stream;
43   stream.str(expr);
44   double val;
45   stream >> val;
46   if(!stream.fail())
47     if(stream.eof())
48       return new LeafExprVal(val);
49     else
50       {
51         std::ostringstream errMsg;
52         char MSGTYP6[]="Error following expression is not consedered as a double value : ";
53         errMsg << MSGTYP6 << expr;
54         throw INTERP_KERNEL::Exception(errMsg.str().c_str());
55       }
56   else
57     return new LeafExprVar(expr);
58 }
59
60 LeafExpr::~LeafExpr()
61 {
62 }
63
64 LeafExprVal::LeafExprVal(double value):_value(value)
65 {
66 }
67
68 LeafExprVal::~LeafExprVal()
69 {
70 }
71
72 void LeafExprVal::fillValue(Value *val) const throw(INTERP_KERNEL::Exception)
73 {
74   val->setDouble(_value);
75 }
76
77 void LeafExprVal::replaceValues(const std::vector<double>& valuesInExpr) throw(INTERP_KERNEL::Exception)
78 {
79   int pos=(int)_value;
80   int lgth=(int)valuesInExpr.size();
81   if(pos>=lgth || pos<0)
82     throw INTERP_KERNEL::Exception("LeafExprVal::replaceValues : Big Problem detected ! Send expression to Salome support with expression !");
83   _value=valuesInExpr[pos];
84 }
85
86 LeafExprVar::LeafExprVar(const std::string& var):_fast_pos(-1),_var_name(var)
87 {
88 }
89
90 void LeafExprVar::fillValue(Value *val) const throw(INTERP_KERNEL::Exception)
91 {
92   val->setVarname(_fast_pos,_var_name);
93 }
94
95 void LeafExprVar::prepareExprEvaluation(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo) const throw(INTERP_KERNEL::Exception)
96 {
97   std::vector<std::string>::const_iterator iter=std::find(vars.begin(),vars.end(),_var_name);
98   if(iter==vars.end())
99     {
100       if(!isRecognizedKeyVar(_var_name,_fast_pos))
101         {
102           std::ostringstream oss; oss << "Var : " << _var_name << " not in : ";
103           std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss,", "));
104           throw INTERP_KERNEL::Exception(oss.str().c_str());
105         }
106       else
107         {
108           int relPos=-7-_fast_pos;
109           if(relPos>=targetNbOfCompo)
110             {
111               std::ostringstream oss; oss << "LeafExprVar::prepareExprEvaluation : Found recognized unitary vector \"" << _var_name << "\" which implies that component #" << relPos;
112               oss << " exists, but it is not the case component id should be in [0," << targetNbOfCompo << ") !";
113               throw INTERP_KERNEL::Exception(oss.str().c_str());
114             }
115           else
116             return;
117         }
118     }
119   _fast_pos=(int)std::distance(vars.begin(),iter);
120   if(_fast_pos>=nbOfCompo)
121     {
122       std::ostringstream oss; oss << "LeafExprVar::prepareExprEvaluation : Found var \"" << _var_name << "\" on place " << _fast_pos << " whereas only must be in [0," << nbOfCompo << ") !";
123       throw INTERP_KERNEL::Exception(oss.str().c_str());
124     }
125 }
126
127 void LeafExprVar::prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception)
128 {
129   if(!isRecognizedKeyVar(_var_name,_fast_pos))
130     _fast_pos=-2;
131 }
132
133 bool LeafExprVar::isRecognizedKeyVar(const std::string& var, int& pos)
134 {
135   if(var.length()!=sizeof(END_OF_RECOGNIZED_VAR))
136     return false;
137   std::string end=var.substr(1);
138   if(end!=END_OF_RECOGNIZED_VAR)
139     return false;
140   char first=var[0];
141   if(first<'I' || first>'Z')
142     return false;
143   pos=-7-(first-'I');
144   return true;
145 }
146
147 /*!
148  * Nothing to do it is not a bug.
149  */
150 void LeafExprVar::replaceValues(const std::vector<double>& valuesInExpr) throw(INTERP_KERNEL::Exception)
151 {
152 }
153
154 LeafExprVar::~LeafExprVar()
155 {
156 }
157
158 ExprParser::ExprParser(const char *expr, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false),_expr(expr)
159 {
160   _expr=deleteWhiteSpaces(_expr);
161 }
162
163 //! For \b NOT null terminated strings coming from FORTRAN.
164 ExprParser::ExprParser(const char *expr, int lgth, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false)
165 {
166   _expr=buildStringFromFortran(expr,lgth);
167   _expr=deleteWhiteSpaces(_expr);
168 }
169
170 ExprParser::~ExprParser()
171 {
172   delete _leaf;
173   releaseFunctions();
174 }
175
176 std::size_t ExprParser::FindCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket)
177 {
178   int level=0;
179   for(std::size_t iter=0;iter<posOfCloseBracket;iter++)
180     {
181       std::size_t iter2=posOfCloseBracket-1-iter;
182       if(expr[iter2]==')')
183         level++;
184       else if(expr[iter2]=='(')
185         {
186           if(level==0)
187             return iter2;
188           else
189             level--;
190         }
191     }
192   return std::string::npos;
193 }
194
195 std::string ExprParser::buildStringFromFortran(const char *expr, int lgth)
196 {
197   std::string ret(expr,lgth);
198   std::string whiteSpaces(WHITE_SPACES);
199   std::size_t found=ret.find_last_not_of(whiteSpaces);
200   if (found!=std::string::npos)
201     ret.erase(found+1);
202   else
203     ret.clear();//ret is all whitespace
204   return ret;
205 }
206
207 std::string ExprParser::deleteWhiteSpaces(const std::string& expr)
208 {
209   std::string ret(expr);
210   std::string whiteSpaces(WHITE_SPACES);
211   std::size_t where1=0,where2=0;
212   while(where2!=std::string::npos && where1!=std::string::npos)
213     {
214       where1=ret.find_first_of(whiteSpaces.c_str(),where1,whiteSpaces.length());
215       if(where1!=std::string::npos)
216         {
217           where2=ret.find_first_not_of(whiteSpaces,where1);
218           if(where2!=std::string::npos)
219             ret.erase(ret.begin()+where1,ret.begin()+where2);
220           else
221             ret.erase(ret.begin()+where1,ret.end());
222         }
223     }
224   return ret;
225 }
226
227 void ExprParser::parse() throw(INTERP_KERNEL::Exception)
228 {
229   _is_parsed=true;
230   _is_parsing_ok=false;
231   _sub_expr.clear();
232   releaseFunctions();
233   if(!_expr.empty())
234     {
235       std::string tmp(_expr);
236       std::vector<double> valuesInExpr;
237       fillValuesInExpr(valuesInExpr);
238       checkBracketsParity();
239       if(!simplify())
240         parseDeeper();
241       replaceValues(valuesInExpr);
242       _expr=tmp;
243     }
244   _is_parsing_ok=true;
245 }
246
247 double ExprParser::evaluate() const throw(INTERP_KERNEL::Exception)
248 {
249   Value *gen=new ValueDouble;
250   ValueDouble *res=(ValueDouble *)evaluateLowLev(gen);
251   delete gen;
252   double ret=res->getData();
253   delete res;
254   return ret;
255 }
256
257 DecompositionInUnitBase ExprParser::evaluateUnit() const throw(INTERP_KERNEL::Exception)
258 {
259   Value *gen=new ValueUnit;
260   ValueUnit *res=0;
261   try
262     {
263       res=(ValueUnit *)evaluateLowLev(gen);
264     }
265   catch(INTERP_KERNEL::Exception& e)
266     {
267       delete gen;
268       throw e;
269     }
270   delete gen;
271   DecompositionInUnitBase ret=res->getData();
272   delete res;
273   return ret;
274 }
275
276 void ExprParser::evaluateExpr(int szOfOutParam, const double *inParam, double *outParam) const throw(INTERP_KERNEL::Exception)
277 {
278   Value *gen=new ValueDoubleExpr(szOfOutParam,inParam);
279   ValueDoubleExpr *res=0;
280   try
281     {
282       res=(ValueDoubleExpr *)evaluateLowLev(gen);
283     }
284   catch(INTERP_KERNEL::Exception& e)
285     {
286       delete gen;
287       throw e;
288     }
289   delete gen;
290   std::copy(res->getData(),res->getData()+szOfOutParam,outParam);
291   delete res;
292 }
293
294 void ExprParser::prepareExprEvaluation(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo) const throw(INTERP_KERNEL::Exception)
295 {
296   if(_leaf)
297     {
298       LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
299       if(leafC)
300         leafC->prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo);
301     }
302   else
303     for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
304       (*iter).prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo);
305 }
306
307 void ExprParser::prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception)
308 {
309   std::set<std::string> trueVars;
310   getTrueSetOfVars(trueVars);
311   if(trueVars.size()>1)
312     {
313       std::ostringstream oss; oss << "For this type of evaluation only one not keyword variable authorized : ";
314       oss << "having " << trueVars.size() << " : ";
315       std::copy(trueVars.begin(),trueVars.end(),std::ostream_iterator<std::string>(oss," ")); oss << " !";
316       throw INTERP_KERNEL::Exception(oss.str().c_str());
317     }
318   prepareExprEvaluationVecLowLev();
319 }
320
321 void ExprParser::prepareExprEvaluationVecLowLev() const throw(INTERP_KERNEL::Exception)
322 {
323   if(_leaf)
324     {
325       LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
326       if(leafC)
327         leafC->prepareExprEvaluationVec();
328     }
329   else
330     for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
331       (*iter).prepareExprEvaluationVecLowLev();
332 }
333
334 Value *ExprParser::evaluateLowLev(Value *valGen) const throw(INTERP_KERNEL::Exception)
335 {
336   if(!_is_parsing_ok)
337     throw INTERP_KERNEL::Exception("Parsing fails ! Invalid expression !");
338   if(_sub_expr.empty() && !_leaf)
339     throw INTERP_KERNEL::Exception("Empty expression !");
340   std::vector<Value *> stackOfVal;
341   try
342     {
343       if(_leaf)
344         {
345           Value *ret=valGen->newInstance();
346           try
347             {
348               _leaf->fillValue(ret);
349             }
350           catch(INTERP_KERNEL::Exception& e)
351             {
352               delete ret;
353               throw e;
354             }
355           stackOfVal.resize(1);
356           stackOfVal[0]=ret;
357         }
358       else
359         {
360           stackOfVal.resize(_sub_expr.size());
361           std::vector<Value *>::reverse_iterator iter2=stackOfVal.rbegin();
362           for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++,iter2++)
363             *iter2=(*iter).evaluateLowLev(valGen);
364         }
365       std::list<Function *>::const_iterator iter3;
366       for(iter3=_func_btw_sub_expr.begin();iter3!=_func_btw_sub_expr.end();iter3++)
367         (*iter3)->operate(stackOfVal);
368     }
369   catch(INTERP_KERNEL::Exception& e)
370     {
371       for(std::vector<Value *>::iterator iter4=stackOfVal.begin();iter4!=stackOfVal.end();iter4++)
372         delete *iter4;
373       throw e;
374     }
375   return stackOfVal.back();
376 }
377
378 void ExprParser::getSetOfVars(std::set<std::string>& vars) const
379 {
380   if(_leaf)
381     {
382       LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
383       if(leafC)
384         vars.insert(leafC->getVar());
385     }
386   else
387     for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
388       (*iter).getSetOfVars(vars);
389 }
390
391 void ExprParser::getTrueSetOfVars(std::set<std::string>& trueVars) const
392 {
393   std::set<std::string> vars;
394   getSetOfVars(vars);
395   trueVars.clear();
396   for(std::set<std::string>::const_iterator iter=vars.begin();iter!=vars.end();iter++)
397     {
398       int tmp;
399       if(!LeafExprVar::isRecognizedKeyVar(*iter,tmp))
400         trueVars.insert(*iter);
401     }
402 }
403
404 void ExprParser::parseDeeper() throw(INTERP_KERNEL::Exception)
405 {
406   for(std::list<ExprParser>::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
407     if(!(*iter).simplify())
408       (*iter).parseDeeper();
409 }
410
411 /*!
412  * This method has the responsability to see if this->_expr can be seen as a unary function of something.
413  * Something defined as the contain of highest level barckets.
414  * Typically '(3*x+2)' and 'cos(4*l+p*n)' will be intercepted by this method whereas '3*x+2' not...etc..
415  */
416 void ExprParser::parseUnaryFunc() throw(INTERP_KERNEL::Exception)
417 {
418   if(_expr[_expr.length()-1]!=')')
419     return ;
420   //at this level of code _expr 
421   std::size_t pos1=_expr.find_first_of('(');
422   std::size_t pos4=FindCorrespondingOpenBracket(_expr,_expr.length()-1);
423   if(pos4!=pos1)
424     return ;
425   std::string funcName=_expr.substr(0,pos1);
426   std::size_t pos2=funcName.find_first_of("+-*/^><",0,7);
427   std::size_t pos3=funcName.find_first_not_of("+-*/^><",0,7);
428   if(pos2!=std::string::npos && pos3!=std::string::npos)
429     return ;//Bracket group is not alone, can't conclude not recursively.
430   std::string newExp2=_expr.substr(pos1+1,_expr.length()-pos1-2);
431   std::size_t nbOfParamsInFunc=std::count(newExp2.begin(),newExp2.end(),',')+1;
432   if(pos3!=std::string::npos)
433     _func_btw_sub_expr.push_back(FunctionsFactory::buildFuncFromString(funcName.c_str(),(int)nbOfParamsInFunc));
434   else
435     {
436       std::size_t lgth=funcName.length();
437       char tmp[2]; tmp[1]='\0';
438       for(std::size_t i=0;i<lgth;i++)
439         {
440           tmp[0]=funcName[i];
441           _func_btw_sub_expr.push_back(FunctionsFactory::buildFuncFromString(tmp,(int)nbOfParamsInFunc));
442         }
443     }
444   std::size_t pos6=0;
445   for(std::size_t i=0;i<nbOfParamsInFunc;i++)
446     {
447       std::size_t pos5=newExp2.find_first_of(',',pos6);
448       std::size_t len=std::string::npos;
449       if(pos5!=std::string::npos)
450         len=pos5-pos6;
451       std::string newExp3=newExp2.substr(pos6,len);
452       _sub_expr.push_back(ExprParser(newExp3.c_str(),this));
453       pos6=pos5+1;
454     }
455   _is_parsing_ok=true;
456 }
457
458 /*!
459  *  This method has the responsability to see if this->_expr is interpretable without any recursion.
460  * \return true if no recursion needed, false if this->_expr is too complex to be interpreted at this level.
461  * \throw exception if this->_expr is simple enough to try to interprate this and this expression contains an error.  
462  */
463 bool ExprParser::tryToInterpALeaf() throw(INTERP_KERNEL::Exception)
464 {
465   std::size_t pos=_expr.find_first_not_of("+-",0,2);
466   std::string minimizedExpr=_expr.substr(pos);
467   std::size_t pos2=minimizedExpr.find_first_of("+-*/^()<>",0,9);
468   if(pos2!=std::string::npos)
469     return false;
470   delete _leaf;
471   _leaf=LeafExpr::buildInstanceFrom(minimizedExpr);
472   int nbOfNegs=0;
473   for(std::size_t i=0;i<pos;i++)
474     if(_expr[i]=='-')
475       nbOfNegs++;
476   if(nbOfNegs%2)
477     _func_btw_sub_expr.push_back(FunctionsFactory::buildUnaryFuncFromString("-"));
478   _is_parsing_ok=true;
479   return true;
480 }
481
482 void ExprParser::parseForCmp() throw(INTERP_KERNEL::Exception)
483 {
484   std::string::const_iterator iter;
485   int curLevel=0;
486   std::string curPart;
487   bool isParsingSucceed=false;
488   for(iter=_expr.begin();iter!=_expr.end();iter++)
489     {
490       switch(*iter)
491         {
492         case '>':
493         case '<':
494           {
495             isParsingSucceed=true;
496             if(!curPart.empty())
497               {
498                 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
499                 curPart.clear();
500                 _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
501               }
502             else
503               {
504                 std::ostringstream errMsg;
505                 char MSGTYP1[]="Error non unary function for '";
506                 errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'";
507                 std::string tmp=_expr.substr(iter-_expr.begin());
508                 LocateError(errMsg,tmp,0);
509                 throw INTERP_KERNEL::Exception(errMsg.str().c_str());
510               }
511             break;
512           }
513         case '(':
514           curLevel++;
515           curPart+=*iter;
516           break;
517         case ')':
518           curLevel--;
519           curPart+=*iter;
520           break;
521         default:
522           curPart+=*iter;
523         }
524     }
525   if(isParsingSucceed)
526     {
527       if(!curPart.empty())
528         {
529           _sub_expr.push_back(ExprParser(curPart.c_str(),this));
530           _is_parsing_ok=true;
531         }
532       else
533         {
534           std::ostringstream errMsg;
535           char MSGTYP4[]="Error following expression finished by > / < without right part.";
536           errMsg << EXPR_PARSE_ERR_MSG << MSGTYP4 << _expr;
537           throw INTERP_KERNEL::Exception(errMsg.str().c_str());
538         }
539     }
540 }
541
542 void ExprParser::parseForAddMin() throw(INTERP_KERNEL::Exception)
543 {
544   std::string::const_iterator iter;
545   int curLevel=0;
546   std::string curPart;
547   bool isParsingSucceed=false;
548   for(iter=_expr.begin();iter!=_expr.end();iter++)
549     {
550       switch(*iter)
551         {
552         case '+':
553         case '-':
554           if(curLevel!=0)
555             curPart+=*iter;
556           else
557             {
558               if(!curPart.empty())
559                 {
560                   std::string::reverse_iterator accessor=curPart.rbegin();
561                   if(*accessor!='*' && *accessor!='/' && *accessor!='^')
562                     {
563                       isParsingSucceed=true;
564                       _sub_expr.push_back(ExprParser(curPart.c_str(),this));
565                       curPart.clear();
566                       _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
567                     }
568                   else
569                     curPart+=*iter;
570                 }
571               else
572                 curPart+=*iter;
573             }
574         break;
575         case '(':
576           curLevel++;
577           curPart+=*iter;
578           break;
579         case ')':
580           curLevel--;
581           curPart+=*iter;
582           break;
583         default:
584           curPart+=*iter;
585         }
586     }
587   if(isParsingSucceed)
588     {
589       if(!curPart.empty())
590         {
591           _sub_expr.push_back(ExprParser(curPart.c_str(),this));
592           _is_parsing_ok=true;
593         }
594       else
595         {
596           std::ostringstream errMsg;
597           char MSGTYP4[]="Error following expression finished by +/- without right part.";
598           errMsg << EXPR_PARSE_ERR_MSG << MSGTYP4 << _expr;
599           throw INTERP_KERNEL::Exception(errMsg.str().c_str());
600         }
601     }
602 }
603
604 void ExprParser::parseForMulDiv() throw(INTERP_KERNEL::Exception)
605 {
606   std::string::const_iterator iter;
607   int curLevel=0;
608   std::string curPart;
609   bool isParsingSucceed=false;
610   for(iter=_expr.begin();iter!=_expr.end();iter++)
611     {
612       switch(*iter)
613         {
614         case '/':
615         case '*':
616           if(curLevel!=0)
617             curPart+=*iter;
618           else
619             {
620               isParsingSucceed=true;
621               if(!curPart.empty())
622                 {
623                   _sub_expr.push_back(ExprParser(curPart.c_str(),this));
624                   curPart.clear();
625                   _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
626                 }
627               else
628                 {
629                   std::ostringstream errMsg;
630                   char MSGTYP1[]="Error non unary function for '";
631                   errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'";
632                   std::string tmp=_expr.substr(iter-_expr.begin());
633                   LocateError(errMsg,tmp,0);
634                   throw INTERP_KERNEL::Exception(errMsg.str().c_str());
635                 }
636             }
637         break;
638         case '(':
639           curLevel++;
640           curPart+=*iter;
641           break;
642         case ')':
643           curLevel--;
644           curPart+=*iter;
645           break;
646         default:
647           curPart+=*iter;
648         }
649     }
650   if(isParsingSucceed)
651     {
652       if(!curPart.empty())
653         {
654           _sub_expr.push_back(ExprParser(curPart.c_str(),this));
655           _is_parsing_ok=true;
656         }
657       else
658         {
659           std::ostringstream errMsg;
660           char MSGTYP5[]="Error following expression finished by *// without right part.";
661           errMsg << EXPR_PARSE_ERR_MSG << MSGTYP5 << _expr;
662           throw INTERP_KERNEL::Exception(errMsg.str().c_str());
663         }
664     }
665 }
666
667 void ExprParser::parseForPow() throw(INTERP_KERNEL::Exception)
668 {
669   std::string::const_iterator iter;
670   int curLevel=0;
671   std::string curPart;
672   bool isParsingSucceed=false;
673   for(iter=_expr.begin();iter!=_expr.end();iter++)
674     {
675       switch(*iter)
676         {
677         case '^':
678           if(curLevel!=0)
679             curPart+=*iter;
680           else
681             if(!curPart.empty())
682               {
683                 isParsingSucceed=true;
684                 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
685                 curPart.clear();
686                 _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
687               }
688             else
689               {
690                 std::ostringstream errMsg;
691                 char MSGTYP1[]="Error non unary function for '";
692                 errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'";
693                 std::string tmp=_expr.substr(iter-_expr.begin());
694                 LocateError(errMsg,tmp,0);curPart+=*iter;
695                 throw INTERP_KERNEL::Exception(errMsg.str().c_str());
696               }
697           break;
698         case '(':
699           curLevel++;
700           curPart+=*iter;
701           break;
702         case ')':
703           curLevel--;
704           curPart+=*iter;
705           break;
706         default:
707           curPart+=*iter;
708         }
709     }
710   if(isParsingSucceed)
711     {
712       if(!curPart.empty())
713         {
714           _sub_expr.push_back(ExprParser(curPart.c_str(),this));
715           _is_parsing_ok=true;
716         }
717       else
718         {
719           std::ostringstream errMsg;
720           char MSGTYP6[]="Error following expression finished by ^ without right part.";
721           errMsg << EXPR_PARSE_ERR_MSG << MSGTYP6 << _expr;
722           throw INTERP_KERNEL::Exception(errMsg.str().c_str());
723         }
724     }
725 }
726
727 void ExprParser::releaseFunctions()
728 {
729   for(std::list<Function *>::iterator iter=_func_btw_sub_expr.begin();iter!=_func_btw_sub_expr.end();iter++)
730     delete *iter;
731   _func_btw_sub_expr.clear();
732 }
733
734 /*!
735  * This method parse this->_expr at the current level.
736  * This method first try to see if this->_expr is a leaf, if not it try a unary function of something (see INTERP_KERNEL::ExprParser::parseUnaryFunc method)
737  * If true is returned, no deeper parsing needed, if false is returned for a full parsing of this->_expr INTERP_KERNEL::ExprParser::parseDeeper call needed.
738  */
739 bool ExprParser::simplify() throw(INTERP_KERNEL::Exception)
740 {
741   if(tryToInterpALeaf())
742     return true;
743   parseUnaryFunc();
744   if(!_is_parsing_ok)
745     {
746       parseForCmp();
747       if(!_is_parsing_ok)
748         {
749           parseForAddMin();
750           if(!_is_parsing_ok)
751             {
752               parseForMulDiv();
753               if(!_is_parsing_ok)
754                 parseForPow();
755             }
756         }
757     }
758   if(!_is_parsing_ok)
759     {
760       std::ostringstream errMsg;
761       char MSGTYP3[]="Error in interpreting : ";
762       errMsg << EXPR_PARSE_ERR_MSG << MSGTYP3 << _expr;
763       LocateError(errMsg,_expr,0);
764       throw INTERP_KERNEL::Exception(errMsg.str().c_str());
765     }
766   return false;
767 }
768
769 void ExprParser::checkBracketsParity() const throw(INTERP_KERNEL::Exception)
770 {
771   std::string::const_iterator iter;
772   int curLevel=0;
773   for(iter=_expr.begin();iter!=_expr.end();iter++)
774     {
775       if(*iter=='(')
776         curLevel++;
777       else if(*iter==')')
778         {
779           if(curLevel==0)
780             {
781               std::ostringstream errMsg;
782               char MSGTYP1[]="Error in brackets : closing brackets ')' before openning '('";
783               errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1;
784               LocateError(errMsg,_expr,(int)std::distance(_expr.begin(),iter));
785               throw INTERP_KERNEL::Exception(errMsg.str().c_str());
786             }
787           curLevel--;
788         }
789     }
790   if(curLevel!=0)
791     {
792       std::ostringstream errMsg;
793       char MSGTYP2[]="Error in brackets : not finally closed expr.";
794       errMsg << EXPR_PARSE_ERR_MSG << MSGTYP2;
795       throw INTERP_KERNEL::Exception(errMsg.str().c_str());
796     }
797 }
798
799 /*!
800  * This method substitutes part in [bg,end) in expr by the content of (str(id)) and returns the double value representation in expr[bg,end).
801  * If double representation is invalid an exception is thrown.
802  * This method returns a delta that is the delta to operate to pos in expr after substitution.
803  */
804 double ExprParser::ReplaceAndTraduce(std::string& expr, int id, std::size_t bg, std::size_t end, int& delta) throw(INTERP_KERNEL::Exception)
805 {
806   static const char MSG[]="Interal error : A string expected to be a float is not one ! Bug to signal !";
807   std::istringstream stream;
808   std::ostringstream oss;
809   std::size_t end2=end!=std::string::npos?end-bg:end;
810   std::string tmp=expr.substr(bg,end2);
811   stream.str(tmp);
812   double ret=std::numeric_limits<double>::max();
813   stream >> ret;
814   if(stream.fail())
815     throw INTERP_KERNEL::Exception(MSG);
816   if(!stream.eof())
817     throw INTERP_KERNEL::Exception(MSG);
818   oss << id;
819   std::string tmp2(oss.str());
820   std::size_t l1=tmp.length();
821   delta=(int)tmp2.length()-(int)l1;
822   expr.replace(bg,l1,tmp2);
823   return ret;
824 }
825
826 /*!
827  * This method makes the assumption that _expr has no white space.
828  * This method scans _expr finding in greedy mode the following pattern :
829  * {0..9}+{.}?{0..9}*{{eE}{-}?{0..9}+}?
830  */
831 void ExprParser::fillValuesInExpr(std::vector<double>& valuesInExpr) throw(INTERP_KERNEL::Exception)
832 {
833   const char FIGURES[]="0123456789";
834   const std::string other("+-*^/(<>,");
835   std::size_t lgth=_expr.length();
836   int id=0,delta;
837   for(std::size_t pos=0;pos!=std::string::npos;id++)
838     {
839       std::size_t pos2=_expr.find_first_of(FIGURES,pos,10);
840       if(pos2==std::string::npos)
841         break;
842       if(pos2>0)
843         {//treat case of "x*log10(x)" -> "10" should NOT be intercepted by this
844           if(other.find_first_of(_expr[pos2-1])==std::string::npos)
845             {
846               pos=_expr.find_first_not_of(FIGURES,pos2,10);
847               id--;
848               continue;
849             }
850           if(_expr[pos2-1]==')')
851             {
852               pos=_expr.find_first_not_of(FIGURES,pos2,10);
853               std::ostringstream oss; oss << "Problem on parsing : Number \"" << _expr.substr(pos2,pos!=std::string::npos?pos2-pos:std::string::npos);
854               oss << "\" is right after close parenthesis... ')'";
855               throw INTERP_KERNEL::Exception(oss.str().c_str());
856             }
857         }
858       std::size_t pos3=_expr.find_first_not_of(FIGURES,pos2,10);
859       if(pos3==std::string::npos)
860         {//"x+1223442320"
861           valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta));
862           break;
863         }
864       if(_expr[pos3]=='.')
865         pos3++;
866       if(pos3<lgth)
867         {
868           std::size_t pos4=_expr.find_first_not_of(FIGURES,pos3,10);
869           if(pos4==std::string::npos)
870             {//"x+1223334.223"
871               valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta));
872               break;
873             }
874           else
875             {
876               if(_expr[pos4]!='e' && _expr[pos4]!='E')
877                 {//"x+1223334.223+x"
878                   valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,pos4,delta));
879                   pos=pos4+delta;
880                   continue;
881                 }
882               else
883                 {
884                   if(++pos4<lgth)
885                     {
886                       if(_expr[pos4]=='+' || _expr[pos4]=='-')
887                         pos4++;
888                       if(pos4>=lgth)
889                         {//"x+1223334.223e+" or "1223334.223E-"
890                           std::ostringstream oss; oss << "Invalid expr : float number at the end of expr is invalid lacking number after exponential and sign ! -> \"" << _expr.substr(pos2) << "\"";
891                           throw INTERP_KERNEL::Exception(oss.str().c_str());
892                         }
893                       std::size_t pos5=_expr.find_first_not_of(FIGURES,pos4,10);
894                       if(pos4==pos5)
895                         {//"x+1223334.223e+x" or "1223334.223E-y"
896                           std::ostringstream oss; oss << "Invalid expr : float number in expr is invalid lacking number after exponential ! -> \"" << _expr.substr(pos2,pos4-pos2) << "\"";
897                           throw INTERP_KERNEL::Exception(oss.str().c_str());
898                         }
899                       //OK, normal case
900                       valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,pos5,delta));
901                       pos=pos5+delta;
902                       continue;
903                     }
904                   else//"x+1223334.223e"
905                     {
906                       std::ostringstream oss; oss << "Invalid expr : float number at the end of expr is invalid lacking number after exponential ! " << _expr.substr(pos2);
907                       throw INTERP_KERNEL::Exception(oss.str().c_str());
908                     }
909                 }
910             }
911         }
912       else
913         {//"x+1223334."
914           valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta));
915           break;
916         }
917     }
918 }
919
920 void ExprParser::replaceValues(const std::vector<double>& valuesInExpr) throw(INTERP_KERNEL::Exception)
921 {
922   if(_leaf)
923     _leaf->replaceValues(valuesInExpr);
924   else
925     {
926       for(std::list<ExprParser>::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
927         (*iter).replaceValues(valuesInExpr);
928     }
929 }
930
931 void ExprParser::LocateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr)
932 {
933   stringToDisp << "Position is " << posOfErr << " of string : \"" <<  srcOfErr << "\"" << std::endl;
934 }
935
936 char *ExprParser::compileX86() const
937 {
938   std::vector<std::string> ass;
939   //need in stack
940   ass.push_back("push ebp");
941   ass.push_back("mov ebp,esp");
942   compileX86LowLev(ass);
943   ass.push_back("pop ebp");
944   ass.push_back("ret");
945   std::cout << std::endl;
946   for(std::vector<std::string>::const_iterator iter=ass.begin();iter!=ass.end();iter++)
947     std::cout << "        " << *iter << std::endl;
948   AsmX86 asmb;
949   std::vector<char> output=asmb.convertIntoMachineLangage(ass);
950   for(std::vector<char>::const_iterator iter=output.begin();iter!=output.end();iter++)
951     std::cout << std::hex << (int)((unsigned char)(*iter)) << " ";
952   std::cout << std::endl;
953   unsigned offset;
954   return asmb.copyToExecMemZone(output,offset);
955 }
956
957 char *ExprParser::compileX86_64() const
958 {
959   std::vector<std::string> ass;
960   //need in stack
961   ass.push_back("push rbp");
962   ass.push_back("mov rbp,rsp");
963   compileX86_64LowLev(ass);
964   ass.push_back("sub rsp,8");
965   ass.push_back("fst qword [rsp]");
966   ass.push_back("movsd xmm0,[rsp]");
967   ass.push_back("add rsp,8");
968   ass.push_back("leave");
969   ass.push_back("ret");
970   std::cout << std::endl;
971   for(std::vector<std::string>::const_iterator iter=ass.begin();iter!=ass.end();iter++)
972     std::cout << "        " << *iter << std::endl;
973   AsmX86 asmb;
974   std::vector<char> output=asmb.convertIntoMachineLangage(ass);
975   for(std::vector<char>::const_iterator iter=output.begin();iter!=output.end();iter++)
976     std::cout << std::hex << (int)((unsigned char)(*iter)) << " ";
977   std::cout << std::endl;
978   unsigned offset;
979   return asmb.copyToExecMemZone(output,offset);
980 }
981
982 void ExprParser::compileX86LowLev(std::vector<std::string>& ass) const
983 {
984   if(_leaf)
985     _leaf->compileX86(ass);
986   else
987     {
988       for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
989         (*iter).compileX86LowLev(ass);
990     }
991   for(std::list<Function *>::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++)
992     (*iter2)->operateX86(ass);
993 }
994
995 void ExprParser::compileX86_64LowLev(std::vector<std::string>& ass) const
996 {
997   if(_leaf)
998     _leaf->compileX86_64(ass);
999   else
1000     {
1001       for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
1002         (*iter).compileX86_64LowLev(ass);
1003     }
1004   for(std::list<Function *>::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++)
1005     (*iter2)->operateX86(ass);
1006 }
1007
1008 void LeafExprVal::compileX86(std::vector<std::string>& ass) const
1009 {
1010   ass.push_back("sub esp,8");
1011   int *b=(int *)&_value,*c=(int *)&_value;
1012   c++;
1013   std::ostringstream oss;
1014   oss << std::hex;
1015   oss << "mov dword [esp+4],0x" << *c;
1016   ass.push_back(oss.str());
1017   oss.str("");
1018   oss << "mov dword [esp],0x" << *b;
1019   ass.push_back(oss.str());
1020   ass.push_back("fld qword [esp]");
1021   ass.push_back("add esp,8");
1022 }
1023
1024 void LeafExprVal::compileX86_64(std::vector<std::string>& ass) const
1025 {
1026   ass.push_back("sub rsp,8");
1027   int *b=(int *)&_value,*c=(int *)&_value;
1028   c++;
1029   std::ostringstream oss;
1030   oss << std::hex;
1031   oss << "mov dword [rsp+4],0x" << *c;
1032   ass.push_back(oss.str());
1033   oss.str("");
1034   oss << "mov dword [rsp],0x" << *b;
1035   ass.push_back(oss.str());
1036   ass.push_back("fld qword [rsp]");
1037   ass.push_back("add rsp,8");
1038 }
1039
1040 void LeafExprVar::compileX86(std::vector<std::string>& ass) const
1041 {
1042   ass.push_back("fld qword [ebp+8]");
1043 }
1044
1045 void LeafExprVar::compileX86_64(std::vector<std::string>& ass) const
1046 {
1047   ass.push_back("sub rsp,8");
1048   ass.push_back("movsd [rsp],xmm0");
1049   ass.push_back("fld qword [rsp]");
1050   ass.push_back("add rsp,8");
1051 }
1052
1053 int ExprParser::getStackSizeToPlayX86(const ExprParser *asker) const
1054 {
1055   if(asker)
1056     {
1057       int sz=_father->getStackSizeToPlayX86(this);
1058       int i=0;
1059       for(std::list<ExprParser>::const_reverse_iterator iter=_sub_expr.rbegin();iter!=_sub_expr.rend();iter++,i++)
1060         {
1061           const ExprParser& obj=(*iter);
1062           const ExprParser *pt=&obj;
1063           if(pt==asker)
1064             return sz-i;
1065         }
1066       throw INTERP_KERNEL::Exception("error getStackSizeToPlayX86 an object ExprParser called as father, whereas it is not one !");
1067     }
1068   else
1069     {
1070       if(!_father)
1071         return MAX_X86_FP_ST;
1072       return _father->getStackSizeToPlayX86(this);
1073     }
1074 }