#include "rpneval.h" #include #include "strutilxx.h" #include "srandgen.h" #include #include namespace SOPHYA { /*! \class SOPHYA::RPNExpressionEvaluator \ingroup SysTools Arithmetic expression (double precision float) evaluator in Reverse Polish Notation (RPN). This is an HP calculator like syntax. Space are used for separating the string expression into tokens. */ RPNExpressionEvaluator::RPNExpressionEvaluator(string const & sex) { vector exe; FillVStringFrString(sex, exe, ' '); int rc = EvalRPNExpr(exe, 0); if (rc < exe.size()) { string msg = "RPNExpressionEvaluator() - syntax error near "; msg += exe[rc]; char buff[32]; sprintf(buff," (word %d)",rc); msg += buff; throw RPNExprException(msg); } } RPNExpressionEvaluator::RPNExpressionEvaluator(vector & exe, int off) { int rc = EvalRPNExpr(exe, off); if (rc < exe.size()) { string msg = "RPNExpressionEvaluator() - syntax error near "; msg += exe[rc]; char buff[32]; sprintf(buff," (word %d)",rc); msg += buff; throw RPNExprException(msg); } } RPNExpressionEvaluator::~RPNExpressionEvaluator() { } /* Operations sur le stack RPN */ /* --Methode-- */ double RPNExpressionEvaluator::Evaluate() const { double x; if ( CheckStack( x) ) throw RPNExprException("RPNExpressionEvaluator::Evaluate() EmptyStack"); else return x; } /* --Methode-- */ int RPNExpressionEvaluator::EvalRPNExpr(vector & args, int off) { if (args.size() <= off) return 1; double x,y; x = y = 0.; for(int k=off; ky") { if ( CheckStack( x, y) ) return k; rpnstack_.top() = x; rpnstack_.push(y); } else if (args[k] == "pop") { rpnstack_.pop(); } else if (args[k] == "push") { if (rpnstack_.empty()) rpnstack_.push(0.); else rpnstack_.push(rpnstack_.top()); } // On met un nombre sur le stack else { char * esptr; x = strtod(args[k].c_str(), &esptr); // if (ctof(args[k].c_str(),&x) < 0) { if (esptr == args[k].c_str()) return k; rpnstack_.push(x); } } return(args.size()+1); } inline void RPNExpressionEvaluator::PrintStack() { if (rpnstack_.empty()) cout << "RPNExpressionEvaluator::PrintStack() Empty stack " << endl; else { stack s; s = rpnstack_; int k = 0; cout << "RPNExpressionEvaluator::PrintStack() Size()= " << s.size() << endl; while( !s.empty() ) { cout << " " << k << ": " << s.top() << " "; if (k == 0) cout << " (x) " << endl; else if (k == 1) cout << " (y) " << endl; else if (k == 2) cout << " (z) " << endl; else cout << endl; s.pop(); k++; } } } int RPNExpressionEvaluator::SumStack(double& sx, double& sx2) { sx = sx2 = 0.; int nn = 0; double x = 0.; while( !rpnstack_.empty() ) { x = rpnstack_.top(); rpnstack_.pop(); sx += x; sx2 += x*x; nn++; } return(nn); } int RPNExpressionEvaluator::ProductStack(double& px) { px = 1.; int nn = 0; double x = 0.; while( !rpnstack_.empty() ) { x = rpnstack_.top(); rpnstack_.pop(); px *= x; nn++; } return(nn); } } // End of namespace SOPHYA