33 #define PARSER_CONST_PI 3.141592653589793238462643
34 #define PARSER_CONST_E 2.718281828459045235360287
46 int ParserTester::c_iCount = 0;
49 ParserTester::ParserTester()
52 AddTest(&ParserTester::TestNames);
53 AddTest(&ParserTester::TestSyntax);
54 AddTest(&ParserTester::TestPostFix);
55 AddTest(&ParserTester::TestInfixOprt);
56 AddTest(&ParserTester::TestVarConst);
57 AddTest(&ParserTester::TestMultiArg);
58 AddTest(&ParserTester::TestExpression);
59 AddTest(&ParserTester::TestIfThenElse);
60 AddTest(&ParserTester::TestInterface);
61 AddTest(&ParserTester::TestBinOprt);
62 AddTest(&ParserTester::TestException);
63 AddTest(&ParserTester::TestStrArg);
64 AddTest(&ParserTester::TestBulkMode);
66 ParserTester::c_iCount = 0;
72 if (a_szExpr[1]==0 || (a_szExpr[0]!=
'0' || a_szExpr[1]!=
'x') )
78 stringstream_type::pos_type nPos(0);
80 ss >> std::hex >> iVal;
83 if (nPos==(stringstream_type::pos_type)0)
86 *a_iPos += (int)(2 + nPos);
92 int ParserTester::TestInterface()
128 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
134 int ParserTester::TestStrArg()
139 iStat += EqnTest(
_T(
"valueof(\"\")"), 123,
true);
140 iStat += EqnTest(
_T(
"valueof(\"aaa\")+valueof(\"bbb\") "), 246,
true);
141 iStat += EqnTest(
_T(
"2*(valueof(\"aaa\")-23)+valueof(\"bbb\")"), 323,
true);
143 iStat += EqnTest(
_T(
"a*(atof(\"10\")-b)"), 8,
true);
144 iStat += EqnTest(
_T(
"a-(atof(\"10\")*b)"), -19,
true);
146 iStat += EqnTest(
_T(
"strfun1(\"100\")"), 100,
true);
147 iStat += EqnTest(
_T(
"strfun2(\"100\",1)"), 101,
true);
148 iStat += EqnTest(
_T(
"strfun3(\"99\",1,2)"), 102,
true);
150 iStat += EqnTest(
_T(
"atof(str1)+atof(str2)"), 3.33,
true);
155 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
161 int ParserTester::TestBulkMode()
166 #define EQN_TEST_BULK(EXPR, R1, R2, R3, R4, PASS) \
168 double res[] = { R1, R2, R3, R4 }; \
169 iStat += EqnTestBulk(_T(EXPR), res, (PASS)); \
177 EQN_TEST_BULK(
"a", 1, 1, 1, 1,
false)
178 EQN_TEST_BULK(
"a", 1, 2, 3, 4,
true)
179 EQN_TEST_BULK(
"b=a", 1, 2, 3, 4,
true)
180 EQN_TEST_BULK(
"b=a, b*10", 10, 20, 30, 40,
true)
181 EQN_TEST_BULK(
"b=a, b*10, a", 1, 2, 3, 4,
true)
182 EQN_TEST_BULK(
"a+b", 3, 4, 5, 6,
true)
183 EQN_TEST_BULK(
"c*(a+b)", 9, 12, 15, 18,
true)
189 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
195 int ParserTester::TestBinOprt()
203 iStat += EqnTest(
_T(
"a++b"), 3,
true);
204 iStat += EqnTest(
_T(
"a ++ b"), 3,
true);
205 iStat += EqnTest(
_T(
"1++2"), 3,
true);
206 iStat += EqnTest(
_T(
"1 ++ 2"), 3,
true);
207 iStat += EqnTest(
_T(
"a add b"), 3,
true);
208 iStat += EqnTest(
_T(
"1 add 2"), 3,
true);
209 iStat += EqnTest(
_T(
"a<b"), 1,
true);
210 iStat += EqnTest(
_T(
"b>a"), 1,
true);
211 iStat += EqnTest(
_T(
"a>a"), 0,
true);
212 iStat += EqnTest(
_T(
"a<a"), 0,
true);
213 iStat += EqnTest(
_T(
"a>a"), 0,
true);
214 iStat += EqnTest(
_T(
"a<=a"), 1,
true);
215 iStat += EqnTest(
_T(
"a<=b"), 1,
true);
216 iStat += EqnTest(
_T(
"b<=a"), 0,
true);
217 iStat += EqnTest(
_T(
"a>=a"), 1,
true);
218 iStat += EqnTest(
_T(
"b>=a"), 1,
true);
219 iStat += EqnTest(
_T(
"a>=b"), 0,
true);
222 iStat += EqnTest(
_T(
"1 && 1"), 1,
true);
223 iStat += EqnTest(
_T(
"1 && 0"), 0,
true);
224 iStat += EqnTest(
_T(
"(a<b) && (b>a)"), 1,
true);
225 iStat += EqnTest(
_T(
"(a<b) && (a>b)"), 0,
true);
228 iStat += EqnTest(
_T(
"12 & 255"), 12,
true);
229 iStat += EqnTest(
_T(
"12 & 0"), 0,
true);
230 iStat += EqnTest(
_T(
"12&255"), 12,
true);
231 iStat += EqnTest(
_T(
"12&0"), 0,
true);
234 iStat += EqnTest(
_T(
"a = b"), 2,
true);
235 iStat += EqnTest(
_T(
"a = sin(b)"), 0.909297,
true);
236 iStat += EqnTest(
_T(
"a = 1+sin(b)"), 1.909297,
true);
237 iStat += EqnTest(
_T(
"(a=b)*2"), 4,
true);
238 iStat += EqnTest(
_T(
"2*(a=b)"), 4,
true);
239 iStat += EqnTest(
_T(
"2*(a=b+1)"), 6,
true);
240 iStat += EqnTest(
_T(
"(a=b+1)*2"), 6,
true);
241 iStat += EqnTest(
_T(
"a=c, a*10"), 30,
true);
243 iStat += EqnTest(
_T(
"2^2^3"), 256,
true);
244 iStat += EqnTest(
_T(
"1/2/3"), 1.0/6.0,
true);
247 iStat += EqnTest(
_T(
"3+4*2/(1-5)^2^3"), 3.0001220703125,
true);
250 iStat += EqnTestInt(
_T(
"1 | 2"), 3,
true);
251 iStat += EqnTestInt(
_T(
"1 || 2"), 1,
true);
252 iStat += EqnTestInt(
_T(
"123 & 456"), 72,
true);
253 iStat += EqnTestInt(
_T(
"(123 & 456) % 10"), 2,
true);
254 iStat += EqnTestInt(
_T(
"1 && 0"), 0,
true);
255 iStat += EqnTestInt(
_T(
"123 && 456"), 1,
true);
256 iStat += EqnTestInt(
_T(
"1 << 3"), 8,
true);
257 iStat += EqnTestInt(
_T(
"8 >> 3"), 1,
true);
258 iStat += EqnTestInt(
_T(
"9 / 4"), 2,
true);
259 iStat += EqnTestInt(
_T(
"9 % 4"), 1,
true);
260 iStat += EqnTestInt(
_T(
"if(5%2,1,0)"), 1,
true);
261 iStat += EqnTestInt(
_T(
"if(4%2,1,0)"), 0,
true);
262 iStat += EqnTestInt(
_T(
"-10+1"), -9,
true);
263 iStat += EqnTestInt(
_T(
"1+2*3"), 7,
true);
264 iStat += EqnTestInt(
_T(
"const1 != const2"), 1,
true);
265 iStat += EqnTestInt(
_T(
"const1 != const2"), 0,
false);
266 iStat += EqnTestInt(
_T(
"const1 == const2"), 0,
true);
267 iStat += EqnTestInt(
_T(
"const1 == 1"), 1,
true);
268 iStat += EqnTestInt(
_T(
"10*(const1 == 1)"), 10,
true);
269 iStat += EqnTestInt(
_T(
"2*(const1 | const2)"), 6,
true);
270 iStat += EqnTestInt(
_T(
"2*(const1 | const2)"), 7,
false);
271 iStat += EqnTestInt(
_T(
"const1 < const2"), 1,
true);
272 iStat += EqnTestInt(
_T(
"const2 > const1"), 1,
true);
273 iStat += EqnTestInt(
_T(
"const1 <= 1"), 1,
true);
274 iStat += EqnTestInt(
_T(
"const2 >= 2"), 1,
true);
275 iStat += EqnTestInt(
_T(
"2*(const1 + const2)"), 6,
true);
276 iStat += EqnTestInt(
_T(
"2*(const1 - const2)"), -2,
true);
277 iStat += EqnTestInt(
_T(
"a != b"), 1,
true);
278 iStat += EqnTestInt(
_T(
"a != b"), 0,
false);
279 iStat += EqnTestInt(
_T(
"a == b"), 0,
true);
280 iStat += EqnTestInt(
_T(
"a == 1"), 1,
true);
281 iStat += EqnTestInt(
_T(
"10*(a == 1)"), 10,
true);
282 iStat += EqnTestInt(
_T(
"2*(a | b)"), 6,
true);
283 iStat += EqnTestInt(
_T(
"2*(a | b)"), 7,
false);
284 iStat += EqnTestInt(
_T(
"a < b"), 1,
true);
285 iStat += EqnTestInt(
_T(
"b > a"), 1,
true);
286 iStat += EqnTestInt(
_T(
"a <= 1"), 1,
true);
287 iStat += EqnTestInt(
_T(
"b >= 2"), 1,
true);
288 iStat += EqnTestInt(
_T(
"2*(a + b)"), 6,
true);
289 iStat += EqnTestInt(
_T(
"2*(a - b)"), -2,
true);
290 iStat += EqnTestInt(
_T(
"a + (a << b)"), 5,
true);
291 iStat += EqnTestInt(
_T(
"-2^2"), -4,
true);
292 iStat += EqnTestInt(
_T(
"3--a"), 4,
true);
293 iStat += EqnTestInt(
_T(
"3+-3^2"), -6,
true);
296 iStat += EqnTestInt(
_T(
"0xff"), 255,
true);
297 iStat += EqnTestInt(
_T(
"10+0xff"), 265,
true);
298 iStat += EqnTestInt(
_T(
"0xff+10"), 265,
true);
299 iStat += EqnTestInt(
_T(
"10*0xff"), 2550,
true);
300 iStat += EqnTestInt(
_T(
"0xff*10"), 2550,
true);
301 iStat += EqnTestInt(
_T(
"10+0xff+1"), 266,
true);
302 iStat += EqnTestInt(
_T(
"1+0xff+10"), 266,
true);
310 iStat += EqnTestInt(
_T(
"a + b * c"), 7,
true);
311 iStat += EqnTestInt(
_T(
"a * b + c"), 5,
true);
312 iStat += EqnTestInt(
_T(
"a<b && b>10"), 0,
true);
313 iStat += EqnTestInt(
_T(
"a<b && b<10"), 1,
true);
315 iStat += EqnTestInt(
_T(
"a + b << c"), 17,
true);
316 iStat += EqnTestInt(
_T(
"a << b + c"), 7,
true);
317 iStat += EqnTestInt(
_T(
"c * b < a"), 0,
true);
318 iStat += EqnTestInt(
_T(
"c * b == 6 * a"), 1,
true);
319 iStat += EqnTestInt(
_T(
"2^2^3"), 256,
true);
325 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
332 int ParserTester::TestNames()
337 mu::console() <<
"testing name restriction enforcement...";
341 #define PARSER_THROWCHECK(DOMAIN, FAIL, EXPR, ARG) \
343 ParserTester::c_iCount++; \
346 p.Define##DOMAIN(EXPR, ARG); \
348 catch(Parser::exception_type&) \
350 iErr = (FAIL==false) ? 0 : 1; \
355 PARSER_THROWCHECK(Const,
false,
_T(
"0a"), 1)
356 PARSER_THROWCHECK(Const,
false,
_T(
"9a"), 1)
357 PARSER_THROWCHECK(Const,
false,
_T(
"+a"), 1)
358 PARSER_THROWCHECK(Const,
false,
_T(
"-a"), 1)
359 PARSER_THROWCHECK(Const,
false,
_T(
"a-"), 1)
360 PARSER_THROWCHECK(Const,
false,
_T(
"a*"), 1)
361 PARSER_THROWCHECK(Const,
false,
_T(
"a?"), 1)
362 PARSER_THROWCHECK(Const,
true,
_T(
"a"), 1)
363 PARSER_THROWCHECK(Const,
true,
_T(
"a_min"), 1)
364 PARSER_THROWCHECK(Const,
true,
_T(
"a_min0"), 1)
365 PARSER_THROWCHECK(Const,
true,
_T(
"a_min9"), 1)
369 PARSER_THROWCHECK(Var,
false,
_T(
"123abc"), &a)
370 PARSER_THROWCHECK(Var,
false,
_T(
"9a"), &a)
371 PARSER_THROWCHECK(Var,
false,
_T(
"0a"), &a)
372 PARSER_THROWCHECK(Var,
false,
_T(
"+a"), &a)
373 PARSER_THROWCHECK(Var,
false,
_T(
"-a"), &a)
374 PARSER_THROWCHECK(Var,
false,
_T(
"?a"), &a)
375 PARSER_THROWCHECK(Var,
false,
_T(
"!a"), &a)
376 PARSER_THROWCHECK(Var,
false,
_T(
"a+"), &a)
377 PARSER_THROWCHECK(Var,
false,
_T(
"a-"), &a)
378 PARSER_THROWCHECK(Var,
false,
_T(
"a*"), &a)
379 PARSER_THROWCHECK(Var,
false,
_T(
"a?"), &a)
380 PARSER_THROWCHECK(Var,
true,
_T(
"a"), &a)
381 PARSER_THROWCHECK(Var,
true,
_T(
"a_min"), &a)
382 PARSER_THROWCHECK(Var,
true,
_T(
"a_min0"), &a)
383 PARSER_THROWCHECK(Var,
true,
_T(
"a_min9"), &a)
384 PARSER_THROWCHECK(Var,
false,
_T(
"a_min9"), 0)
387 PARSER_THROWCHECK(PostfixOprt,
false,
_T(
"(k"), f1of1)
388 PARSER_THROWCHECK(PostfixOprt,
false,
_T(
"9+"), f1of1)
389 PARSER_THROWCHECK(PostfixOprt,
false,
_T(
"+"), 0)
391 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"-a"), f1of1)
392 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"?a"), f1of1)
393 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"_"), f1of1)
394 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"#"), f1of1)
395 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"&&"), f1of1)
396 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"||"), f1of1)
397 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"&"), f1of1)
398 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"|"), f1of1)
399 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"++"), f1of1)
400 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"--"), f1of1)
401 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"?>"), f1of1)
402 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"?<"), f1of1)
403 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"**"), f1of1)
404 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"xor"), f1of1)
405 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"and"), f1of1)
406 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"or"), f1of1)
407 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"not"), f1of1)
408 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"!"), f1of1)
413 PARSER_THROWCHECK(Oprt,
false,
_T(
"+"), f1of2)
414 PARSER_THROWCHECK(Oprt,
false,
_T(
"-"), f1of2)
415 PARSER_THROWCHECK(Oprt,
false,
_T(
"*"), f1of2)
416 PARSER_THROWCHECK(Oprt,
false,
_T(
"/"), f1of2)
417 PARSER_THROWCHECK(Oprt,
false,
_T(
"^"), f1of2)
418 PARSER_THROWCHECK(Oprt,
false,
_T(
"&&"), f1of2)
419 PARSER_THROWCHECK(Oprt,
false,
_T(
"||"), f1of2)
422 PARSER_THROWCHECK(Oprt,
true,
_T(
"+"), f1of2)
423 PARSER_THROWCHECK(Oprt,
true,
_T(
"-"), f1of2)
424 PARSER_THROWCHECK(Oprt,
true,
_T(
"*"), f1of2)
425 PARSER_THROWCHECK(Oprt,
true,
_T(
"/"), f1of2)
426 PARSER_THROWCHECK(Oprt,
true,
_T(
"^"), f1of2)
427 PARSER_THROWCHECK(Oprt,
true,
_T(
"&&"), f1of2)
428 PARSER_THROWCHECK(Oprt,
true,
_T(
"||"), f1of2)
429 #undef PARSER_THROWCHECK
434 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
440 int ParserTester::TestSyntax()
451 iStat += EqnTest(
_T(
"(1+ 2*a)"), 3,
true);
452 iStat += EqnTest(
_T(
"sqrt((4))"), 2,
true);
453 iStat += EqnTest(
_T(
"sqrt((2)+2)"), 2,
true);
454 iStat += EqnTest(
_T(
"sqrt(2+(2))"), 2,
true);
455 iStat += EqnTest(
_T(
"sqrt(a+(3))"), 2,
true);
456 iStat += EqnTest(
_T(
"sqrt((3)+a)"), 2,
true);
457 iStat += EqnTest(
_T(
"order(1,2)"), 1,
true);
458 iStat += EqnTest(
_T(
"(2+"), 0,
false);
459 iStat += EqnTest(
_T(
"2++4"), 0,
false);
460 iStat += EqnTest(
_T(
"2+-4"), 0,
false);
461 iStat += EqnTest(
_T(
"(2+)"), 0,
false);
462 iStat += EqnTest(
_T(
"--2"), 0,
false);
463 iStat += EqnTest(
_T(
"ksdfj"), 0,
false);
464 iStat += EqnTest(
_T(
"()"), 0,
false);
465 iStat += EqnTest(
_T(
"5+()"), 0,
false);
466 iStat += EqnTest(
_T(
"sin(cos)"), 0,
false);
467 iStat += EqnTest(
_T(
"5t6"), 0,
false);
468 iStat += EqnTest(
_T(
"5 t 6"), 0,
false);
469 iStat += EqnTest(
_T(
"8*"), 0,
false);
470 iStat += EqnTest(
_T(
",3"), 0,
false);
471 iStat += EqnTest(
_T(
"3,5"), 0,
false);
472 iStat += EqnTest(
_T(
"sin(8,8)"), 0,
false);
473 iStat += EqnTest(
_T(
"(7,8)"), 0,
false);
474 iStat += EqnTest(
_T(
"sin)"), 0,
false);
475 iStat += EqnTest(
_T(
"a)"), 0,
false);
476 iStat += EqnTest(
_T(
"pi)"), 0,
false);
477 iStat += EqnTest(
_T(
"sin(())"), 0,
false);
478 iStat += EqnTest(
_T(
"sin()"), 0,
false);
483 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
489 int ParserTester::TestVarConst()
492 mu::console() <<
_T(
"testing variable/constant detection...");
495 iStat += EqnTestWithVarChange(
_T(
"a"), 1, 1, 2, 2 );
496 iStat += EqnTestWithVarChange(
_T(
"2*a"), 2, 4, 3, 6 );
499 iStat += EqnTest(
_T(
"const"), 1,
true);
500 iStat += EqnTest(
_T(
"const1"), 2,
true);
501 iStat += EqnTest(
_T(
"const2"), 3,
true);
502 iStat += EqnTest(
_T(
"2*const"), 2,
true);
503 iStat += EqnTest(
_T(
"2*const1"), 4,
true);
504 iStat += EqnTest(
_T(
"2*const2"), 6,
true);
505 iStat += EqnTest(
_T(
"2*const+1"), 3,
true);
506 iStat += EqnTest(
_T(
"2*const1+1"), 5,
true);
507 iStat += EqnTest(
_T(
"2*const2+1"), 7,
true);
508 iStat += EqnTest(
_T(
"const"), 0,
false);
509 iStat += EqnTest(
_T(
"const1"), 0,
false);
510 iStat += EqnTest(
_T(
"const2"), 0,
false);
513 iStat += EqnTest(
_T(
"a"), 1,
true);
514 iStat += EqnTest(
_T(
"aa"), 2,
true);
515 iStat += EqnTest(
_T(
"2*a"), 2,
true);
516 iStat += EqnTest(
_T(
"2*aa"), 4,
true);
517 iStat += EqnTest(
_T(
"2*a-1"), 1,
true);
518 iStat += EqnTest(
_T(
"2*aa-1"), 3,
true);
521 iStat += EqnTest(
_T(
"0xff"), 255,
true);
522 iStat += EqnTest(
_T(
"0x97 + 0xff"), 406,
true);
540 int iCount = (int)UsedVar.size();
549 mu::varmap_type::const_iterator item = UsedVar.begin();
550 for (idx=0; item!=UsedVar.end(); ++item)
552 if (&vVarVal[idx++]!=item->second)
559 iCount = (int)UsedVar.size();
568 for (item = UsedVar.begin(); item!=UsedVar.end(); ++item)
577 iCount = (int)UsedVar.size();
578 if (iCount!=2)
throw false;
579 item = UsedVar.begin();
580 for (idx=0; item!=UsedVar.end(); ++item)
581 if (&vVarVal[idx++]!=item->second)
throw false;
592 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
598 int ParserTester::TestMultiArg()
604 iStat += EqnTest(
_T(
"1,2,3"), 3,
true);
605 iStat += EqnTest(
_T(
"a,b,c"), 3,
true);
606 iStat += EqnTest(
_T(
"a=10,b=20,c=a*b"), 200,
true);
607 iStat += EqnTest(
_T(
"1,\n2,\n3"), 3,
true);
608 iStat += EqnTest(
_T(
"a,\nb,\nc"), 3,
true);
609 iStat += EqnTest(
_T(
"a=10,\nb=20,\nc=a*b"), 200,
true);
610 iStat += EqnTest(
_T(
"1,\r\n2,\r\n3"), 3,
true);
611 iStat += EqnTest(
_T(
"a,\r\nb,\r\nc"), 3,
true);
612 iStat += EqnTest(
_T(
"a=10,\r\nb=20,\r\nc=a*b"), 200,
true);
615 iStat += EqnTest(
_T(
"f1of1(1)"), 1,
true);
616 iStat += EqnTest(
_T(
"f1of2(1, 2)"), 1,
true);
617 iStat += EqnTest(
_T(
"f2of2(1, 2)"), 2,
true);
618 iStat += EqnTest(
_T(
"f1of3(1, 2, 3)"), 1,
true);
619 iStat += EqnTest(
_T(
"f2of3(1, 2, 3)"), 2,
true);
620 iStat += EqnTest(
_T(
"f3of3(1, 2, 3)"), 3,
true);
621 iStat += EqnTest(
_T(
"f1of4(1, 2, 3, 4)"), 1,
true);
622 iStat += EqnTest(
_T(
"f2of4(1, 2, 3, 4)"), 2,
true);
623 iStat += EqnTest(
_T(
"f3of4(1, 2, 3, 4)"), 3,
true);
624 iStat += EqnTest(
_T(
"f4of4(1, 2, 3, 4)"), 4,
true);
625 iStat += EqnTest(
_T(
"f1of5(1, 2, 3, 4, 5)"), 1,
true);
626 iStat += EqnTest(
_T(
"f2of5(1, 2, 3, 4, 5)"), 2,
true);
627 iStat += EqnTest(
_T(
"f3of5(1, 2, 3, 4, 5)"), 3,
true);
628 iStat += EqnTest(
_T(
"f4of5(1, 2, 3, 4, 5)"), 4,
true);
629 iStat += EqnTest(
_T(
"f5of5(1, 2, 3, 4, 5)"), 5,
true);
631 iStat += EqnTest(
_T(
"1+ping()"), 11,
true);
632 iStat += EqnTest(
_T(
"ping()+1"), 11,
true);
633 iStat += EqnTest(
_T(
"2*ping()"), 20,
true);
634 iStat += EqnTest(
_T(
"ping()*2"), 20,
true);
635 iStat += EqnTest(
_T(
"ping(1,2)"), 0,
false);
636 iStat += EqnTest(
_T(
"1+ping(1,2)"), 0,
false);
637 iStat += EqnTest(
_T(
"f1of1(1,2)"), 0,
false);
638 iStat += EqnTest(
_T(
"f1of1()"), 0,
false);
639 iStat += EqnTest(
_T(
"f1of2(1, 2, 3)"), 0,
false);
640 iStat += EqnTest(
_T(
"f1of2(1)"), 0,
false);
641 iStat += EqnTest(
_T(
"f1of3(1, 2, 3, 4)"), 0,
false);
642 iStat += EqnTest(
_T(
"f1of3(1)"), 0,
false);
643 iStat += EqnTest(
_T(
"f1of4(1, 2, 3, 4, 5)"), 0,
false);
644 iStat += EqnTest(
_T(
"f1of4(1)"), 0,
false);
645 iStat += EqnTest(
_T(
"(1,2,3)"), 0,
false);
646 iStat += EqnTest(
_T(
"1,2,3"), 0,
false);
647 iStat += EqnTest(
_T(
"(1*a,2,3)"), 0,
false);
648 iStat += EqnTest(
_T(
"1,2*a,3"), 0,
false);
651 iStat += EqnTest(
_T(
"min(a, 1)"), 1,
true);
652 iStat += EqnTest(
_T(
"min(3*2, 1)"), 1,
true);
653 iStat += EqnTest(
_T(
"min(3*2, 1)"), 6,
false);
654 iStat += EqnTest(
_T(
"firstArg(2,3,4)"), 2,
true);
655 iStat += EqnTest(
_T(
"lastArg(2,3,4)"), 4,
true);
656 iStat += EqnTest(
_T(
"min(3*a+1, 1)"), 1,
true);
657 iStat += EqnTest(
_T(
"max(3*a+1, 1)"), 4,
true);
658 iStat += EqnTest(
_T(
"max(3*a+1, 1)*2"), 8,
true);
659 iStat += EqnTest(
_T(
"2*max(3*a+1, 1)+2"), 10,
true);
662 iStat += EqnTest(
_T(
"sum(a)"), 1,
true);
663 iStat += EqnTest(
_T(
"sum(1,2,3)"), 6,
true);
664 iStat += EqnTest(
_T(
"sum(a,b,c)"), 6,
true);
665 iStat += EqnTest(
_T(
"sum(1,-max(1,2),3)*2"), 4,
true);
666 iStat += EqnTest(
_T(
"2*sum(1,2,3)"), 12,
true);
667 iStat += EqnTest(
_T(
"2*sum(1,2,3)+2"), 14,
true);
668 iStat += EqnTest(
_T(
"2*sum(-1,2,3)+2"), 10,
true);
669 iStat += EqnTest(
_T(
"2*sum(-1,2,-(-a))+2"), 6,
true);
670 iStat += EqnTest(
_T(
"2*sum(-1,10,-a)+2"), 18,
true);
671 iStat += EqnTest(
_T(
"2*sum(1,2,3)*2"), 24,
true);
672 iStat += EqnTest(
_T(
"sum(1,-max(1,2),3)*2"), 4,
true);
673 iStat += EqnTest(
_T(
"sum(1*3, 4, a+2)"), 10,
true);
674 iStat += EqnTest(
_T(
"sum(1*3, 2*sum(1,2,2), a+2)"), 16,
true);
675 iStat += EqnTest(
_T(
"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);
678 iStat += EqnTest(
_T(
"sum()"), 0,
false);
679 iStat += EqnTest(
_T(
"sum(,)"), 0,
false);
680 iStat += EqnTest(
_T(
"sum(1,2,)"), 0,
false);
681 iStat += EqnTest(
_T(
"sum(,1,2)"), 0,
false);
686 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
693 int ParserTester::TestInfixOprt()
698 iStat += EqnTest(
_T(
"+1"), +1,
true);
699 iStat += EqnTest(
_T(
"-(+1)"), -1,
true);
700 iStat += EqnTest(
_T(
"-(+1)*2"), -2,
true);
701 iStat += EqnTest(
_T(
"-(+2)*sqrt(4)"), -4,
true);
702 iStat += EqnTest(
_T(
"3-+a"), 2,
true);
703 iStat += EqnTest(
_T(
"+1*3"), 3,
true);
705 iStat += EqnTest(
_T(
"-1"), -1,
true);
706 iStat += EqnTest(
_T(
"-(-1)"), 1,
true);
707 iStat += EqnTest(
_T(
"-(-1)*2"), 2,
true);
708 iStat += EqnTest(
_T(
"-(-2)*sqrt(4)"), 4,
true);
710 iStat += EqnTest(
_T(
"-a"), -1,
true);
711 iStat += EqnTest(
_T(
"-(a)"), -1,
true);
712 iStat += EqnTest(
_T(
"-(-a)"), 1,
true);
713 iStat += EqnTest(
_T(
"-(-a)*2"), 2,
true);
714 iStat += EqnTest(
_T(
"-(8)"), -8,
true);
715 iStat += EqnTest(
_T(
"-8"), -8,
true);
716 iStat += EqnTest(
_T(
"-(2+1)"), -3,
true);
717 iStat += EqnTest(
_T(
"-(f1of1(1+2*3)+1*2)"), -9,
true);
718 iStat += EqnTest(
_T(
"-(-f1of1(1+2*3)+1*2)"), 5,
true);
719 iStat += EqnTest(
_T(
"-sin(8)"), -0.989358,
true);
720 iStat += EqnTest(
_T(
"3-(-a)"), 4,
true);
721 iStat += EqnTest(
_T(
"3--a"), 4,
true);
722 iStat += EqnTest(
_T(
"-1*3"), -3,
true);
725 iStat += EqnTest(
_T(
"~2#"), 8,
true);
726 iStat += EqnTest(
_T(
"~f1of1(2)#"), 8,
true);
727 iStat += EqnTest(
_T(
"~(b)#"), 8,
true);
728 iStat += EqnTest(
_T(
"(~b)#"), 12,
true);
729 iStat += EqnTest(
_T(
"~(2#)"), 8,
true);
730 iStat += EqnTest(
_T(
"~(f1of1(2)#)"), 8,
true);
732 iStat += EqnTest(
_T(
"-2^2"),-4,
true);
733 iStat += EqnTest(
_T(
"-(a+b)^2"),-9,
true);
734 iStat += EqnTest(
_T(
"(-3)^2"),9,
true);
735 iStat += EqnTest(
_T(
"-(-2^2)"),4,
true);
736 iStat += EqnTest(
_T(
"3+-3^2"),-6,
true);
739 iStat += EqnTest(
_T(
"-2'"), -4,
true);
740 iStat += EqnTest(
_T(
"-(1+1)'"),-4,
true);
741 iStat += EqnTest(
_T(
"2+-(1+1)'"),-2,
true);
742 iStat += EqnTest(
_T(
"2+-2'"), -2,
true);
745 iStat += EqnTest(
_T(
"$2^2"),4,
true);
746 iStat += EqnTest(
_T(
"$(a+b)^2"),9,
true);
747 iStat += EqnTest(
_T(
"($3)^2"),9,
true);
748 iStat += EqnTest(
_T(
"$($2^2)"),-4,
true);
749 iStat += EqnTest(
_T(
"3+$3^2"),12,
true);
752 iStat += EqnTest(
_T(
"~ 123"), 123+2,
true);
753 iStat += EqnTest(
_T(
"~~ 123"), 123+2,
true);
758 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
765 int ParserTester::TestPostFix()
771 iStat += EqnTest(
_T(
"3{m}+5"), 5.003,
true);
772 iStat += EqnTest(
_T(
"1000{m}"), 1,
true);
773 iStat += EqnTest(
_T(
"1000 {m}"), 1,
true);
774 iStat += EqnTest(
_T(
"(a){m}"), 1e-3,
true);
775 iStat += EqnTest(
_T(
"a{m}"), 1e-3,
true);
776 iStat += EqnTest(
_T(
"a {m}"), 1e-3,
true);
777 iStat += EqnTest(
_T(
"-(a){m}"), -1e-3,
true);
778 iStat += EqnTest(
_T(
"-2{m}"), -2e-3,
true);
779 iStat += EqnTest(
_T(
"-2 {m}"), -2e-3,
true);
780 iStat += EqnTest(
_T(
"f1of1(1000){m}"), 1,
true);
781 iStat += EqnTest(
_T(
"-f1of1(1000){m}"), -1,
true);
782 iStat += EqnTest(
_T(
"-f1of1(-1000){m}"), 1,
true);
783 iStat += EqnTest(
_T(
"f4of4(0,0,0,1000){m}"), 1,
true);
784 iStat += EqnTest(
_T(
"2+(a*1000){m}"), 3,
true);
787 iStat += EqnTest(
_T(
"2*3000meg+2"), 2*3e9+2,
true);
790 iStat += EqnTest(
_T(
"1000{m}"), 0.1,
false);
791 iStat += EqnTest(
_T(
"(a){m}"), 2,
false);
810 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
816 int ParserTester::TestExpression()
824 iStat += EqnTest(
_T(
"2*b*5"), 20,
true);
825 iStat += EqnTest(
_T(
"2*b*5 + 4*b"), 28,
true);
826 iStat += EqnTest(
_T(
"2*a/3"), 2.0/3.0,
true);
829 iStat += EqnTest(
_T(
"3+b"), b+3,
true);
830 iStat += EqnTest(
_T(
"b+3"), b+3,
true);
831 iStat += EqnTest(
_T(
"b*3+2"), b*3+2,
true);
832 iStat += EqnTest(
_T(
"3*b+2"), b*3+2,
true);
833 iStat += EqnTest(
_T(
"2+b*3"), b*3+2,
true);
834 iStat += EqnTest(
_T(
"2+3*b"), b*3+2,
true);
835 iStat += EqnTest(
_T(
"b+3*b"), b+3*b,
true);
836 iStat += EqnTest(
_T(
"3*b+b"), b+3*b,
true);
838 iStat += EqnTest(
_T(
"2+b*3+b"), 2+b*3+b,
true);
839 iStat += EqnTest(
_T(
"b+2+b*3"), b+2+b*3,
true);
841 iStat += EqnTest(
_T(
"(2*b+1)*4"), (2*b+1)*4,
true);
842 iStat += EqnTest(
_T(
"4*(2*b+1)"), (2*b+1)*4,
true);
845 iStat += EqnTest(
_T(
"1+2-3*4/5^6"), 2.99923,
true);
846 iStat += EqnTest(
_T(
"1^2/3*4-5+6"), 2.33333333,
true);
847 iStat += EqnTest(
_T(
"1+2*3"), 7,
true);
848 iStat += EqnTest(
_T(
"1+2*3"), 7,
true);
849 iStat += EqnTest(
_T(
"(1+2)*3"), 9,
true);
850 iStat += EqnTest(
_T(
"(1+2)*(-3)"), -9,
true);
851 iStat += EqnTest(
_T(
"2/4"), 0.5,
true);
853 iStat += EqnTest(
_T(
"exp(ln(7))"), 7,
true);
854 iStat += EqnTest(
_T(
"e^ln(7)"), 7,
true);
855 iStat += EqnTest(
_T(
"e^(ln(7))"), 7,
true);
856 iStat += EqnTest(
_T(
"(e^(ln(7)))"), 7,
true);
857 iStat += EqnTest(
_T(
"1-(e^(ln(7)))"), -6,
true);
858 iStat += EqnTest(
_T(
"2*(e^(ln(7)))"), 14,
true);
859 iStat += EqnTest(
_T(
"10^log(5)"), pow(10.0, log(5.0)),
true);
860 iStat += EqnTest(
_T(
"10^log10(5)"), 5,
true);
861 iStat += EqnTest(
_T(
"2^log2(4)"), 4,
true);
862 iStat += EqnTest(
_T(
"-(sin(0)+1)"), -1,
true);
863 iStat += EqnTest(
_T(
"-(2^1.1)"), -2.14354692,
true);
865 iStat += EqnTest(
_T(
"(cos(2.41)/b)"), -0.372056,
true);
866 iStat += EqnTest(
_T(
"(1*(2*(3*(4*(5*(6*(a+b)))))))"), 2160,
true);
867 iStat += EqnTest(
_T(
"(1*(2*(3*(4*(5*(6*(7*(a+b))))))))"), 15120,
true);
868 iStat += EqnTest(
_T(
"(a/((((b+(((e*(((((pi*((((3.45*((pi+a)+pi))+b)+b)*a))+0.68)+e)+a)/a))+a)+b))+b)*a)-pi))"), 0.00377999,
true);
872 _T(
"(((-9))-e/(((((((pi-(((-7)+(-3)/4/e))))/(((-5))-2)-((pi+(-0))*(sqrt((e+e))*(-8))*(((-pi)+(-pi)-(-9)*(6*5))")
873 _T(
"/(-e)-e))/2)/((((sqrt(2/(-e)+6)-(4-2))+((5/(-2))/(1*(-pi)+3))/8)*pi*((pi/((-2)/(-6)*1*(-1))*(-6)+(-e)))))/")
874 _T(
"((e+(-2)+(-e)*((((-3)*9+(-e)))+(-9)))))))-((((e-7+(((5/pi-(3/1+pi)))))/e)/(-5))/(sqrt((((((1+(-7))))+((((-")
875 _T(
"e)*(-e)))-8))*(-5)/((-e)))*(-6)-((((((-2)-(-9)-(-e)-1)/3))))/(sqrt((8+(e-((-6))+(9*(-9))))*(((3+2-8))*(7+6")
876 _T(
"+(-5))+((0/(-e)*(-pi))+7)))+(((((-e)/e/e)+((-6)*5)*e+(3+(-5)/pi))))+pi))/sqrt((((9))+((((pi))-8+2))+pi))/e")
877 _T(
"*4)*((-5)/(((-pi))*(sqrt(e)))))-(((((((-e)*(e)-pi))/4+(pi)*(-9)))))))+(-pi)"), -12.23016549,
true);
881 _T(
"(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")
882 _T(
")+a)))*2.77)"), -2.16995656,
true);
885 iStat += EqnTest(
_T(
"1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12"), -7995810.09926,
true);
890 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
898 int ParserTester::TestIfThenElse()
904 iStat += ThrowTest(
_T(
":3"), ecUNEXPECTED_CONDITIONAL);
905 iStat += ThrowTest(
_T(
"? 1 : 2"), ecUNEXPECTED_CONDITIONAL);
906 iStat += ThrowTest(
_T(
"(a<b) ? (b<c) ? 1 : 2"), ecMISSING_ELSE_CLAUSE);
907 iStat += ThrowTest(
_T(
"(a<b) ? 1"), ecMISSING_ELSE_CLAUSE);
908 iStat += ThrowTest(
_T(
"(a<b) ? a"), ecMISSING_ELSE_CLAUSE);
909 iStat += ThrowTest(
_T(
"(a<b) ? a+b"), ecMISSING_ELSE_CLAUSE);
910 iStat += ThrowTest(
_T(
"a : b"), ecMISPLACED_COLON);
911 iStat += ThrowTest(
_T(
"1 : 2"), ecMISPLACED_COLON);
912 iStat += ThrowTest(
_T(
"(1) ? 1 : 2 : 3"), ecMISPLACED_COLON);
915 iStat += EqnTest(
_T(
"1 ? 128 : 255"), 128,
true);
916 iStat += EqnTest(
_T(
"1<2 ? 128 : 255"), 128,
true);
917 iStat += EqnTest(
_T(
"a<b ? 128 : 255"), 128,
true);
918 iStat += EqnTest(
_T(
"(a<b) ? 128 : 255"), 128,
true);
919 iStat += EqnTest(
_T(
"(1) ? 10 : 11"), 10,
true);
920 iStat += EqnTest(
_T(
"(0) ? 10 : 11"), 11,
true);
921 iStat += EqnTest(
_T(
"(1) ? a+b : c+d"), 3,
true);
922 iStat += EqnTest(
_T(
"(0) ? a+b : c+d"), 1,
true);
923 iStat += EqnTest(
_T(
"(1) ? 0 : 1"), 0,
true);
924 iStat += EqnTest(
_T(
"(0) ? 0 : 1"), 1,
true);
925 iStat += EqnTest(
_T(
"(a<b) ? 10 : 11"), 10,
true);
926 iStat += EqnTest(
_T(
"(a>b) ? 10 : 11"), 11,
true);
927 iStat += EqnTest(
_T(
"(a<b) ? c : d"), 3,
true);
928 iStat += EqnTest(
_T(
"(a>b) ? c : d"), -2,
true);
930 iStat += EqnTest(
_T(
"(a>b) ? 1 : 0"), 0,
true);
931 iStat += EqnTest(
_T(
"((a>b) ? 1 : 0) ? 1 : 2"), 2,
true);
932 iStat += EqnTest(
_T(
"((a>b) ? 1 : 0) ? 1 : sum((a>b) ? 1 : 2)"), 2,
true);
933 iStat += EqnTest(
_T(
"((a>b) ? 0 : 1) ? 1 : sum((a>b) ? 1 : 2)"), 1,
true);
935 iStat += EqnTest(
_T(
"sum((a>b) ? 1 : 2)"), 2,
true);
936 iStat += EqnTest(
_T(
"sum((1) ? 1 : 2)"), 1,
true);
937 iStat += EqnTest(
_T(
"sum((a>b) ? 1 : 2, 100)"), 102,
true);
938 iStat += EqnTest(
_T(
"sum((1) ? 1 : 2, 100)"), 101,
true);
939 iStat += EqnTest(
_T(
"sum(3, (a>b) ? 3 : 10)"), 13,
true);
940 iStat += EqnTest(
_T(
"sum(3, (a<b) ? 3 : 10)"), 6,
true);
941 iStat += EqnTest(
_T(
"10*sum(3, (a>b) ? 3 : 10)"), 130,
true);
942 iStat += EqnTest(
_T(
"10*sum(3, (a<b) ? 3 : 10)"), 60,
true);
943 iStat += EqnTest(
_T(
"sum(3, (a>b) ? 3 : 10)*10"), 130,
true);
944 iStat += EqnTest(
_T(
"sum(3, (a<b) ? 3 : 10)*10"), 60,
true);
945 iStat += EqnTest(
_T(
"(a<b) ? sum(3, (a<b) ? 3 : 10)*10 : 99"), 60,
true);
946 iStat += EqnTest(
_T(
"(a>b) ? sum(3, (a<b) ? 3 : 10)*10 : 99"), 99,
true);
947 iStat += EqnTest(
_T(
"(a<b) ? sum(3, (a<b) ? 3 : 10,10,20)*10 : 99"), 360,
true);
948 iStat += EqnTest(
_T(
"(a>b) ? sum(3, (a<b) ? 3 : 10,10,20)*10 : 99"), 99,
true);
949 iStat += EqnTest(
_T(
"(a>b) ? sum(3, (a<b) ? 3 : 10,10,20)*10 : sum(3, (a<b) ? 3 : 10)*10"), 60,
true);
952 iStat += EqnTest(
_T(
"(a<b)&&(a<b) ? 128 : 255"), 128,
true);
953 iStat += EqnTest(
_T(
"(a>b)&&(a<b) ? 128 : 255"), 255,
true);
954 iStat += EqnTest(
_T(
"(1<2)&&(1<2) ? 128 : 255"), 128,
true);
955 iStat += EqnTest(
_T(
"(1>2)&&(1<2) ? 128 : 255"), 255,
true);
956 iStat += EqnTest(
_T(
"((1<2)&&(1<2)) ? 128 : 255"), 128,
true);
957 iStat += EqnTest(
_T(
"((1>2)&&(1<2)) ? 128 : 255"), 255,
true);
958 iStat += EqnTest(
_T(
"((a<b)&&(a<b)) ? 128 : 255"), 128,
true);
959 iStat += EqnTest(
_T(
"((a>b)&&(a<b)) ? 128 : 255"), 255,
true);
961 iStat += EqnTest(
_T(
"1>0 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64"), 255,
true);
962 iStat += EqnTest(
_T(
"1>0 ? 1>2 ? 128 : 255 :(1>0 ? 32 : 64)"), 255,
true);
963 iStat += EqnTest(
_T(
"1>0 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64"), 128,
true);
964 iStat += EqnTest(
_T(
"1>0 ? 1>0 ? 128 : 255 :(1>2 ? 32 : 64)"), 128,
true);
965 iStat += EqnTest(
_T(
"1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64"), 32,
true);
966 iStat += EqnTest(
_T(
"1>2 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64"), 64,
true);
967 iStat += EqnTest(
_T(
"1>0 ? 50 : 1>0 ? 128 : 255"), 50,
true);
968 iStat += EqnTest(
_T(
"1>0 ? 50 : (1>0 ? 128 : 255)"), 50,
true);
969 iStat += EqnTest(
_T(
"1>0 ? 1>0 ? 128 : 255 : 50"), 128,
true);
970 iStat += EqnTest(
_T(
"1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 1>2 ? 64 : 16"), 32,
true);
971 iStat += EqnTest(
_T(
"1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 :(1>2 ? 64 : 16)"), 32,
true);
972 iStat += EqnTest(
_T(
"1>0 ? 1>2 ? 128 : 255 : 1>0 ? 32 :1>2 ? 64 : 16"), 255,
true);
973 iStat += EqnTest(
_T(
"1>0 ? 1>2 ? 128 : 255 : (1>0 ? 32 :1>2 ? 64 : 16)"), 255,
true);
974 iStat += EqnTest(
_T(
"1 ? 0 ? 128 : 255 : 1 ? 32 : 64"), 255,
true);
977 iStat += EqnTest(
_T(
"a= 0 ? 128 : 255, a"), 255,
true);
978 iStat += EqnTest(
_T(
"a=((a>b)&&(a<b)) ? 128 : 255, a"), 255,
true);
979 iStat += EqnTest(
_T(
"c=(a<b)&&(a<b) ? 128 : 255, c"), 128,
true);
980 iStat += EqnTest(
_T(
"0 ? a=a+1 : 666, a"), 1,
true);
981 iStat += EqnTest(
_T(
"1?a=10:a=20, a"), 10,
true);
982 iStat += EqnTest(
_T(
"0?a=10:a=20, a"), 20,
true);
983 iStat += EqnTest(
_T(
"0?a=sum(3,4):10, a"), 1,
true);
985 iStat += EqnTest(
_T(
"a=1?b=1?3:4:5, a"), 3,
true);
986 iStat += EqnTest(
_T(
"a=1?b=1?3:4:5, b"), 3,
true);
987 iStat += EqnTest(
_T(
"a=0?b=1?3:4:5, a"), 5,
true);
988 iStat += EqnTest(
_T(
"a=0?b=1?3:4:5, b"), 2,
true);
990 iStat += EqnTest(
_T(
"a=1?5:b=1?3:4, a"), 5,
true);
991 iStat += EqnTest(
_T(
"a=1?5:b=1?3:4, b"), 2,
true);
992 iStat += EqnTest(
_T(
"a=0?5:b=1?3:4, a"), 3,
true);
993 iStat += EqnTest(
_T(
"a=0?5:b=1?3:4, b"), 3,
true);
998 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
1004 int ParserTester::TestException()
1022 #if defined(MUP_MATH_EXCEPTIONS)
1046 iStat += ThrowTest(
_T(
"valueof(\"xxx\")"), 999,
false);
1054 iStat += ThrowTest(
_T(
"valueof(\"\\\"abc\\\"\")"), 999,
false);
1092 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
1099 void ParserTester::AddTest(testfun_type a_pFun)
1101 m_vTestFun.push_back(a_pFun);
1105 void ParserTester::Run()
1110 for (
int i=0; i<(int)m_vTestFun.size(); ++i)
1111 iStat += (this->*m_vTestFun[i])();
1119 catch(std::exception &e)
1132 mu::console() <<
"Test passed (" << ParserTester::c_iCount <<
" expressions)" << endl;
1137 <<
" errors (" << ParserTester::c_iCount
1138 <<
" expressions)" << endl;
1140 ParserTester::c_iCount = 0;
1145 int ParserTester::ThrowTest(
const string_type &a_str,
int a_iErrc,
bool a_bFail)
1147 ParserTester::c_iCount++;
1170 if (a_bFail==
false || (a_bFail==
true && a_iErrc!=e.
GetCode()) )
1173 <<
_T(
"Expression: ") << a_str
1175 <<
_T(
" Expected:") << a_iErrc;
1178 return (a_iErrc==e.
GetCode()) ? 0 : 1;
1182 bool bRet((a_bFail==
false) ? 0 : 1);
1186 <<
_T(
"Expression: ") << a_str
1187 <<
_T(
" did evaluate; Expected error:") << a_iErrc;
1198 int ParserTester::EqnTestWithVarChange(
const string_type &a_str,
1204 ParserTester::c_iCount++;
1223 if ( fabs(a_fRes1-fVal[0]) > 0.0000000001)
1224 throw std::runtime_error(
"incorrect result (first pass)");
1226 if ( fabs(a_fRes2-fVal[1]) > 0.0000000001)
1227 throw std::runtime_error(
"incorrect result (second pass)");
1234 catch(std::exception &e)
1236 mu::console() <<
_T(
"\n fail: ") << a_str.c_str() <<
_T(
" (") << e.what() <<
_T(
")");
1241 mu::console() <<
_T(
"\n fail: ") << a_str.c_str() <<
_T(
" (unexpected exception)");
1253 int ParserTester::EqnTest(
const string_type &a_str,
double a_fRes,
bool a_fPass)
1255 ParserTester::c_iCount++;
1257 value_type fVal[5] = {-999, -998, -997, -996, -995};
1261 std::auto_ptr<Parser> p1;
1272 p1->DefineConst(
_T(
"const"), 1);
1273 p1->DefineConst(
_T(
"const1"), 2);
1274 p1->DefineConst(
_T(
"const2"), 3);
1276 p1->DefineStrConst(
_T(
"str1"),
_T(
"1.11"));
1277 p1->DefineStrConst(
_T(
"str2"),
_T(
"2.22"));
1280 p1->DefineVar(
_T(
"a"), &vVarVal[0]);
1281 p1->DefineVar(
_T(
"aa"), &vVarVal[1]);
1282 p1->DefineVar(
_T(
"b"), &vVarVal[1]);
1283 p1->DefineVar(
_T(
"c"), &vVarVal[2]);
1284 p1->DefineVar(
_T(
"d"), &vVarVal[3]);
1287 p1->AddValIdent(&ParserTester::IsHexVal);
1290 p1->DefineFun(
_T(
"ping"), Ping);
1291 p1->DefineFun(
_T(
"f1of1"), f1of1);
1292 p1->DefineFun(
_T(
"f1of2"), f1of2);
1293 p1->DefineFun(
_T(
"f2of2"), f2of2);
1294 p1->DefineFun(
_T(
"f1of3"), f1of3);
1295 p1->DefineFun(
_T(
"f2of3"), f2of3);
1296 p1->DefineFun(
_T(
"f3of3"), f3of3);
1297 p1->DefineFun(
_T(
"f1of4"), f1of4);
1298 p1->DefineFun(
_T(
"f2of4"), f2of4);
1299 p1->DefineFun(
_T(
"f3of4"), f3of4);
1300 p1->DefineFun(
_T(
"f4of4"), f4of4);
1301 p1->DefineFun(
_T(
"f1of5"), f1of5);
1302 p1->DefineFun(
_T(
"f2of5"), f2of5);
1303 p1->DefineFun(
_T(
"f3of5"), f3of5);
1304 p1->DefineFun(
_T(
"f4of5"), f4of5);
1305 p1->DefineFun(
_T(
"f5of5"), f5of5);
1308 p1->DefineOprt(
_T(
"add"), add, 0);
1309 p1->DefineOprt(
_T(
"++"), add, 0);
1310 p1->DefineOprt(
_T(
"&"), land, prLAND);
1313 p1->DefineFun(
_T(
"min"), Min);
1314 p1->DefineFun(
_T(
"max"), Max);
1315 p1->DefineFun(
_T(
"sum"), Sum);
1316 p1->DefineFun(
_T(
"valueof"), ValueOf);
1317 p1->DefineFun(
_T(
"atof"), StrToFloat);
1318 p1->DefineFun(
_T(
"strfun1"), StrFun1);
1319 p1->DefineFun(
_T(
"strfun2"), StrFun2);
1320 p1->DefineFun(
_T(
"strfun3"), StrFun3);
1321 p1->DefineFun(
_T(
"lastArg"), LastArg);
1322 p1->DefineFun(
_T(
"firstArg"), FirstArg);
1323 p1->DefineFun(
_T(
"order"), FirstArg);
1328 p1->DefineInfixOprt(
_T(
"$"), sign,
prPOW+1);
1329 p1->DefineInfixOprt(
_T(
"~"), plus2);
1330 p1->DefineInfixOprt(
_T(
"~~"), plus2);
1331 p1->DefinePostfixOprt(
_T(
"{m}"), Milli);
1332 p1->DefinePostfixOprt(
_T(
"{M}"), Mega);
1333 p1->DefinePostfixOprt(
_T(
"m"), Milli);
1334 p1->DefinePostfixOprt(
_T(
"meg"), Mega);
1335 p1->DefinePostfixOprt(
_T(
"#"), times3);
1336 p1->DefinePostfixOprt(
_T(
"'"), sqr);
1341 fVal[0] = p1->Eval();
1342 fVal[1] = p1->Eval();
1343 if (fVal[0]!=fVal[1])
1350 std::vector<mu::Parser> vParser;
1351 vParser.push_back(*(p1.get()));
1358 fVal[2] = p2.
Eval();
1365 fVal[3] = p3.
Eval();
1371 fVal[4] = v[nNum-1];
1373 catch(std::exception &e)
1379 bool bCloseEnough(
true);
1380 for (
unsigned i=0; i<
sizeof(fVal)/
sizeof(
value_type); ++i)
1382 bCloseEnough &= (fabs(a_fRes-fVal[i]) <= fabs(fVal[i]*0.00001));
1387 #pragma warning(push)
1388 #pragma warning(disable:4127)
1389 if (std::numeric_limits<value_type>::has_infinity)
1390 #pragma warning(pop)
1392 bCloseEnough &= (fabs(fVal[i]) != numeric_limits<value_type>::infinity());
1396 iRet = ((bCloseEnough && a_fPass) || (!bCloseEnough && !a_fPass)) ? 0 : 1;
1402 <<
_T(
" (incorrect result; expected: ") << a_fRes
1403 <<
_T(
" ;calculated: ") << fVal[0] <<
_T(
",")
1404 << fVal[1] <<
_T(
",")
1405 << fVal[2] <<
_T(
",")
1406 << fVal[3] <<
_T(
",")
1407 << fVal[4] <<
_T(
").");
1414 if (fVal[0]!=fVal[2] && fVal[0]!=-999 && fVal[1]!=-998)
1415 mu::console() <<
_T(
"\n fail: ") << a_str.c_str() <<
_T(
" (copy construction)");
1421 catch(std::exception &e)
1423 mu::console() <<
_T(
"\n fail: ") << a_str.c_str() <<
_T(
" (") << e.what() <<
_T(
")");
1428 mu::console() <<
_T(
"\n fail: ") << a_str.c_str() <<
_T(
" (unexpected exception)");
1436 int ParserTester::EqnTestInt(
const string_type &a_str,
double a_fRes,
bool a_fPass)
1438 ParserTester::c_iCount++;
1457 if (fVal[0]!=fVal[1])
1460 iRet = ( (a_fRes==fVal[0] && a_fPass) ||
1461 (a_fRes!=fVal[0] && !a_fPass) ) ? 0 : 1;
1465 <<
_T(
" (incorrect result; expected: ") << a_fRes
1466 <<
_T(
" ;calculated: ") << fVal[0]<<
_T(
").");
1479 mu::console() <<
_T(
"\n fail: ") << a_str.c_str() <<
_T(
" (unexpected exception)");
1488 int ParserTester::EqnTestBulk(
const string_type &a_str,
double a_fRes[4],
bool a_fPass)
1490 ParserTester::c_iCount++;
1510 p.
Eval(vResults, nBulkSize);
1512 bool bCloseEnough(
true);
1513 for (
int i = 0; i < nBulkSize; ++i)
1515 bCloseEnough &= (fabs(a_fRes[i] - vResults[i]) <= fabs(a_fRes[i] * 0.00001));
1518 iRet = ((bCloseEnough && a_fPass) || (!bCloseEnough && !a_fPass)) ? 0 : 1;
1522 <<
_T(
" (incorrect result; expected: {") << a_fRes[0] <<
_T(
",") << a_fRes[1] <<
_T(
",") << a_fRes[2] <<
_T(
",") << a_fRes[3] <<
_T(
"}")
1523 <<
_T(
" ;calculated: ") << vResults[0] <<
_T(
",") << vResults[1] <<
_T(
",") << vResults[2] <<
_T(
",") << vResults[3] <<
_T(
"}");
1536 mu::console() <<
_T(
"\n fail: ") << a_str.c_str() <<
_T(
" (unexpected exception)");
1545 void ParserTester::Abort()
const
1547 mu::console() <<
_T(
"Test failed (internal error in test class)") << endl;
void DefinePostfixOprt(const string_type &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true)
Add a user defined operator.
#define _T(x)
Activate this option in order to compile with OpenMP support.
const string_type & GetExpr() const
gets the expression related tp this error.
binary operators may only be applied to value items of the same type
void DefineVar(const string_type &a_sName, value_type *a_fVar)
Add a user defined variable.
std::ostream & console()
Encapsulate cout.
Token cant be identified.
Division by zero (currently unused)
std::map< string_type, value_type * > varmap_type
Type used for storing variables.
unterminated string constant. (Example: "3*valueof("hello)")
#define PARSER_CONST_PI
Pi (what else?).
void ClearConst()
Clear all user defined constants.
Unexpected function found. (Example: "sin(8)cos(9)")
power operator priority (highest)
value_type Eval() const
Calculate the result.
std::basic_stringstream< char_type, std::char_traits< char_type >, std::allocator< char_type > > stringstream_type
Typedef for easily using stringstream that respect the parser stringtype.
void EnableOptimizer(bool a_bIsOn=true)
Enable or disable the formula optimization feature.
An unexpected value token has been found.
void ClearPostfixOprt()
Clear all user defined postfix operators.
catch division by zero, sqrt(-1), log(0) (currently unused)
void DefineFun(const string_type &a_strName, T a_pFun, bool a_bAllowOpt=true)
Define a parser function without arguments.
Error class of the parser.
const varmap_type & GetVar() const
Return a map containing the used variables only.
MUP_BASETYPE value_type
The numeric datatype used by the parser.
void SetExpr(const string_type &a_sExpr)
Set the formula.
Mathematical expressions parser.
Too many function parameters.
A numerical function has been called with a non value type of argument.
Namespace for mathematical applications.
Unexpected end of formula. (Example: "2+sin(")
Too few function parameters. (Example: "ite(1<2,2)")
A string function has been called with a different type of argument.
EErrorCodes GetCode() const
Return the error code.
void RemoveVar(const string_type &a_strVarName)
Remove a variable from internal storage.
string_type::value_type char_type
The character type used by the parser.
Mathematical expressions parser.
void DefineConst(const string_type &a_sName, value_type a_fVal)
Add a user defined constant.
void EnableBuiltInOprt(bool a_bIsOn=true)
Enable or disable the built in binary operators.
This file contains the parser test class.
Unexpected binary operator found.
MUP_STRING_TYPE string_type
The stringtype used by the parser.
Unexpected Parenthesis, opening or closing.
#define PARSER_CONST_E
The Eulerian number.
const string_type & GetToken() const
Return string related with this token (if available).
Missing parens. (Example: "3*sin(3")
const string_type & GetMsg() const
Returns the message string for this error.
const varmap_type & GetUsedVar() const
Return a map containing the used variables only.