Back to index

salome-med  6.5.0
InterpKernelExprParser.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 #include "InterpKernelExprParser.hxx"
00021 #include "InterpKernelValue.hxx"
00022 #include "InterpKernelAsmX86.hxx"
00023 
00024 #include <cctype>
00025 #include <sstream>
00026 #include <limits>
00027 #include <vector>
00028 #include <iterator>
00029 #include <iostream>
00030 #include <algorithm>
00031 
00032 using namespace INTERP_KERNEL;
00033 
00034 const char LeafExprVar::END_OF_RECOGNIZED_VAR[]="Vec";
00035 
00036 const char ExprParser::WHITE_SPACES[]=" \n";
00037 
00038 const char ExprParser::EXPR_PARSE_ERR_MSG[]="Invalid expression detected : ";
00039 
00040 LeafExpr *LeafExpr::buildInstanceFrom(const std::string& expr) throw(INTERP_KERNEL::Exception)
00041 {
00042   std::istringstream stream;
00043   stream.str(expr);
00044   double val;
00045   stream >> val;
00046   if(!stream.fail())
00047     if(stream.eof())
00048       return new LeafExprVal(val);
00049     else
00050       {
00051         std::ostringstream errMsg;
00052         char MSGTYP6[]="Error following expression is not consedered as a double value : ";
00053         errMsg << MSGTYP6 << expr;
00054         throw INTERP_KERNEL::Exception(errMsg.str().c_str());
00055       }
00056   else
00057     return new LeafExprVar(expr);
00058 }
00059 
00060 LeafExpr::~LeafExpr()
00061 {
00062 }
00063 
00064 LeafExprVal::LeafExprVal(double value):_value(value)
00065 {
00066 }
00067 
00068 LeafExprVal::~LeafExprVal()
00069 {
00070 }
00071 
00072 void LeafExprVal::fillValue(Value *val) const throw(INTERP_KERNEL::Exception)
00073 {
00074   val->setDouble(_value);
00075 }
00076 
00077 void LeafExprVal::replaceValues(const std::vector<double>& valuesInExpr) throw(INTERP_KERNEL::Exception)
00078 {
00079   int pos=(int)_value;
00080   int lgth=(int)valuesInExpr.size();
00081   if(pos>=lgth || pos<0)
00082     throw INTERP_KERNEL::Exception("LeafExprVal::replaceValues : Big Problem detected ! Send expression to Salome support with expression !");
00083   _value=valuesInExpr[pos];
00084 }
00085 
00086 LeafExprVar::LeafExprVar(const std::string& var):_fast_pos(-1),_var_name(var)
00087 {
00088 }
00089 
00090 void LeafExprVar::fillValue(Value *val) const throw(INTERP_KERNEL::Exception)
00091 {
00092   val->setVarname(_fast_pos,_var_name);
00093 }
00094 
00095 void LeafExprVar::prepareExprEvaluation(const std::vector<std::string>& vars) const throw(INTERP_KERNEL::Exception)
00096 {
00097   std::vector<std::string>::const_iterator iter=std::find(vars.begin(),vars.end(),_var_name);
00098   if(iter==vars.end())
00099     {
00100       if(!isRecognizedKeyVar(_var_name,_fast_pos))
00101         {
00102           std::ostringstream oss; oss << "Var : " << _var_name << " not in : ";
00103           std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss,", "));
00104           throw INTERP_KERNEL::Exception(oss.str().c_str());
00105         }
00106       return;
00107     }
00108   _fast_pos=(int)std::distance(vars.begin(),iter);
00109 }
00110 
00111 void LeafExprVar::prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception)
00112 {
00113   if(!isRecognizedKeyVar(_var_name,_fast_pos))
00114     _fast_pos=-2;
00115 }
00116 
00117 bool LeafExprVar::isRecognizedKeyVar(const std::string& var, int& pos)
00118 {
00119   if(var.length()!=sizeof(END_OF_RECOGNIZED_VAR))
00120     return false;
00121   std::string end=var.substr(1);
00122   if(end!=END_OF_RECOGNIZED_VAR)
00123     return false;
00124   char first=var[0];
00125   if(first<'I' || first>'Z')
00126     return false;
00127   pos=-7-(first-'I');
00128   return true;
00129 }
00130 
00134 void LeafExprVar::replaceValues(const std::vector<double>& valuesInExpr) throw(INTERP_KERNEL::Exception)
00135 {
00136 }
00137 
00138 LeafExprVar::~LeafExprVar()
00139 {
00140 }
00141 
00142 ExprParser::ExprParser(const char *expr, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false),_expr(expr)
00143 {
00144   _expr=deleteWhiteSpaces(_expr);
00145 }
00146 
00148 ExprParser::ExprParser(const char *expr, int lgth, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false)
00149 {
00150   _expr=buildStringFromFortran(expr,lgth);
00151   _expr=deleteWhiteSpaces(_expr);
00152 }
00153 
00154 ExprParser::~ExprParser()
00155 {
00156   delete _leaf;
00157   releaseFunctions();
00158 }
00159 
00160 std::size_t ExprParser::FindCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket)
00161 {
00162   int level=0;
00163   for(std::size_t iter=0;iter<posOfCloseBracket;iter++)
00164     {
00165       std::size_t iter2=posOfCloseBracket-1-iter;
00166       if(expr[iter2]==')')
00167         level++;
00168       else if(expr[iter2]=='(')
00169         {
00170           if(level==0)
00171             return iter2;
00172           else
00173             level--;
00174         }
00175     }
00176   return std::string::npos;
00177 }
00178 
00179 std::string ExprParser::buildStringFromFortran(const char *expr, int lgth)
00180 {
00181   std::string ret(expr,lgth);
00182   std::string whiteSpaces(WHITE_SPACES);
00183   std::size_t found=ret.find_last_not_of(whiteSpaces);
00184   if (found!=std::string::npos)
00185     ret.erase(found+1);
00186   else
00187     ret.clear();//ret is all whitespace
00188   return ret;
00189 }
00190 
00191 std::string ExprParser::deleteWhiteSpaces(const std::string& expr)
00192 {
00193   std::string ret(expr);
00194   std::string whiteSpaces(WHITE_SPACES);
00195   std::size_t where1=0,where2=0;
00196   while(where2!=std::string::npos && where1!=std::string::npos)
00197     {
00198       where1=ret.find_first_of(whiteSpaces.c_str(),where1,whiteSpaces.length());
00199       if(where1!=std::string::npos)
00200         {
00201           where2=ret.find_first_not_of(whiteSpaces,where1);
00202           if(where2!=std::string::npos)
00203             ret.erase(ret.begin()+where1,ret.begin()+where2);
00204           else
00205             ret.erase(ret.begin()+where1,ret.end());
00206         }
00207     }
00208   return ret;
00209 }
00210 
00211 void ExprParser::parse() throw(INTERP_KERNEL::Exception)
00212 {
00213   _is_parsed=true;
00214   _is_parsing_ok=false;
00215   _sub_expr.clear();
00216   releaseFunctions();
00217   if(!_expr.empty())
00218     {
00219       std::string tmp(_expr);
00220       std::vector<double> valuesInExpr;
00221       fillValuesInExpr(valuesInExpr);
00222       checkBracketsParity();
00223       if(!simplify())
00224         parseDeeper();
00225       replaceValues(valuesInExpr);
00226       _expr=tmp;
00227     }
00228   _is_parsing_ok=true;
00229 }
00230 
00231 double ExprParser::evaluate() const throw(INTERP_KERNEL::Exception)
00232 {
00233   Value *gen=new ValueDouble;
00234   ValueDouble *res=(ValueDouble *)evaluateLowLev(gen);
00235   delete gen;
00236   double ret=res->getData();
00237   delete res;
00238   return ret;
00239 }
00240 
00241 DecompositionInUnitBase ExprParser::evaluateUnit() const throw(INTERP_KERNEL::Exception)
00242 {
00243   Value *gen=new ValueUnit;
00244   ValueUnit *res=0;
00245   try
00246     {
00247       res=(ValueUnit *)evaluateLowLev(gen);
00248     }
00249   catch(INTERP_KERNEL::Exception& e)
00250     {
00251       delete gen;
00252       throw e;
00253     }
00254   delete gen;
00255   DecompositionInUnitBase ret=res->getData();
00256   delete res;
00257   return ret;
00258 }
00259 
00260 void ExprParser::evaluateExpr(int szOfOutParam, const double *inParam, double *outParam) const throw(INTERP_KERNEL::Exception)
00261 {
00262   Value *gen=new ValueDoubleExpr(szOfOutParam,inParam);
00263   ValueDoubleExpr *res=0;
00264   try
00265     {
00266       res=(ValueDoubleExpr *)evaluateLowLev(gen);
00267     }
00268   catch(INTERP_KERNEL::Exception& e)
00269     {
00270       delete gen;
00271       throw e;
00272     }
00273   delete gen;
00274   std::copy(res->getData(),res->getData()+szOfOutParam,outParam);
00275   delete res;
00276 }
00277 
00278 void ExprParser::prepareExprEvaluation(const std::vector<std::string>& vars) const throw(INTERP_KERNEL::Exception)
00279 {
00280   if(_leaf)
00281     {
00282       LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
00283       if(leafC)
00284         leafC->prepareExprEvaluation(vars);
00285     }
00286   else
00287     for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
00288       (*iter).prepareExprEvaluation(vars);
00289 }
00290 
00291 void ExprParser::prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception)
00292 {
00293   std::set<std::string> trueVars;
00294   getTrueSetOfVars(trueVars);
00295   if(trueVars.size()>1)
00296     {
00297       std::ostringstream oss; oss << "For this type of evaluation only one not keyword variable authorized : ";
00298       oss << "having " << trueVars.size() << " : ";
00299       std::copy(trueVars.begin(),trueVars.end(),std::ostream_iterator<std::string>(oss," ")); oss << " !";
00300       throw INTERP_KERNEL::Exception(oss.str().c_str());
00301     }
00302   prepareExprEvaluationVecLowLev();
00303 }
00304 
00305 void ExprParser::prepareExprEvaluationVecLowLev() const throw(INTERP_KERNEL::Exception)
00306 {
00307   if(_leaf)
00308     {
00309       LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
00310       if(leafC)
00311         leafC->prepareExprEvaluationVec();
00312     }
00313   else
00314     for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
00315       (*iter).prepareExprEvaluationVecLowLev();
00316 }
00317 
00318 Value *ExprParser::evaluateLowLev(Value *valGen) const throw(INTERP_KERNEL::Exception)
00319 {
00320   if(!_is_parsing_ok)
00321     throw INTERP_KERNEL::Exception("Parsing fails ! Invalid expression !");
00322   if(_sub_expr.empty() && !_leaf)
00323     throw INTERP_KERNEL::Exception("Empty expression !");
00324   std::vector<Value *> stackOfVal;
00325   try
00326     {
00327       if(_leaf)
00328         {
00329           Value *ret=valGen->newInstance();
00330           try
00331             {
00332               _leaf->fillValue(ret);
00333             }
00334           catch(INTERP_KERNEL::Exception& e)
00335             {
00336               delete ret;
00337               throw e;
00338             }
00339           stackOfVal.resize(1);
00340           stackOfVal[0]=ret;
00341         }
00342       else
00343         {
00344           stackOfVal.resize(_sub_expr.size());
00345           std::vector<Value *>::reverse_iterator iter2=stackOfVal.rbegin();
00346           for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++,iter2++)
00347             *iter2=(*iter).evaluateLowLev(valGen);
00348         }
00349       std::list<Function *>::const_iterator iter3;
00350       for(iter3=_func_btw_sub_expr.begin();iter3!=_func_btw_sub_expr.end();iter3++)
00351         (*iter3)->operate(stackOfVal);
00352     }
00353   catch(INTERP_KERNEL::Exception& e)
00354     {
00355       for(std::vector<Value *>::iterator iter4=stackOfVal.begin();iter4!=stackOfVal.end();iter4++)
00356         delete *iter4;
00357       throw e;
00358     }
00359   return stackOfVal.back();
00360 }
00361 
00362 void ExprParser::getSetOfVars(std::set<std::string>& vars) const
00363 {
00364   if(_leaf)
00365     {
00366       LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
00367       if(leafC)
00368         vars.insert(leafC->getVar());
00369     }
00370   else
00371     for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
00372       (*iter).getSetOfVars(vars);
00373 }
00374 
00375 void ExprParser::getTrueSetOfVars(std::set<std::string>& trueVars) const
00376 {
00377   std::set<std::string> vars;
00378   getSetOfVars(vars);
00379   trueVars.clear();
00380   for(std::set<std::string>::const_iterator iter=vars.begin();iter!=vars.end();iter++)
00381     {
00382       int tmp;
00383       if(!LeafExprVar::isRecognizedKeyVar(*iter,tmp))
00384         trueVars.insert(*iter);
00385     }
00386 }
00387 
00388 void ExprParser::parseDeeper() throw(INTERP_KERNEL::Exception)
00389 {
00390   for(std::list<ExprParser>::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
00391     if(!(*iter).simplify())
00392       (*iter).parseDeeper();
00393 }
00394 
00400 void ExprParser::parseUnaryFunc() throw(INTERP_KERNEL::Exception)
00401 {
00402   if(_expr[_expr.length()-1]!=')')
00403     return ;
00404   //at this level of code _expr 
00405   std::size_t pos1=_expr.find_first_of('(');
00406   std::size_t pos4=FindCorrespondingOpenBracket(_expr,_expr.length()-1);
00407   if(pos4!=pos1)
00408     return ;
00409   std::string funcName=_expr.substr(0,pos1);
00410   std::size_t pos2=funcName.find_first_of("+-*/^><",0,7);
00411   std::size_t pos3=funcName.find_first_not_of("+-*/^><",0,7);
00412   if(pos2!=std::string::npos && pos3!=std::string::npos)
00413     return ;//Bracket group is not alone, can't conclude not recursively.
00414   std::string newExp2=_expr.substr(pos1+1,_expr.length()-pos1-2);
00415   std::size_t nbOfParamsInFunc=std::count(newExp2.begin(),newExp2.end(),',')+1;
00416   if(pos3!=std::string::npos)
00417     _func_btw_sub_expr.push_back(FunctionsFactory::buildFuncFromString(funcName.c_str(),(int)nbOfParamsInFunc));
00418   else
00419     {
00420       std::size_t lgth=funcName.length();
00421       char tmp[2]; tmp[1]='\0';
00422       for(std::size_t i=0;i<lgth;i++)
00423         {
00424           tmp[0]=funcName[i];
00425           _func_btw_sub_expr.push_back(FunctionsFactory::buildFuncFromString(tmp,(int)nbOfParamsInFunc));
00426         }
00427     }
00428   std::size_t pos6=0;
00429   for(std::size_t i=0;i<nbOfParamsInFunc;i++)
00430     {
00431       std::size_t pos5=newExp2.find_first_of(',',pos6);
00432       std::size_t len=std::string::npos;
00433       if(pos5!=std::string::npos)
00434         len=pos5-pos6;
00435       std::string newExp3=newExp2.substr(pos6,len);
00436       _sub_expr.push_back(ExprParser(newExp3.c_str(),this));
00437       pos6=pos5+1;
00438     }
00439   _is_parsing_ok=true;
00440 }
00441 
00447 bool ExprParser::tryToInterpALeaf() throw(INTERP_KERNEL::Exception)
00448 {
00449   std::size_t pos=_expr.find_first_not_of("+-",0,2);
00450   std::string minimizedExpr=_expr.substr(pos);
00451   std::size_t pos2=minimizedExpr.find_first_of("+-*/^()<>",0,9);
00452   if(pos2!=std::string::npos)
00453     return false;
00454   delete _leaf;
00455   _leaf=LeafExpr::buildInstanceFrom(minimizedExpr);
00456   int nbOfNegs=0;
00457   for(std::size_t i=0;i<pos;i++)
00458     if(_expr[i]=='-')
00459       nbOfNegs++;
00460   if(nbOfNegs%2)
00461     _func_btw_sub_expr.push_back(FunctionsFactory::buildUnaryFuncFromString("-"));
00462   _is_parsing_ok=true;
00463   return true;
00464 }
00465 
00466 void ExprParser::parseForCmp() throw(INTERP_KERNEL::Exception)
00467 {
00468   std::string::const_iterator iter;
00469   int curLevel=0;
00470   std::string curPart;
00471   bool isParsingSucceed=false;
00472   for(iter=_expr.begin();iter!=_expr.end();iter++)
00473     {
00474       switch(*iter)
00475         {
00476         case '>':
00477         case '<':
00478           {
00479             isParsingSucceed=true;
00480             if(!curPart.empty())
00481               {
00482                 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
00483                 curPart.clear();
00484                 _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
00485               }
00486             else
00487               {
00488                 std::ostringstream errMsg;
00489                 char MSGTYP1[]="Error non unary function for '";
00490                 errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'";
00491                 std::string tmp=_expr.substr(iter-_expr.begin());
00492                 LocateError(errMsg,tmp,0);
00493                 throw INTERP_KERNEL::Exception(errMsg.str().c_str());
00494               }
00495             break;
00496           }
00497         case '(':
00498           curLevel++;
00499           curPart+=*iter;
00500           break;
00501         case ')':
00502           curLevel--;
00503           curPart+=*iter;
00504           break;
00505         default:
00506           curPart+=*iter;
00507         }
00508     }
00509   if(isParsingSucceed)
00510     {
00511       if(!curPart.empty())
00512         {
00513           _sub_expr.push_back(ExprParser(curPart.c_str(),this));
00514           _is_parsing_ok=true;
00515         }
00516       else
00517         {
00518           std::ostringstream errMsg;
00519           char MSGTYP4[]="Error following expression finished by > / < without right part.";
00520           errMsg << EXPR_PARSE_ERR_MSG << MSGTYP4 << _expr;
00521           throw INTERP_KERNEL::Exception(errMsg.str().c_str());
00522         }
00523     }
00524 }
00525 
00526 void ExprParser::parseForAddMin() throw(INTERP_KERNEL::Exception)
00527 {
00528   std::string::const_iterator iter;
00529   int curLevel=0;
00530   std::string curPart;
00531   bool isParsingSucceed=false;
00532   for(iter=_expr.begin();iter!=_expr.end();iter++)
00533     {
00534       switch(*iter)
00535         {
00536         case '+':
00537         case '-':
00538           if(curLevel!=0)
00539             curPart+=*iter;
00540           else
00541             {
00542               if(!curPart.empty())
00543                 {
00544                   std::string::reverse_iterator accessor=curPart.rbegin();
00545                   if(*accessor!='*' && *accessor!='/' && *accessor!='^')
00546                     {
00547                       isParsingSucceed=true;
00548                       _sub_expr.push_back(ExprParser(curPart.c_str(),this));
00549                       curPart.clear();
00550                       _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
00551                     }
00552                   else
00553                     curPart+=*iter;
00554                 }
00555               else
00556                 curPart+=*iter;
00557             }
00558         break;
00559         case '(':
00560           curLevel++;
00561           curPart+=*iter;
00562           break;
00563         case ')':
00564           curLevel--;
00565           curPart+=*iter;
00566           break;
00567         default:
00568           curPart+=*iter;
00569         }
00570     }
00571   if(isParsingSucceed)
00572     {
00573       if(!curPart.empty())
00574         {
00575           _sub_expr.push_back(ExprParser(curPart.c_str(),this));
00576           _is_parsing_ok=true;
00577         }
00578       else
00579         {
00580           std::ostringstream errMsg;
00581           char MSGTYP4[]="Error following expression finished by +/- without right part.";
00582           errMsg << EXPR_PARSE_ERR_MSG << MSGTYP4 << _expr;
00583           throw INTERP_KERNEL::Exception(errMsg.str().c_str());
00584         }
00585     }
00586 }
00587 
00588 void ExprParser::parseForMulDiv() throw(INTERP_KERNEL::Exception)
00589 {
00590   std::string::const_iterator iter;
00591   int curLevel=0;
00592   std::string curPart;
00593   bool isParsingSucceed=false;
00594   for(iter=_expr.begin();iter!=_expr.end();iter++)
00595     {
00596       switch(*iter)
00597         {
00598         case '/':
00599         case '*':
00600           if(curLevel!=0)
00601             curPart+=*iter;
00602           else
00603             {
00604               isParsingSucceed=true;
00605               if(!curPart.empty())
00606                 {
00607                   _sub_expr.push_back(ExprParser(curPart.c_str(),this));
00608                   curPart.clear();
00609                   _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
00610                 }
00611               else
00612                 {
00613                   std::ostringstream errMsg;
00614                   char MSGTYP1[]="Error non unary function for '";
00615                   errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'";
00616                   std::string tmp=_expr.substr(iter-_expr.begin());
00617                   LocateError(errMsg,tmp,0);
00618                   throw INTERP_KERNEL::Exception(errMsg.str().c_str());
00619                 }
00620             }
00621         break;
00622         case '(':
00623           curLevel++;
00624           curPart+=*iter;
00625           break;
00626         case ')':
00627           curLevel--;
00628           curPart+=*iter;
00629           break;
00630         default:
00631           curPart+=*iter;
00632         }
00633     }
00634   if(isParsingSucceed)
00635     {
00636       if(!curPart.empty())
00637         {
00638           _sub_expr.push_back(ExprParser(curPart.c_str(),this));
00639           _is_parsing_ok=true;
00640         }
00641       else
00642         {
00643           std::ostringstream errMsg;
00644           char MSGTYP5[]="Error following expression finished by *// without right part.";
00645           errMsg << EXPR_PARSE_ERR_MSG << MSGTYP5 << _expr;
00646           throw INTERP_KERNEL::Exception(errMsg.str().c_str());
00647         }
00648     }
00649 }
00650 
00651 void ExprParser::parseForPow() throw(INTERP_KERNEL::Exception)
00652 {
00653   std::string::const_iterator iter;
00654   int curLevel=0;
00655   std::string curPart;
00656   bool isParsingSucceed=false;
00657   for(iter=_expr.begin();iter!=_expr.end();iter++)
00658     {
00659       switch(*iter)
00660         {
00661         case '^':
00662           if(curLevel!=0)
00663             curPart+=*iter;
00664           else
00665             if(!curPart.empty())
00666               {
00667                 isParsingSucceed=true;
00668                 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
00669                 curPart.clear();
00670                 _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
00671               }
00672             else
00673               {
00674                 std::ostringstream errMsg;
00675                 char MSGTYP1[]="Error non unary function for '";
00676                 errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'";
00677                 std::string tmp=_expr.substr(iter-_expr.begin());
00678                 LocateError(errMsg,tmp,0);curPart+=*iter;
00679                 throw INTERP_KERNEL::Exception(errMsg.str().c_str());
00680               }
00681           break;
00682         case '(':
00683           curLevel++;
00684           curPart+=*iter;
00685           break;
00686         case ')':
00687           curLevel--;
00688           curPart+=*iter;
00689           break;
00690         default:
00691           curPart+=*iter;
00692         }
00693     }
00694   if(isParsingSucceed)
00695     {
00696       if(!curPart.empty())
00697         {
00698           _sub_expr.push_back(ExprParser(curPart.c_str(),this));
00699           _is_parsing_ok=true;
00700         }
00701       else
00702         {
00703           std::ostringstream errMsg;
00704           char MSGTYP6[]="Error following expression finished by ^ without right part.";
00705           errMsg << EXPR_PARSE_ERR_MSG << MSGTYP6 << _expr;
00706           throw INTERP_KERNEL::Exception(errMsg.str().c_str());
00707         }
00708     }
00709 }
00710 
00711 void ExprParser::releaseFunctions()
00712 {
00713   for(std::list<Function *>::iterator iter=_func_btw_sub_expr.begin();iter!=_func_btw_sub_expr.end();iter++)
00714     delete *iter;
00715   _func_btw_sub_expr.clear();
00716 }
00717 
00723 bool ExprParser::simplify() throw(INTERP_KERNEL::Exception)
00724 {
00725   if(tryToInterpALeaf())
00726     return true;
00727   parseUnaryFunc();
00728   if(!_is_parsing_ok)
00729     {
00730       parseForCmp();
00731       if(!_is_parsing_ok)
00732         {
00733           parseForAddMin();
00734           if(!_is_parsing_ok)
00735             {
00736               parseForMulDiv();
00737               if(!_is_parsing_ok)
00738                 parseForPow();
00739             }
00740         }
00741     }
00742   if(!_is_parsing_ok)
00743     {
00744       std::ostringstream errMsg;
00745       char MSGTYP3[]="Error in interpreting : ";
00746       errMsg << EXPR_PARSE_ERR_MSG << MSGTYP3 << _expr;
00747       LocateError(errMsg,_expr,0);
00748       throw INTERP_KERNEL::Exception(errMsg.str().c_str());
00749     }
00750   return false;
00751 }
00752 
00753 void ExprParser::checkBracketsParity() const throw(INTERP_KERNEL::Exception)
00754 {
00755   std::string::const_iterator iter;
00756   int curLevel=0;
00757   for(iter=_expr.begin();iter!=_expr.end();iter++)
00758     {
00759       if(*iter=='(')
00760         curLevel++;
00761       else if(*iter==')')
00762         {
00763           if(curLevel==0)
00764             {
00765               std::ostringstream errMsg;
00766               char MSGTYP1[]="Error in brackets : closing brackets ')' before openning '('";
00767               errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1;
00768               LocateError(errMsg,_expr,(int)std::distance(_expr.begin(),iter));
00769               throw INTERP_KERNEL::Exception(errMsg.str().c_str());
00770             }
00771           curLevel--;
00772         }
00773     }
00774   if(curLevel!=0)
00775     {
00776       std::ostringstream errMsg;
00777       char MSGTYP2[]="Error in brackets : not finally closed expr.";
00778       errMsg << EXPR_PARSE_ERR_MSG << MSGTYP2;
00779       throw INTERP_KERNEL::Exception(errMsg.str().c_str());
00780     }
00781 }
00782 
00788 double ExprParser::ReplaceAndTraduce(std::string& expr, int id, std::size_t bg, std::size_t end, int& delta) throw(INTERP_KERNEL::Exception)
00789 {
00790   static const char MSG[]="Interal error : A string expected to be a float is not one ! Bug to signal !";
00791   std::istringstream stream;
00792   std::ostringstream oss;
00793   std::size_t end2=end!=std::string::npos?end-bg:end;
00794   std::string tmp=expr.substr(bg,end2);
00795   stream.str(tmp);
00796   double ret=std::numeric_limits<double>::max();
00797   stream >> ret;
00798   if(stream.fail())
00799     throw INTERP_KERNEL::Exception(MSG);
00800   if(!stream.eof())
00801     throw INTERP_KERNEL::Exception(MSG);
00802   oss << id;
00803   std::string tmp2(oss.str());
00804   std::size_t l1=tmp.length();
00805   delta=(int)tmp2.length()-(int)l1;
00806   expr.replace(bg,l1,tmp2);
00807   return ret;
00808 }
00809 
00815 void ExprParser::fillValuesInExpr(std::vector<double>& valuesInExpr) throw(INTERP_KERNEL::Exception)
00816 {
00817   const char FIGURES[]="0123456789";
00818   const std::string other("+-*^/(<>,");
00819   std::size_t lgth=_expr.length();
00820   int id=0,delta;
00821   for(std::size_t pos=0;pos!=std::string::npos;id++)
00822     {
00823       std::size_t pos2=_expr.find_first_of(FIGURES,pos,10);
00824       if(pos2==std::string::npos)
00825         break;
00826       if(pos2>0)
00827         {//treat case of "x*log10(x)" -> "10" should NOT be intercepted by this
00828           if(other.find_first_of(_expr[pos2-1])==std::string::npos)
00829             {
00830               pos=_expr.find_first_not_of(FIGURES,pos2,10);
00831               id--;
00832               continue;
00833             }
00834           if(_expr[pos2-1]==')')
00835             {
00836               pos=_expr.find_first_not_of(FIGURES,pos2,10);
00837               std::ostringstream oss; oss << "Problem on parsing : Number \"" << _expr.substr(pos2,pos!=std::string::npos?pos2-pos:std::string::npos);
00838               oss << "\" is right after close parenthesis... ')'";
00839               throw INTERP_KERNEL::Exception(oss.str().c_str());
00840             }
00841         }
00842       std::size_t pos3=_expr.find_first_not_of(FIGURES,pos2,10);
00843       if(pos3==std::string::npos)
00844         {//"x+1223442320"
00845           valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta));
00846           break;
00847         }
00848       if(_expr[pos3]=='.')
00849         pos3++;
00850       if(pos3<lgth)
00851         {
00852           std::size_t pos4=_expr.find_first_not_of(FIGURES,pos3,10);
00853           if(pos4==std::string::npos)
00854             {//"x+1223334.223"
00855               valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta));
00856               break;
00857             }
00858           else
00859             {
00860               if(_expr[pos4]!='e' && _expr[pos4]!='E')
00861                 {//"x+1223334.223+x"
00862                   valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,pos4,delta));
00863                   pos=pos4+delta;
00864                   continue;
00865                 }
00866               else
00867                 {
00868                   if(++pos4<lgth)
00869                     {
00870                       if(_expr[pos4]=='+' || _expr[pos4]=='-')
00871                         pos4++;
00872                       if(pos4>=lgth)
00873                         {//"x+1223334.223e+" or "1223334.223E-"
00874                           std::ostringstream oss; oss << "Invalid expr : float number at the end of expr is invalid lacking number after exponential and sign ! -> \"" << _expr.substr(pos2) << "\"";
00875                           throw INTERP_KERNEL::Exception(oss.str().c_str());
00876                         }
00877                       std::size_t pos5=_expr.find_first_not_of(FIGURES,pos4,10);
00878                       if(pos4==pos5)
00879                         {//"x+1223334.223e+x" or "1223334.223E-y"
00880                           std::ostringstream oss; oss << "Invalid expr : float number in expr is invalid lacking number after exponential ! -> \"" << _expr.substr(pos2,pos4-pos2) << "\"";
00881                           throw INTERP_KERNEL::Exception(oss.str().c_str());
00882                         }
00883                       //OK, normal case
00884                       valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,pos5,delta));
00885                       pos=pos5+delta;
00886                       continue;
00887                     }
00888                   else//"x+1223334.223e"
00889                     {
00890                       std::ostringstream oss; oss << "Invalid expr : float number at the end of expr is invalid lacking number after exponential ! " << _expr.substr(pos2);
00891                       throw INTERP_KERNEL::Exception(oss.str().c_str());
00892                     }
00893                 }
00894             }
00895         }
00896       else
00897         {//"x+1223334."
00898           valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta));
00899           break;
00900         }
00901     }
00902 }
00903 
00904 void ExprParser::replaceValues(const std::vector<double>& valuesInExpr) throw(INTERP_KERNEL::Exception)
00905 {
00906   if(_leaf)
00907     _leaf->replaceValues(valuesInExpr);
00908   else
00909     {
00910       for(std::list<ExprParser>::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
00911         (*iter).replaceValues(valuesInExpr);
00912     }
00913 }
00914 
00915 void ExprParser::LocateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr)
00916 {
00917   stringToDisp << "Position is " << posOfErr << " of string : \"" <<  srcOfErr << "\"" << std::endl;
00918 }
00919 
00920 char *ExprParser::compileX86() const
00921 {
00922   std::vector<std::string> ass;
00923   //need in stack
00924   ass.push_back("push ebp");
00925   ass.push_back("mov ebp,esp");
00926   compileX86LowLev(ass);
00927   ass.push_back("pop ebp");
00928   ass.push_back("ret");
00929   std::cout << std::endl;
00930   for(std::vector<std::string>::const_iterator iter=ass.begin();iter!=ass.end();iter++)
00931     std::cout << "        " << *iter << std::endl;
00932   AsmX86 asmb;
00933   std::vector<char> output=asmb.convertIntoMachineLangage(ass);
00934   for(std::vector<char>::const_iterator iter=output.begin();iter!=output.end();iter++)
00935     std::cout << std::hex << (int)((unsigned char)(*iter)) << " ";
00936   std::cout << std::endl;
00937   unsigned offset;
00938   return asmb.copyToExecMemZone(output,offset);
00939 }
00940 
00941 char *ExprParser::compileX86_64() const
00942 {
00943   std::vector<std::string> ass;
00944   //need in stack
00945   ass.push_back("push rbp");
00946   ass.push_back("mov rbp,rsp");
00947   compileX86_64LowLev(ass);
00948   ass.push_back("sub rsp,8");
00949   ass.push_back("fst qword [rsp]");
00950   ass.push_back("movsd xmm0,[rsp]");
00951   ass.push_back("add rsp,8");
00952   ass.push_back("leave");
00953   ass.push_back("ret");
00954   std::cout << std::endl;
00955   for(std::vector<std::string>::const_iterator iter=ass.begin();iter!=ass.end();iter++)
00956     std::cout << "        " << *iter << std::endl;
00957   AsmX86 asmb;
00958   std::vector<char> output=asmb.convertIntoMachineLangage(ass);
00959   for(std::vector<char>::const_iterator iter=output.begin();iter!=output.end();iter++)
00960     std::cout << std::hex << (int)((unsigned char)(*iter)) << " ";
00961   std::cout << std::endl;
00962   unsigned offset;
00963   return asmb.copyToExecMemZone(output,offset);
00964 }
00965 
00966 void ExprParser::compileX86LowLev(std::vector<std::string>& ass) const
00967 {
00968   if(_leaf)
00969     _leaf->compileX86(ass);
00970   else
00971     {
00972       for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
00973         (*iter).compileX86LowLev(ass);
00974     }
00975   for(std::list<Function *>::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++)
00976     (*iter2)->operateX86(ass);
00977 }
00978 
00979 void ExprParser::compileX86_64LowLev(std::vector<std::string>& ass) const
00980 {
00981   if(_leaf)
00982     _leaf->compileX86_64(ass);
00983   else
00984     {
00985       for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
00986         (*iter).compileX86_64LowLev(ass);
00987     }
00988   for(std::list<Function *>::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++)
00989     (*iter2)->operateX86(ass);
00990 }
00991 
00992 void LeafExprVal::compileX86(std::vector<std::string>& ass) const
00993 {
00994   ass.push_back("sub esp,8");
00995   int *b=(int *)&_value,*c=(int *)&_value;
00996   c++;
00997   std::ostringstream oss;
00998   oss << std::hex;
00999   oss << "mov dword [esp+4],0x" << *c;
01000   ass.push_back(oss.str());
01001   oss.str("");
01002   oss << "mov dword [esp],0x" << *b;
01003   ass.push_back(oss.str());
01004   ass.push_back("fld qword [esp]");
01005   ass.push_back("add esp,8");
01006 }
01007 
01008 void LeafExprVal::compileX86_64(std::vector<std::string>& ass) const
01009 {
01010   ass.push_back("sub rsp,8");
01011   int *b=(int *)&_value,*c=(int *)&_value;
01012   c++;
01013   std::ostringstream oss;
01014   oss << std::hex;
01015   oss << "mov dword [rsp+4],0x" << *c;
01016   ass.push_back(oss.str());
01017   oss.str("");
01018   oss << "mov dword [rsp],0x" << *b;
01019   ass.push_back(oss.str());
01020   ass.push_back("fld qword [rsp]");
01021   ass.push_back("add rsp,8");
01022 }
01023 
01024 void LeafExprVar::compileX86(std::vector<std::string>& ass) const
01025 {
01026   ass.push_back("fld qword [ebp+8]");
01027 }
01028 
01029 void LeafExprVar::compileX86_64(std::vector<std::string>& ass) const
01030 {
01031   ass.push_back("sub rsp,8");
01032   ass.push_back("movsd [rsp],xmm0");
01033   ass.push_back("fld qword [rsp]");
01034   ass.push_back("add rsp,8");
01035 }
01036 
01037 int ExprParser::getStackSizeToPlayX86(const ExprParser *asker) const
01038 {
01039   if(asker)
01040     {
01041       int sz=_father->getStackSizeToPlayX86(this);
01042       int i=0;
01043       for(std::list<ExprParser>::const_reverse_iterator iter=_sub_expr.rbegin();iter!=_sub_expr.rend();iter++,i++)
01044         {
01045           const ExprParser& obj=(*iter);
01046           const ExprParser *pt=&obj;
01047           if(pt==asker)
01048             return sz-i;
01049         }
01050       throw INTERP_KERNEL::Exception("error getStackSizeToPlayX86 an object ExprParser called as father, whereas it is not one !");
01051     }
01052   else
01053     {
01054       if(!_father)
01055         return MAX_X86_FP_ST;
01056       return _father->getStackSizeToPlayX86(this);
01057     }
01058 }