#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 != 0) throw RPNExprException("RPNExpressionEvaluator() - syntax error"); } RPNExpressionEvaluator::RPNExpressionEvaluator(vector & exe, int off) { int rc = EvalRPNExpr(exe, off); if (rc != 0) throw RPNExprException("RPNExpressionEvaluator() - syntax error"); } 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 0; double x,y; x = y = 0.; stack rpnstack_; // Stack des operations en RPN for(int k=off; ky") { if ( CheckStack( x, y) ) return(1); 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 2; rpnstack_.push(x); } } return(0); } 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