32 #define PARSER_CONST_PI 3.141592653589793238462643
33 #define PARSER_CONST_E 2.718281828459045235360287
35 #define wxT(x) MUP_T(x)
48 int ParserTester::c_iCount = 0;
51 ParserTester::ParserTester()
118 iStat +=
EqnTest(
wxT(
"valueof(\"aaa\")+valueof(\"bbb\") "), 246,
true);
119 iStat +=
EqnTest(
wxT(
"2*(valueof(\"aaa\")-23)+valueof(\"bbb\")"), 323,
true);
121 iStat +=
EqnTest(
wxT(
"a*(atof(\"10\")-b)"), 8,
true);
122 iStat +=
EqnTest(
wxT(
"a-(atof(\"10\")*b)"), -19,
true);
124 iStat +=
EqnTest(
wxT(
"strfun1(\"100\")"), 100,
true);
125 iStat +=
EqnTest(
wxT(
"strfun2(\"100\",1)"), 101,
true);
126 iStat +=
EqnTest(
wxT(
"strfun3(\"99\",1,2)"), 102,
true);
146 iStat +=
EqnTest(
wxT(
"1 xor 2 xor 3"), 0,
true);
147 iStat +=
EqnTest(
wxT(
"a xor b xor 3"), 0,
true);
148 iStat +=
EqnTest(
wxT(
"a xor b xor c"), 0,
true);
149 iStat +=
EqnTest(
wxT(
"(1 xor 2) xor 3"), 0,
true);
150 iStat +=
EqnTest(
wxT(
"(a xor b) xor c"), 0,
true);
151 iStat +=
EqnTest(
wxT(
"(a) xor (b) xor c"), 0,
true);
157 iStat +=
EqnTest(
wxT(
"a = sin(b)"), 0.909297,
true);
158 iStat +=
EqnTest(
wxT(
"a = 1+sin(b)"), 1.909297,
true);
237 mu::console() <<
"testing name restriction enforcement...";
241 #define PARSER_THROWCHECK(DOMAIN, FAIL, EXPR, ARG) \
243 ParserTester::c_iCount++; \
246 p.Define##DOMAIN(EXPR, ARG); \
248 catch(Parser::exception_type&) \
250 iErr = (FAIL==false) ? 0 : 1; \
322 #undef PARSER_THROWCHECK
340 iStat +=
EqnTest(
wxT(
"sqrt((2)+2)"), 2,
true);
341 iStat +=
EqnTest(
wxT(
"sqrt(2+(2))"), 2,
true);
342 iStat +=
EqnTest(
wxT(
"sqrt(a+(3))"), 2,
true);
343 iStat +=
EqnTest(
wxT(
"sqrt((3)+a)"), 2,
true);
379 mu::console() <<
wxT(
"testing variable/constant name recognition...");
389 iStat +=
EqnTest(
wxT(
"2*const1+1"), 5,
true);
390 iStat +=
EqnTest(
wxT(
"2*const2+1"), 7,
true);
419 int iCount = (
int)UsedVar.size();
420 if (iCount!=4)
throw false;
422 mu::varmap_type::const_iterator item = UsedVar.begin();
423 for (idx=0; item!=UsedVar.end(); ++item)
425 if (&vVarVal[idx++]!=item->second)
432 iCount = (
int)UsedVar.size();
433 if (iCount!=3)
throw false;
435 for (item = UsedVar.begin(); item!=UsedVar.end(); ++item)
444 iCount = (
int)UsedVar.size();
445 if (iCount!=2)
throw false;
446 item = UsedVar.begin();
447 for (idx=0; item!=UsedVar.end(); ++item)
448 if (&vVarVal[idx++]!=item->second)
throw false;
472 iStat +=
EqnTest(
wxT(
"f1of2(1, 2)"), 1,
true);
473 iStat +=
EqnTest(
wxT(
"f2of2(1, 2)"), 2,
true);
474 iStat +=
EqnTest(
wxT(
"f1of3(1, 2, 3)"), 1,
true);
475 iStat +=
EqnTest(
wxT(
"f2of3(1, 2, 3)"), 2,
true);
476 iStat +=
EqnTest(
wxT(
"f3of3(1, 2, 3)"), 3,
true);
477 iStat +=
EqnTest(
wxT(
"f1of4(1, 2, 3, 4)"), 1,
true);
478 iStat +=
EqnTest(
wxT(
"f2of4(1, 2, 3, 4)"), 2,
true);
479 iStat +=
EqnTest(
wxT(
"f3of4(1, 2, 3, 4)"), 3,
true);
480 iStat +=
EqnTest(
wxT(
"f4of4(1, 2, 3, 4)"), 4,
true);
481 iStat +=
EqnTest(
wxT(
"f1of5(1, 2, 3, 4, 5)"), 1,
true);
482 iStat +=
EqnTest(
wxT(
"f2of5(1, 2, 3, 4, 5)"), 2,
true);
483 iStat +=
EqnTest(
wxT(
"f3of5(1, 2, 3, 4, 5)"), 3,
true);
484 iStat +=
EqnTest(
wxT(
"f4of5(1, 2, 3, 4, 5)"), 4,
true);
485 iStat +=
EqnTest(
wxT(
"f5of5(1, 2, 3, 4, 5)"), 5,
true);
491 iStat +=
EqnTest(
wxT(
"ping(1,2)"), 0,
false);
492 iStat +=
EqnTest(
wxT(
"1+ping(1,2)"), 0,
false);
493 iStat +=
EqnTest(
wxT(
"f1of1(1,2)"), 0,
false);
495 iStat +=
EqnTest(
wxT(
"f1of2(1, 2, 3)"), 0,
false);
497 iStat +=
EqnTest(
wxT(
"f1of3(1, 2, 3, 4)"), 0,
false);
499 iStat +=
EqnTest(
wxT(
"f1of4(1, 2, 3, 4, 5)"), 0,
false);
503 iStat +=
EqnTest(
wxT(
"(1*a,2,3)"), 0,
false);
508 iStat +=
EqnTest(
wxT(
"min(3*2, 1)"), 1,
true);
509 iStat +=
EqnTest(
wxT(
"min(3*2, 1)"), 6,
false);
510 iStat +=
EqnTest(
wxT(
"firstArg(2,3,4)"), 2,
true);
511 iStat +=
EqnTest(
wxT(
"lastArg(2,3,4)"), 4,
true);
512 iStat +=
EqnTest(
wxT(
"min(3*a+1, 1)"), 1,
true);
513 iStat +=
EqnTest(
wxT(
"max(3*a+1, 1)"), 4,
true);
514 iStat +=
EqnTest(
wxT(
"max(3*a+1, 1)*2"), 8,
true);
515 iStat +=
EqnTest(
wxT(
"2*max(3*a+1, 1)+2"), 10,
true);
519 iStat +=
EqnTest(
wxT(
"sum(1,2,3)"), 6,
true);
520 iStat +=
EqnTest(
wxT(
"sum(a,b,c)"), 6,
true);
521 iStat +=
EqnTest(
wxT(
"sum(1,-max(1,2),3)*2"), 4,
true);
522 iStat +=
EqnTest(
wxT(
"2*sum(1,2,3)"), 12,
true);
523 iStat +=
EqnTest(
wxT(
"2*sum(1,2,3)+2"), 14,
true);
524 iStat +=
EqnTest(
wxT(
"2*sum(-1,2,3)+2"), 10,
true);
525 iStat +=
EqnTest(
wxT(
"2*sum(-1,2,-(-a))+2"), 6,
true);
526 iStat +=
EqnTest(
wxT(
"2*sum(-1,10,-a)+2"), 18,
true);
527 iStat +=
EqnTest(
wxT(
"2*sum(1,2,3)*2"), 24,
true);
528 iStat +=
EqnTest(
wxT(
"sum(1,-max(1,2),3)*2"), 4,
true);
529 iStat +=
EqnTest(
wxT(
"sum(1*3, 4, a+2)"), 10,
true);
530 iStat +=
EqnTest(
wxT(
"sum(1*3, 2*sum(1,2,2), a+2)"), 16,
true);
531 iStat +=
EqnTest(
wxT(
"sum(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2)"), 24,
true);
536 iStat +=
EqnTest(
wxT(
"sum(1,2,)"), 0,
false);
537 iStat +=
EqnTest(
wxT(
"sum(,1,2)"), 0,
false);
557 iStat +=
EqnTest(
wxT(
"-(-2)*sqrt(4)"), 4,
true);
565 iStat +=
EqnTest(
wxT(
"-(f1of1(1+2*3)+1*2)"), -9,
true);
566 iStat +=
EqnTest(
wxT(
"-(-f1of1(1+2*3)+1*2)"), 5,
true);
567 iStat +=
EqnTest(
wxT(
"-sin(8)"), -0.989358,
true);
573 iStat +=
EqnTest(
wxT(
"~f1of1(2)#"), 8,
true);
577 iStat +=
EqnTest(
wxT(
"~(f1of1(2)#)"), 8,
true);
620 iStat +=
EqnTest(
wxT(
"f1of1(1000)m"), 1,
true);
621 iStat +=
EqnTest(
wxT(
"-f1of1(1000)m"), -1,
true);
622 iStat +=
EqnTest(
wxT(
"-f1of1(-1000)m"), 1,
true);
623 iStat +=
EqnTest(
wxT(
"f4of4(0,0,0,1000)m"), 1,
true);
624 iStat +=
EqnTest(
wxT(
"2+(a*1000)m"), 3,
true);
653 mu::console() <<
"testing volatile/nonvolatile functions...";
684 p.
SetExpr(
wxT(
"valueof(\"Das ist ein Test\")") );
742 iStat +=
EqnTest(
wxT(
"1+2-3*4/5^6"), 2.99923,
true);
743 iStat +=
EqnTest(
wxT(
"1^2/3*4-5+6"), 2.3333,
true);
747 iStat +=
EqnTest(
wxT(
"(1+2)*(-3)"), -9,
true);
750 iStat +=
EqnTest(
wxT(
"exp(ln(7))"), 7,
true);
753 iStat +=
EqnTest(
wxT(
"(e^(ln(7)))"), 7,
true);
754 iStat +=
EqnTest(
wxT(
"1-(e^(ln(7)))"), -6,
true);
755 iStat +=
EqnTest(
wxT(
"2*(e^(ln(7)))"), 14,
true);
757 iStat +=
EqnTest(
wxT(
"10^log10(5)"), 5,
true);
759 iStat +=
EqnTest(
wxT(
"-(sin(0)+1)"), -1,
true);
760 iStat +=
EqnTest(
wxT(
"-(2^1.1)"), -2.14354692,
true);
762 iStat +=
EqnTest(
wxT(
"(cos(2.41)/b)"), -0.372056,
true);
764 #if !defined(MUP_UNICODE)
770 "(((-9))-e/(((((((pi-(((-7)+(-3)/4/e))))/(((-5))-2)-((pi+(-0))*(sqrt((e+e))*(-8))*(((-pi)+(-pi)-(-9)*(6*5))"
771 "/(-e)-e))/2)/((((sqrt(2/(-e)+6)-(4-2))+((5/(-2))/(1*(-pi)+3))/8)*pi*((pi/((-2)/(-6)*1*(-1))*(-6)+(-e)))))/"
772 "((e+(-2)+(-e)*((((-3)*9+(-e)))+(-9)))))))-((((e-7+(((5/pi-(3/1+pi)))))/e)/(-5))/(sqrt((((((1+(-7))))+((((-"
773 "e)*(-e)))-8))*(-5)/((-e)))*(-6)-((((((-2)-(-9)-(-e)-1)/3))))/(sqrt((8+(e-((-6))+(9*(-9))))*(((3+2-8))*(7+6"
774 "+(-5))+((0/(-e)*(-pi))+7)))+(((((-e)/e/e)+((-6)*5)*e+(3+(-5)/pi))))+pi))/sqrt((((9))+((((pi))-8+2))+pi))/e"
775 "*4)*((-5)/(((-pi))*(sqrt(e)))))-(((((((-e)*(e)-pi))/4+(pi)*(-9)))))))+(-pi)", -12.23016549,
true);
779 "(atan(sin((((((((((((((((pi/cos((a/((((0.53-b)-pi)*e)/b))))+2.51)+a)-0.54)/0.98)+b)*b)+e)/a)+b)+a)+b)+pi)/e"
780 ")+a)))*2.77)", -2.16995656,
true);
784 iStat +=
EqnTest(
wxT(
"1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12"), -7995810.09926,
true);
822 iStat +=
ThrowTest(
wxT(
"valueof(\"xxx\")"), 999,
false);
830 iStat +=
ThrowTest(
wxT(
"valueof(\"\\\"abc\\\"\")"), 999,
false);
889 catch(std::exception &e)
908 <<
" expressions)" << endl;
939 if (a_bFail==
false || (a_bFail==
true && a_iErrc!=e.
GetCode()) )
942 <<
wxT(
"Expression: ") << a_str
944 <<
wxT(
" Expected:") << a_iErrc;
947 return (a_iErrc==e.
GetCode()) ? 0 : 1;
951 bool bRet((a_bFail==
false) ? 0 : 1);
955 <<
wxT(
"Expression: ") << a_str
956 <<
wxT(
" did evaluate; Expected error:") << a_iErrc;
1035 value_type fVal[4] = {-999, -998, -997, -996};
1036 fVal[0] = p1->
Eval();
1037 fVal[1] = p1->
Eval();
1038 if (fVal[0]!=fVal[1])
1045 std::vector<mu::Parser> vParser;
1046 vParser.push_back(*p1);
1054 fVal[2] = p2.
Eval();
1061 fVal[3] = p3.
Eval();
1063 catch(std::exception &e)
1069 bool bCloseEnough(
true);
1070 for (
int i=0;
i<4; ++
i)
1072 bCloseEnough &= (
fabs(a_fRes-fVal[
i]) <=
fabs(fVal[
i]*0.0001));
1075 iRet = ((bCloseEnough && a_fPass) || (!bCloseEnough && !a_fPass)) ? 0 : 1;
1079 <<
wxT(
" (incorrect result; expected: ") << a_fRes
1080 <<
wxT(
" ;calculated: ") << fVal[0]<<
wxT(
").");
1091 catch(std::exception &e)
1098 mu::console() <<
wxT(
"\n fail: ") << a_str.c_str() <<
wxT(
" (unexpected exception)");
1127 if (fVal[0]!=fVal[1])
1130 iRet = ( (a_fRes==fVal[0] && a_fPass) ||
1131 (a_fRes!=fVal[0] && !a_fPass) ) ? 0 : 1;
1135 <<
wxT(
" (incorrect result; expected: ") << a_fRes
1136 <<
wxT(
" ;calculated: ") << fVal[0]<<
wxT(
").");
1149 mu::console() <<
wxT(
"\n fail: ") << a_str.c_str() <<
wxT(
" (unexpected exception)");
1160 mu::console() <<
wxT(
"Test failed (internal error in test class)") << endl;
void EnableOptimizer(bool a_bIsOn=true)
Enable or disable the formula optimization feature.
void DefineInfixOprt(const string_type &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool a_bAllowOpt=true)
Add a user defined operator.
value_type Eval() const
Calculate the result.
void DefineVar(const string_type &a_sName, value_type *a_fVar)
Add a user defined variable.
void DefineConst(const string_type &a_sName, value_type a_fVal)
Add a user defined constant.
void RemoveVar(const string_type &a_strVarName)
Remove a variable from internal storage.
ParserError exception_type
Type of the error class.
void ClearConst()
Clear all user defined constants.
void EnableBuiltInOprt(bool a_bIsOn=true)
Enable or disable the built in binary operators.
void DefinePostfixOprt(const string_type &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true)
Add a user defined operator.
void SetExpr(const string_type &a_sExpr)
Set the formula.
void DefineFun(const string_type &a_strName, fun_type0 a_pFun, bool a_bAllowOpt=true)
const varmap_type & GetUsedVar() const
Return a map containing the used variables only.
Error class of the parser.
EErrorCodes GetCode() const
Return the error code.
const string_type & GetMsg() const
Returns the message string for this error.
const string_type & GetExpr() const
gets the expression related tp this error.
const string_type & GetToken() const
Return string related with this token (if available).
Mathematical expressions parser.
Mathematical expressions parser.
static value_type f2of4(value_type, value_type v, value_type, value_type)
static value_type ValueOf(const char_type *)
static value_type Sum(const value_type *a_afArg, int a_iArgc)
static value_type f2of3(value_type, value_type v, value_type)
static value_type StrFun3(const char_type *v1, value_type v2, value_type v3)
std::vector< testfun_type > m_vTestFun
void Abort() const
Internal error in test class Test is going to be aborted.
static value_type Min(value_type a_fVal1, value_type a_fVal2)
int ThrowTest(const string_type &a_str, int a_iErrc, bool a_bFail=true)
int EqnTestInt(const string_type &a_str, double a_fRes, bool a_fPass)
static value_type f4of5(value_type, value_type, value_type, value_type v, value_type)
static value_type Milli(value_type v)
static value_type f3of3(value_type, value_type, value_type v)
static value_type FirstArg(const value_type *a_afArg, int a_iArgc)
static value_type plus2(value_type v1)
static value_type times3(value_type v1)
static value_type RndWithString(const char_type *)
int TestVolatile()
Test volatile (nonoptimizeable functions).
static value_type LastArg(const value_type *a_afArg, int a_iArgc)
static value_type Rnd(value_type v)
static value_type f2of2(value_type, value_type v)
static value_type f4of4(value_type, value_type, value_type, value_type v)
static value_type f1of4(value_type v, value_type, value_type, value_type)
static value_type Max(value_type a_fVal1, value_type a_fVal2)
static value_type sign(value_type v)
void AddTest(testfun_type a_pFun)
int EqnTest(const string_type &a_str, double a_fRes, bool a_fPass)
Evaluate a tet expression.
static value_type f3of4(value_type, value_type, value_type v, value_type)
static value_type f2of5(value_type, value_type v, value_type, value_type, value_type)
static value_type StrFun1(const char_type *v1)
int TestNames()
Check muParser name restriction enforcement.
static value_type f1of3(value_type v, value_type, value_type)
static value_type f1of1(value_type v)
static value_type f3of5(value_type, value_type, value_type v, value_type, value_type)
static value_type StrToFloat(const char_type *a_szMsg)
static value_type f5of5(value_type, value_type, value_type, value_type, value_type v)
static value_type f1of2(value_type v, value_type)
static value_type sqr(value_type v1)
static value_type f1of5(value_type v, value_type, value_type, value_type, value_type)
static value_type StrFun2(const char_type *v1, value_type v2)
static void Test(const char *bind1, SQLSMALLINT type1, const char *bind2, SQLSMALLINT type2)
unsigned int
A callback function used to compare two keys in a database.
#define PARSER_THROWCHECK(DOMAIN, FAIL, EXPR, ARG)
This file contains the parser test class.
Namespace for mathematical applications.
std::ostream & console()
Encapsulate cout.
std::map< string_type, value_type * > varmap_type
Type used for storing variables.
@ prPOW
power operator priority (highest)
@ ecUNASSIGNABLE_TOKEN
Token cant be identified.
@ ecMISSING_PARENS
Missing parens. (Example: "3*sin(3")
@ ecUNEXPECTED_EOF
Unexpected end of formula. (Example: "2+sin(")
@ ecSTRING_EXPECTED
A string function has been called with a different type of argument.
@ ecTOO_MANY_PARAMS
Too many function parameters.
@ ecVAL_EXPECTED
A numerical function has been called with a non value type of argument.
@ ecUNEXPECTED_FUN
Unexpected function found. (Example: "sin(8)cos(9)")
@ ecSTR_RESULT
result is a string
@ ecUNEXPECTED_OPERATOR
Unexpected binary operator found.
@ ecOPRT_TYPE_CONFLICT
binary operators may only be applied to value items of the same type
@ ecUNEXPECTED_PARENS
Unexpected Parenthesis, opening or closing.
@ ecUNEXPECTED_ARG_SEP
An unexpected comma has been found. (Example: "1,23")
@ ecUNTERMINATED_STRING
unterminated string constant. (Example: "3*valueof("hello)")
@ ecTOO_FEW_PARAMS
Too few function parameters. (Example: "ite(1<2,2)")
@ ecUNEXPECTED_VAL
An unexpected value token has been found.
double value_type
The numeric datatype used by the parser.
std::string string_type
The stringtype used by the parser.