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()
141 iStat += ThrowTest(
_T(R
"(6 - 6 ? 4 : "", ? 4 : "", ? 4 : "")"), ecUNEXPECTED_STR, true);
148 iStat += ThrowTest(
_T(R
"("","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",8)"), ecSTR_RESULT);
152 iStat += EqnTest(_T("valueof(\"\")"), 123,
true);
153 iStat += EqnTest(
_T(
"valueof(\"aaa\")+valueof(\"bbb\") "), 246,
true);
154 iStat += EqnTest(
_T(
"2*(valueof(\"aaa\")-23)+valueof(\"bbb\")"), 323,
true);
157 iStat += EqnTest(
_T(
"a*(atof(\"10\")-b)"), 8,
true);
158 iStat += EqnTest(
_T(
"a-(atof(\"10\")*b)"), -19,
true);
161 iStat += EqnTest(
_T(
"strfun1(\"100\")"), 100,
true);
162 iStat += EqnTest(
_T(
"strfun2(\"100\",1)"), 101,
true);
163 iStat += EqnTest(
_T(
"strfun3(\"99\",1,2)"), 102,
true);
164 iStat += EqnTest(
_T(
"strfun4(\"99\",1,2,3)"), 105,
true);
165 iStat += EqnTest(
_T(
"strfun5(\"99\",1,2,3,4)"), 109,
true);
168 iStat += EqnTest(
_T(
"atof(str1)+atof(str2)"), 3.33,
true);
173 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
179 int ParserTester::TestBulkMode()
184 #define EQN_TEST_BULK(EXPR, R1, R2, R3, R4, PASS) \
186 double res[] = { R1, R2, R3, R4 }; \
187 iStat += EqnTestBulk(_T(EXPR), res, (PASS)); \
195 EQN_TEST_BULK(
"a", 1, 1, 1, 1,
false)
196 EQN_TEST_BULK(
"a", 1, 2, 3, 4,
true)
197 EQN_TEST_BULK(
"b=a", 1, 2, 3, 4,
true)
198 EQN_TEST_BULK(
"b=a, b*10", 10, 20, 30, 40,
true)
199 EQN_TEST_BULK(
"b=a, b*10, a", 1, 2, 3, 4,
true)
200 EQN_TEST_BULK(
"a+b", 3, 4, 5, 6,
true)
201 EQN_TEST_BULK(
"c*(a+b)", 9, 12, 15, 18,
true)
207 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
213 int ParserTester::TestBinOprt()
221 iStat += EqnTest(
_T(
"a++b"), 3,
true);
222 iStat += EqnTest(
_T(
"a ++ b"), 3,
true);
223 iStat += EqnTest(
_T(
"1++2"), 3,
true);
224 iStat += EqnTest(
_T(
"1 ++ 2"), 3,
true);
225 iStat += EqnTest(
_T(
"a add b"), 3,
true);
226 iStat += EqnTest(
_T(
"1 add 2"), 3,
true);
227 iStat += EqnTest(
_T(
"a<b"), 1,
true);
228 iStat += EqnTest(
_T(
"b>a"), 1,
true);
229 iStat += EqnTest(
_T(
"a>a"), 0,
true);
230 iStat += EqnTest(
_T(
"a<a"), 0,
true);
231 iStat += EqnTest(
_T(
"a>a"), 0,
true);
232 iStat += EqnTest(
_T(
"a<=a"), 1,
true);
233 iStat += EqnTest(
_T(
"a<=b"), 1,
true);
234 iStat += EqnTest(
_T(
"b<=a"), 0,
true);
235 iStat += EqnTest(
_T(
"a>=a"), 1,
true);
236 iStat += EqnTest(
_T(
"b>=a"), 1,
true);
237 iStat += EqnTest(
_T(
"a>=b"), 0,
true);
240 iStat += EqnTest(
_T(
"1 && 1"), 1,
true);
241 iStat += EqnTest(
_T(
"1 && 0"), 0,
true);
242 iStat += EqnTest(
_T(
"(a<b) && (b>a)"), 1,
true);
243 iStat += EqnTest(
_T(
"(a<b) && (a>b)"), 0,
true);
246 iStat += EqnTest(
_T(
"12 & 255"), 12,
true);
247 iStat += EqnTest(
_T(
"12 & 0"), 0,
true);
248 iStat += EqnTest(
_T(
"12&255"), 12,
true);
249 iStat += EqnTest(
_T(
"12&0"), 0,
true);
252 iStat += EqnTest(
_T(
"a = b"), 2,
true);
253 iStat += EqnTest(
_T(
"a = sin(b)"), 0.909297,
true);
254 iStat += EqnTest(
_T(
"a = 1+sin(b)"), 1.909297,
true);
255 iStat += EqnTest(
_T(
"(a=b)*2"), 4,
true);
256 iStat += EqnTest(
_T(
"2*(a=b)"), 4,
true);
257 iStat += EqnTest(
_T(
"2*(a=b+1)"), 6,
true);
258 iStat += EqnTest(
_T(
"(a=b+1)*2"), 6,
true);
259 iStat += EqnTest(
_T(
"a=c, a*10"), 30,
true);
261 iStat += EqnTest(
_T(
"2^2^3"), 256,
true);
262 iStat += EqnTest(
_T(
"1/2/3"), 1.0 / 6.0,
true);
265 iStat += EqnTest(
_T(
"3+4*2/(1-5)^2^3"), 3.0001220703125,
true);
268 iStat += EqnTestInt(
_T(
"1 | 2"), 3,
true);
269 iStat += EqnTestInt(
_T(
"1 || 2"), 1,
true);
270 iStat += EqnTestInt(
_T(
"123 & 456"), 72,
true);
271 iStat += EqnTestInt(
_T(
"(123 & 456) % 10"), 2,
true);
272 iStat += EqnTestInt(
_T(
"1 && 0"), 0,
true);
273 iStat += EqnTestInt(
_T(
"123 && 456"), 1,
true);
274 iStat += EqnTestInt(
_T(
"1 << 3"), 8,
true);
275 iStat += EqnTestInt(
_T(
"8 >> 3"), 1,
true);
276 iStat += EqnTestInt(
_T(
"9 / 4"), 2,
true);
277 iStat += EqnTestInt(
_T(
"9 % 4"), 1,
true);
278 iStat += EqnTestInt(
_T(
"if(5%2,1,0)"), 1,
true);
279 iStat += EqnTestInt(
_T(
"if(4%2,1,0)"), 0,
true);
280 iStat += EqnTestInt(
_T(
"-10+1"), -9,
true);
281 iStat += EqnTestInt(
_T(
"1+2*3"), 7,
true);
282 iStat += EqnTestInt(
_T(
"const1 != const2"), 1,
true);
283 iStat += EqnTestInt(
_T(
"const1 != const2"), 0,
false);
284 iStat += EqnTestInt(
_T(
"const1 == const2"), 0,
true);
285 iStat += EqnTestInt(
_T(
"const1 == 1"), 1,
true);
286 iStat += EqnTestInt(
_T(
"10*(const1 == 1)"), 10,
true);
287 iStat += EqnTestInt(
_T(
"2*(const1 | const2)"), 6,
true);
288 iStat += EqnTestInt(
_T(
"2*(const1 | const2)"), 7,
false);
289 iStat += EqnTestInt(
_T(
"const1 < const2"), 1,
true);
290 iStat += EqnTestInt(
_T(
"const2 > const1"), 1,
true);
291 iStat += EqnTestInt(
_T(
"const1 <= 1"), 1,
true);
292 iStat += EqnTestInt(
_T(
"const2 >= 2"), 1,
true);
293 iStat += EqnTestInt(
_T(
"2*(const1 + const2)"), 6,
true);
294 iStat += EqnTestInt(
_T(
"2*(const1 - const2)"), -2,
true);
295 iStat += EqnTestInt(
_T(
"a != b"), 1,
true);
296 iStat += EqnTestInt(
_T(
"a != b"), 0,
false);
297 iStat += EqnTestInt(
_T(
"a == b"), 0,
true);
298 iStat += EqnTestInt(
_T(
"a == 1"), 1,
true);
299 iStat += EqnTestInt(
_T(
"10*(a == 1)"), 10,
true);
300 iStat += EqnTestInt(
_T(
"2*(a | b)"), 6,
true);
301 iStat += EqnTestInt(
_T(
"2*(a | b)"), 7,
false);
302 iStat += EqnTestInt(
_T(
"a < b"), 1,
true);
303 iStat += EqnTestInt(
_T(
"b > a"), 1,
true);
304 iStat += EqnTestInt(
_T(
"a <= 1"), 1,
true);
305 iStat += EqnTestInt(
_T(
"b >= 2"), 1,
true);
306 iStat += EqnTestInt(
_T(
"2*(a + b)"), 6,
true);
307 iStat += EqnTestInt(
_T(
"2*(a - b)"), -2,
true);
308 iStat += EqnTestInt(
_T(
"a + (a << b)"), 5,
true);
309 iStat += EqnTestInt(
_T(
"-2^2"), -4,
true);
310 iStat += EqnTestInt(
_T(
"3--a"), 4,
true);
311 iStat += EqnTestInt(
_T(
"3+-3^2"), -6,
true);
314 iStat += EqnTestInt(
_T(
"0xff"), 255,
true);
315 iStat += EqnTestInt(
_T(
"10+0xff"), 265,
true);
316 iStat += EqnTestInt(
_T(
"0xff+10"), 265,
true);
317 iStat += EqnTestInt(
_T(
"10*0xff"), 2550,
true);
318 iStat += EqnTestInt(
_T(
"0xff*10"), 2550,
true);
319 iStat += EqnTestInt(
_T(
"10+0xff+1"), 266,
true);
320 iStat += EqnTestInt(
_T(
"1+0xff+10"), 266,
true);
328 iStat += EqnTestInt(
_T(
"a + b * c"), 7,
true);
329 iStat += EqnTestInt(
_T(
"a * b + c"), 5,
true);
330 iStat += EqnTestInt(
_T(
"a<b && b>10"), 0,
true);
331 iStat += EqnTestInt(
_T(
"a<b && b<10"), 1,
true);
333 iStat += EqnTestInt(
_T(
"a + b << c"), 17,
true);
334 iStat += EqnTestInt(
_T(
"a << b + c"), 7,
true);
335 iStat += EqnTestInt(
_T(
"c * b < a"), 0,
true);
336 iStat += EqnTestInt(
_T(
"c * b == 6 * a"), 1,
true);
337 iStat += EqnTestInt(
_T(
"2^2^3"), 256,
true);
343 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
350 int ParserTester::TestNames()
355 mu::console() <<
"testing name restriction enforcement...";
359 #define PARSER_THROWCHECK(DOMAIN, FAIL, EXPR, ARG) \
361 ParserTester::c_iCount++; \
364 p.Define##DOMAIN(EXPR, ARG); \
365 iErr = (FAIL) ? 0 : 1; \
369 iErr = (!FAIL) ? 0 : 1; \
374 PARSER_THROWCHECK(Const,
false,
_T(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), 1)
375 PARSER_THROWCHECK(Const,
false,
_T(
"0a"), 1)
376 PARSER_THROWCHECK(Const,
false,
_T(
"9a"), 1)
377 PARSER_THROWCHECK(Const,
false,
_T(
"+a"), 1)
378 PARSER_THROWCHECK(Const,
false,
_T(
"-a"), 1)
379 PARSER_THROWCHECK(Const,
false,
_T(
"a-"), 1)
380 PARSER_THROWCHECK(Const,
false,
_T(
"a*"), 1)
381 PARSER_THROWCHECK(Const,
false,
_T(
"a?"), 1)
382 PARSER_THROWCHECK(Const,
true,
_T(
"a"), 1)
383 PARSER_THROWCHECK(Const,
true,
_T(
"a_min"), 1)
384 PARSER_THROWCHECK(Const,
true,
_T(
"a_min0"), 1)
385 PARSER_THROWCHECK(Const,
true,
_T(
"a_min9"), 1)
390 PARSER_THROWCHECK(Var,
false,
_T(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), &a);
391 PARSER_THROWCHECK(Var,
false,
_T(
"123abc"), &a)
392 PARSER_THROWCHECK(Var,
false,
_T(
"9a"), &a)
393 PARSER_THROWCHECK(Var,
false,
_T(
"0a"), &a)
394 PARSER_THROWCHECK(Var,
false,
_T(
"+a"), &a)
395 PARSER_THROWCHECK(Var,
false,
_T(
"-a"), &a)
396 PARSER_THROWCHECK(Var,
false,
_T(
"?a"), &a)
397 PARSER_THROWCHECK(Var,
false,
_T(
"!a"), &a)
398 PARSER_THROWCHECK(Var,
false,
_T(
"a+"), &a)
399 PARSER_THROWCHECK(Var,
false,
_T(
"a-"), &a)
400 PARSER_THROWCHECK(Var,
false,
_T(
"a*"), &a)
401 PARSER_THROWCHECK(Var,
false,
_T(
"a?"), &a)
402 PARSER_THROWCHECK(Var,
true,
_T(
"a"), &a)
403 PARSER_THROWCHECK(Var,
true,
_T(
"a_min"), &a)
404 PARSER_THROWCHECK(Var,
true,
_T(
"a_min0"), &a)
405 PARSER_THROWCHECK(Var,
true,
_T(
"a_min9"), &a)
406 PARSER_THROWCHECK(Var,
false,
_T(
"a_min9"), 0)
410 PARSER_THROWCHECK(PostfixOprt,
false,
_T(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), f1of1);
411 PARSER_THROWCHECK(PostfixOprt,
false,
_T(
"(k"), f1of1)
412 PARSER_THROWCHECK(PostfixOprt,
false,
_T(
"9+"), f1of1)
413 PARSER_THROWCHECK(PostfixOprt,
false,
_T(
"+"), 0)
415 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"-a"), f1of1)
416 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"?a"), f1of1)
417 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"_"), f1of1)
418 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"#"), f1of1)
419 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"&&"), f1of1)
420 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"||"), f1of1)
421 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"&"), f1of1)
422 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"|"), f1of1)
423 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"++"), f1of1)
424 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"--"), f1of1)
425 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"?>"), f1of1)
426 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"?<"), f1of1)
427 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"**"), f1of1)
428 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"xor"), f1of1)
429 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"and"), f1of1)
430 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"or"), f1of1)
431 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"not"), f1of1)
432 PARSER_THROWCHECK(PostfixOprt,
true,
_T(
"!"), f1of1)
438 PARSER_THROWCHECK(Oprt,
false,
_T(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), f1of2);
439 PARSER_THROWCHECK(Oprt,
false,
_T(
"+"), f1of2)
440 PARSER_THROWCHECK(Oprt,
false,
_T(
"-"), f1of2)
441 PARSER_THROWCHECK(Oprt,
false,
_T(
"*"), f1of2)
442 PARSER_THROWCHECK(Oprt,
false,
_T(
"/"), f1of2)
443 PARSER_THROWCHECK(Oprt,
false,
_T(
"^"), f1of2)
444 PARSER_THROWCHECK(Oprt,
false,
_T(
"&&"), f1of2)
445 PARSER_THROWCHECK(Oprt,
false,
_T(
"||"), f1of2)
449 PARSER_THROWCHECK(Oprt,
true,
_T(
"+"), f1of2)
450 PARSER_THROWCHECK(Oprt,
true,
_T(
"-"), f1of2)
451 PARSER_THROWCHECK(Oprt,
true,
_T(
"*"), f1of2)
452 PARSER_THROWCHECK(Oprt,
true,
_T(
"/"), f1of2)
453 PARSER_THROWCHECK(Oprt,
true,
_T(
"^"), f1of2)
454 PARSER_THROWCHECK(Oprt,
true,
_T(
"&&"), f1of2)
455 PARSER_THROWCHECK(Oprt,
true,
_T(
"||"), f1of2)
456 #undef PARSER_THROWCHECK
461 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
467 int ParserTester::TestSyntax()
478 iStat += EqnTest(
_T(
"(1+ 2*a)"), 3,
true);
479 iStat += EqnTest(
_T(
"sqrt((4))"), 2,
true);
480 iStat += EqnTest(
_T(
"sqrt((2)+2)"), 2,
true);
481 iStat += EqnTest(
_T(
"sqrt(2+(2))"), 2,
true);
482 iStat += EqnTest(
_T(
"sqrt(a+(3))"), 2,
true);
483 iStat += EqnTest(
_T(
"sqrt((3)+a)"), 2,
true);
484 iStat += EqnTest(
_T(
"order(1,2)"), 1,
true);
485 iStat += EqnTest(
_T(
"(2+"), 0,
false);
486 iStat += EqnTest(
_T(
"2++4"), 0,
false);
487 iStat += EqnTest(
_T(
"2+-4"), 0,
false);
488 iStat += EqnTest(
_T(
"(2+)"), 0,
false);
489 iStat += EqnTest(
_T(
"--2"), 0,
false);
490 iStat += EqnTest(
_T(
"ksdfj"), 0,
false);
491 iStat += EqnTest(
_T(
"()"), 0,
false);
492 iStat += EqnTest(
_T(
"5+()"), 0,
false);
493 iStat += EqnTest(
_T(
"sin(cos)"), 0,
false);
494 iStat += EqnTest(
_T(
"5t6"), 0,
false);
495 iStat += EqnTest(
_T(
"5 t 6"), 0,
false);
496 iStat += EqnTest(
_T(
"8*"), 0,
false);
497 iStat += EqnTest(
_T(
",3"), 0,
false);
498 iStat += EqnTest(
_T(
"3,5"), 0,
false);
499 iStat += EqnTest(
_T(
"sin(8,8)"), 0,
false);
500 iStat += EqnTest(
_T(
"(7,8)"), 0,
false);
501 iStat += EqnTest(
_T(
"sin)"), 0,
false);
502 iStat += EqnTest(
_T(
"a)"), 0,
false);
503 iStat += EqnTest(
_T(
"pi)"), 0,
false);
504 iStat += EqnTest(
_T(
"sin(())"), 0,
false);
505 iStat += EqnTest(
_T(
"sin()"), 0,
false);
510 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
516 int ParserTester::TestVarConst()
519 mu::console() <<
_T(
"testing variable/constant detection...");
522 iStat += EqnTestWithVarChange(
_T(
"a"), 1, 1, 2, 2);
523 iStat += EqnTestWithVarChange(
_T(
"2*a"), 2, 4, 3, 6);
526 iStat += EqnTest(
_T(
"const"), 1,
true);
527 iStat += EqnTest(
_T(
"const1"), 2,
true);
528 iStat += EqnTest(
_T(
"const2"), 3,
true);
529 iStat += EqnTest(
_T(
"2*const"), 2,
true);
530 iStat += EqnTest(
_T(
"2*const1"), 4,
true);
531 iStat += EqnTest(
_T(
"2*const2"), 6,
true);
532 iStat += EqnTest(
_T(
"2*const+1"), 3,
true);
533 iStat += EqnTest(
_T(
"2*const1+1"), 5,
true);
534 iStat += EqnTest(
_T(
"2*const2+1"), 7,
true);
535 iStat += EqnTest(
_T(
"const"), 0,
false);
536 iStat += EqnTest(
_T(
"const1"), 0,
false);
537 iStat += EqnTest(
_T(
"const2"), 0,
false);
540 iStat += EqnTest(
_T(
"a"), 1,
true);
541 iStat += EqnTest(
_T(
"aa"), 2,
true);
542 iStat += EqnTest(
_T(
"2*a"), 2,
true);
543 iStat += EqnTest(
_T(
"2*aa"), 4,
true);
544 iStat += EqnTest(
_T(
"2*a-1"), 1,
true);
545 iStat += EqnTest(
_T(
"2*aa-1"), 3,
true);
548 iStat += EqnTest(
_T(
"0xff"), 255,
true);
549 iStat += EqnTest(
_T(
"0x97 + 0xff"), 406,
true);
567 int iCount = (int)UsedVar.size();
573 if (p.
GetVar().size() != 5)
576 mu::varmap_type::const_iterator item = UsedVar.begin();
577 for (idx = 0; item != UsedVar.end(); ++item)
579 if (&vVarVal[idx++] != item->second)
586 iCount = (int)UsedVar.size();
592 if (p.
GetVar().size() != 5)
595 for (item = UsedVar.begin(); item != UsedVar.end(); ++item)
597 if (item->second != 0)
604 iCount = (int)UsedVar.size();
605 if (iCount != 2)
throw false;
606 item = UsedVar.begin();
607 for (idx = 0; item != UsedVar.end(); ++item)
608 if (&vVarVal[idx++] != item->second)
throw false;
619 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
625 int ParserTester::TestMultiArg()
631 iStat += ThrowTest(
_T(
"6, +, +, +, +, +, +, +, +, +, +, +, +, +, +, 1, +, +, +, +, +, +, +, +, +, +, +, +, +, +, +, +, +, +, +, +, +, +, +, +, +, +, +, +, +, +, +, +"),
ecUNEXPECTED_ARG_SEP,
true);
634 iStat += EqnTest(
_T(
"1,2,3"), 3,
true);
635 iStat += EqnTest(
_T(
"a,b,c"), 3,
true);
636 iStat += EqnTest(
_T(
"a=10,b=20,c=a*b"), 200,
true);
637 iStat += EqnTest(
_T(
"1,\n2,\n3"), 3,
true);
638 iStat += EqnTest(
_T(
"a,\nb,\nc"), 3,
true);
639 iStat += EqnTest(
_T(
"a=10,\nb=20,\nc=a*b"), 200,
true);
640 iStat += EqnTest(
_T(
"1,\r\n2,\r\n3"), 3,
true);
641 iStat += EqnTest(
_T(
"a,\r\nb,\r\nc"), 3,
true);
642 iStat += EqnTest(
_T(
"a=10,\r\nb=20,\r\nc=a*b"), 200,
true);
645 iStat += EqnTest(
_T(
"f1of1(1)"), 1,
true);
646 iStat += EqnTest(
_T(
"f1of2(1, 2)"), 1,
true);
647 iStat += EqnTest(
_T(
"f2of2(1, 2)"), 2,
true);
648 iStat += EqnTest(
_T(
"f1of3(1, 2, 3)"), 1,
true);
649 iStat += EqnTest(
_T(
"f2of3(1, 2, 3)"), 2,
true);
650 iStat += EqnTest(
_T(
"f3of3(1, 2, 3)"), 3,
true);
651 iStat += EqnTest(
_T(
"f1of4(1, 2, 3, 4)"), 1,
true);
652 iStat += EqnTest(
_T(
"f2of4(1, 2, 3, 4)"), 2,
true);
653 iStat += EqnTest(
_T(
"f3of4(1, 2, 3, 4)"), 3,
true);
654 iStat += EqnTest(
_T(
"f4of4(1, 2, 3, 4)"), 4,
true);
655 iStat += EqnTest(
_T(
"f1of5(1, 2, 3, 4, 5)"), 1,
true);
656 iStat += EqnTest(
_T(
"f2of5(1, 2, 3, 4, 5)"), 2,
true);
657 iStat += EqnTest(
_T(
"f3of5(1, 2, 3, 4, 5)"), 3,
true);
658 iStat += EqnTest(
_T(
"f4of5(1, 2, 3, 4, 5)"), 4,
true);
659 iStat += EqnTest(
_T(
"f5of5(1, 2, 3, 4, 5)"), 5,
true);
661 iStat += EqnTest(
_T(
"1+ping()"), 11,
true);
662 iStat += EqnTest(
_T(
"ping()+1"), 11,
true);
663 iStat += EqnTest(
_T(
"2*ping()"), 20,
true);
664 iStat += EqnTest(
_T(
"ping()*2"), 20,
true);
665 iStat += EqnTest(
_T(
"ping(1,2)"), 0,
false);
666 iStat += EqnTest(
_T(
"1+ping(1,2)"), 0,
false);
667 iStat += EqnTest(
_T(
"f1of1(1,2)"), 0,
false);
668 iStat += EqnTest(
_T(
"f1of1()"), 0,
false);
669 iStat += EqnTest(
_T(
"f1of2(1, 2, 3)"), 0,
false);
670 iStat += EqnTest(
_T(
"f1of2(1)"), 0,
false);
671 iStat += EqnTest(
_T(
"f1of3(1, 2, 3, 4)"), 0,
false);
672 iStat += EqnTest(
_T(
"f1of3(1)"), 0,
false);
673 iStat += EqnTest(
_T(
"f1of4(1, 2, 3, 4, 5)"), 0,
false);
674 iStat += EqnTest(
_T(
"f1of4(1)"), 0,
false);
675 iStat += EqnTest(
_T(
"(1,2,3)"), 0,
false);
676 iStat += EqnTest(
_T(
"1,2,3"), 0,
false);
677 iStat += EqnTest(
_T(
"(1*a,2,3)"), 0,
false);
678 iStat += EqnTest(
_T(
"1,2*a,3"), 0,
false);
681 iStat += EqnTest(
_T(
"min(a, 1)"), 1,
true);
682 iStat += EqnTest(
_T(
"min(3*2, 1)"), 1,
true);
683 iStat += EqnTest(
_T(
"min(3*2, 1)"), 6,
false);
684 iStat += EqnTest(
_T(
"firstArg(2,3,4)"), 2,
true);
685 iStat += EqnTest(
_T(
"lastArg(2,3,4)"), 4,
true);
686 iStat += EqnTest(
_T(
"min(3*a+1, 1)"), 1,
true);
687 iStat += EqnTest(
_T(
"max(3*a+1, 1)"), 4,
true);
688 iStat += EqnTest(
_T(
"max(3*a+1, 1)*2"), 8,
true);
689 iStat += EqnTest(
_T(
"2*max(3*a+1, 1)+2"), 10,
true);
692 iStat += EqnTest(
_T(
"sum(a)"), 1,
true);
693 iStat += EqnTest(
_T(
"sum(1,2,3)"), 6,
true);
694 iStat += EqnTest(
_T(
"sum(a,b,c)"), 6,
true);
695 iStat += EqnTest(
_T(
"sum(1,-max(1,2),3)*2"), 4,
true);
696 iStat += EqnTest(
_T(
"2*sum(1,2,3)"), 12,
true);
697 iStat += EqnTest(
_T(
"2*sum(1,2,3)+2"), 14,
true);
698 iStat += EqnTest(
_T(
"2*sum(-1,2,3)+2"), 10,
true);
699 iStat += EqnTest(
_T(
"2*sum(-1,2,-(-a))+2"), 6,
true);
700 iStat += EqnTest(
_T(
"2*sum(-1,10,-a)+2"), 18,
true);
701 iStat += EqnTest(
_T(
"2*sum(1,2,3)*2"), 24,
true);
702 iStat += EqnTest(
_T(
"sum(1,-max(1,2),3)*2"), 4,
true);
703 iStat += EqnTest(
_T(
"sum(1*3, 4, a+2)"), 10,
true);
704 iStat += EqnTest(
_T(
"sum(1*3, 2*sum(1,2,2), a+2)"), 16,
true);
705 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);
708 iStat += EqnTest(
_T(
"sum()"), 0,
false);
709 iStat += EqnTest(
_T(
"sum(,)"), 0,
false);
710 iStat += EqnTest(
_T(
"sum(1,2,)"), 0,
false);
711 iStat += EqnTest(
_T(
"sum(,1,2)"), 0,
false);
716 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
723 int ParserTester::TestInfixOprt()
728 iStat += EqnTest(
_T(
"+1"), +1,
true);
729 iStat += EqnTest(
_T(
"-(+1)"), -1,
true);
730 iStat += EqnTest(
_T(
"-(+1)*2"), -2,
true);
731 iStat += EqnTest(
_T(
"-(+2)*sqrt(4)"), -4,
true);
732 iStat += EqnTest(
_T(
"3-+a"), 2,
true);
733 iStat += EqnTest(
_T(
"+1*3"), 3,
true);
735 iStat += EqnTest(
_T(
"-1"), -1,
true);
736 iStat += EqnTest(
_T(
"-(-1)"), 1,
true);
737 iStat += EqnTest(
_T(
"-(-1)*2"), 2,
true);
738 iStat += EqnTest(
_T(
"-(-2)*sqrt(4)"), 4,
true);
740 iStat += EqnTest(
_T(
"-a"), -1,
true);
741 iStat += EqnTest(
_T(
"-(a)"), -1,
true);
742 iStat += EqnTest(
_T(
"-(-a)"), 1,
true);
743 iStat += EqnTest(
_T(
"-(-a)*2"), 2,
true);
744 iStat += EqnTest(
_T(
"-(8)"), -8,
true);
745 iStat += EqnTest(
_T(
"-8"), -8,
true);
746 iStat += EqnTest(
_T(
"-(2+1)"), -3,
true);
747 iStat += EqnTest(
_T(
"-(f1of1(1+2*3)+1*2)"), -9,
true);
748 iStat += EqnTest(
_T(
"-(-f1of1(1+2*3)+1*2)"), 5,
true);
749 iStat += EqnTest(
_T(
"-sin(8)"), -0.989358,
true);
750 iStat += EqnTest(
_T(
"3-(-a)"), 4,
true);
751 iStat += EqnTest(
_T(
"3--a"), 4,
true);
752 iStat += EqnTest(
_T(
"-1*3"), -3,
true);
755 iStat += EqnTest(
_T(
"~2#"), 8,
true);
756 iStat += EqnTest(
_T(
"~f1of1(2)#"), 8,
true);
757 iStat += EqnTest(
_T(
"~(b)#"), 8,
true);
758 iStat += EqnTest(
_T(
"(~b)#"), 12,
true);
759 iStat += EqnTest(
_T(
"~(2#)"), 8,
true);
760 iStat += EqnTest(
_T(
"~(f1of1(2)#)"), 8,
true);
762 iStat += EqnTest(
_T(
"-2^2"), -4,
true);
763 iStat += EqnTest(
_T(
"-(a+b)^2"), -9,
true);
764 iStat += EqnTest(
_T(
"(-3)^2"), 9,
true);
765 iStat += EqnTest(
_T(
"-(-2^2)"), 4,
true);
766 iStat += EqnTest(
_T(
"3+-3^2"), -6,
true);
769 iStat += EqnTest(
_T(
"-2'"), -4,
true);
770 iStat += EqnTest(
_T(
"-(1+1)'"), -4,
true);
771 iStat += EqnTest(
_T(
"2+-(1+1)'"), -2,
true);
772 iStat += EqnTest(
_T(
"2+-2'"), -2,
true);
775 iStat += EqnTest(
_T(
"$2^2"), 4,
true);
776 iStat += EqnTest(
_T(
"$(a+b)^2"), 9,
true);
777 iStat += EqnTest(
_T(
"($3)^2"), 9,
true);
778 iStat += EqnTest(
_T(
"$($2^2)"), -4,
true);
779 iStat += EqnTest(
_T(
"3+$3^2"), 12,
true);
782 iStat += EqnTest(
_T(
"~ 123"), (
value_type)123.0 + 2,
true);
783 iStat += EqnTest(
_T(
"~~ 123"), (
value_type)123.0 + 2,
true);
788 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
795 int ParserTester::TestPostFix()
801 iStat += EqnTest(
_T(
"3{m}+5"), 5.003,
true);
802 iStat += EqnTest(
_T(
"1000{m}"), 1,
true);
803 iStat += EqnTest(
_T(
"1000 {m}"), 1,
true);
804 iStat += EqnTest(
_T(
"(a){m}"), 1e-3,
true);
805 iStat += EqnTest(
_T(
"a{m}"), 1e-3,
true);
806 iStat += EqnTest(
_T(
"a {m}"), 1e-3,
true);
807 iStat += EqnTest(
_T(
"-(a){m}"), -1e-3,
true);
808 iStat += EqnTest(
_T(
"-2{m}"), -2e-3,
true);
809 iStat += EqnTest(
_T(
"-2 {m}"), -2e-3,
true);
810 iStat += EqnTest(
_T(
"f1of1(1000){m}"), 1,
true);
811 iStat += EqnTest(
_T(
"-f1of1(1000){m}"), -1,
true);
812 iStat += EqnTest(
_T(
"-f1of1(-1000){m}"), 1,
true);
813 iStat += EqnTest(
_T(
"f4of4(0,0,0,1000){m}"), 1,
true);
814 iStat += EqnTest(
_T(
"2+(a*1000){m}"), 3,
true);
817 iStat += EqnTest(
_T(
"2*3000meg+2"), 2 * 3e9 + 2,
true);
820 iStat += EqnTest(
_T(
"1000{m}"), 0.1,
false);
821 iStat += EqnTest(
_T(
"(a){m}"), 2,
false);
840 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
846 int ParserTester::TestExpression()
853 iStat += EqnTest(
_T(
"f0()"), 42,
true);
854 iStat += EqnTest(
_T(
"b^2"), 4,
true);
855 iStat += EqnTest(
_T(
"b^1"), 2,
true);
856 iStat += EqnTest(
_T(
"b^0"), 1,
true);
857 iStat += EqnTest(
_T(
"b^-1"), 0.5,
true);
860 iStat += EqnTest(
_T(
"2*b*5"), 20,
true);
861 iStat += EqnTest(
_T(
"2*b*5 + 4*b"), 28,
true);
862 iStat += EqnTest(
_T(
"2*a/3"), 2.0 / 3.0,
true);
865 iStat += EqnTest(
_T(
"3+b"), b + 3,
true);
866 iStat += EqnTest(
_T(
"b+3"), b + 3,
true);
867 iStat += EqnTest(
_T(
"b*3+2"), b * 3 + 2,
true);
868 iStat += EqnTest(
_T(
"3*b+2"), b * 3 + 2,
true);
869 iStat += EqnTest(
_T(
"2+b*3"), b * 3 + 2,
true);
870 iStat += EqnTest(
_T(
"2+3*b"), b * 3 + 2,
true);
871 iStat += EqnTest(
_T(
"b+3*b"), b + 3 * b,
true);
872 iStat += EqnTest(
_T(
"3*b+b"), b + 3 * b,
true);
874 iStat += EqnTest(
_T(
"2+b*3+b"), 2 + b * 3 + b,
true);
875 iStat += EqnTest(
_T(
"b+2+b*3"), b + 2 + b * 3,
true);
877 iStat += EqnTest(
_T(
"(2*b+1)*4"), (2 * b + 1) * 4,
true);
878 iStat += EqnTest(
_T(
"4*(2*b+1)"), (2 * b + 1) * 4,
true);
881 iStat += EqnTest(
_T(
"1+2-3*4/5^6"), 2.99923,
true);
882 iStat += EqnTest(
_T(
"1^2/3*4-5+6"), 2.33333333,
true);
883 iStat += EqnTest(
_T(
"1+2*3"), 7,
true);
884 iStat += EqnTest(
_T(
"1+2*3"), 7,
true);
885 iStat += EqnTest(
_T(
"(1+2)*3"), 9,
true);
886 iStat += EqnTest(
_T(
"(1+2)*(-3)"), -9,
true);
887 iStat += EqnTest(
_T(
"2/4"), 0.5,
true);
889 iStat += EqnTest(
_T(
"exp(ln(7))"), 7,
true);
890 iStat += EqnTest(
_T(
"e^ln(7)"), 7,
true);
891 iStat += EqnTest(
_T(
"e^(ln(7))"), 7,
true);
892 iStat += EqnTest(
_T(
"(e^(ln(7)))"), 7,
true);
893 iStat += EqnTest(
_T(
"1-(e^(ln(7)))"), -6,
true);
894 iStat += EqnTest(
_T(
"2*(e^(ln(7)))"), 14,
true);
895 iStat += EqnTest(
_T(
"10^log(5)"), pow(10.0, log(5.0)),
true);
896 iStat += EqnTest(
_T(
"10^log10(5)"), 5,
true);
897 iStat += EqnTest(
_T(
"2^log2(4)"), 4,
true);
898 iStat += EqnTest(
_T(
"-(sin(0)+1)"), -1,
true);
899 iStat += EqnTest(
_T(
"-(2^1.1)"), -2.14354692,
true);
901 iStat += EqnTest(
_T(
"(cos(2.41)/b)"), -0.372056,
true);
902 iStat += EqnTest(
_T(
"(1*(2*(3*(4*(5*(6*(a+b)))))))"), 2160,
true);
903 iStat += EqnTest(
_T(
"(1*(2*(3*(4*(5*(6*(7*(a+b))))))))"), 15120,
true);
904 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);
908 _T(
"(((-9))-e/(((((((pi-(((-7)+(-3)/4/e))))/(((-5))-2)-((pi+(-0))*(sqrt((e+e))*(-8))*(((-pi)+(-pi)-(-9)*(6*5))")
909 _T(
"/(-e)-e))/2)/((((sqrt(2/(-e)+6)-(4-2))+((5/(-2))/(1*(-pi)+3))/8)*pi*((pi/((-2)/(-6)*1*(-1))*(-6)+(-e)))))/")
910 _T(
"((e+(-2)+(-e)*((((-3)*9+(-e)))+(-9)))))))-((((e-7+(((5/pi-(3/1+pi)))))/e)/(-5))/(sqrt((((((1+(-7))))+((((-")
911 _T(
"e)*(-e)))-8))*(-5)/((-e)))*(-6)-((((((-2)-(-9)-(-e)-1)/3))))/(sqrt((8+(e-((-6))+(9*(-9))))*(((3+2-8))*(7+6")
912 _T(
"+(-5))+((0/(-e)*(-pi))+7)))+(((((-e)/e/e)+((-6)*5)*e+(3+(-5)/pi))))+pi))/sqrt((((9))+((((pi))-8+2))+pi))/e")
913 _T(
"*4)*((-5)/(((-pi))*(sqrt(e)))))-(((((((-e)*(e)-pi))/4+(pi)*(-9)))))))+(-pi)"), -12.23016549,
true);
917 _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")
918 _T(
")+a)))*2.77)"), -2.16995656,
true);
921 iStat += EqnTest(
_T(
"1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12"), -7995810.09926,
true);
926 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
934 int ParserTester::TestIfThenElse()
943 iStat += ThrowTest(
_T(
":3"), ecUNEXPECTED_CONDITIONAL);
944 iStat += ThrowTest(
_T(
"? 1 : 2"), ecUNEXPECTED_CONDITIONAL);
945 iStat += ThrowTest(
_T(
"(a<b) ? (b<c) ? 1 : 2"), ecMISSING_ELSE_CLAUSE);
946 iStat += ThrowTest(
_T(
"(a<b) ? 1"), ecMISSING_ELSE_CLAUSE);
947 iStat += ThrowTest(
_T(
"(a<b) ? a"), ecMISSING_ELSE_CLAUSE);
948 iStat += ThrowTest(
_T(
"(a<b) ? a+b"), ecMISSING_ELSE_CLAUSE);
949 iStat += ThrowTest(
_T(
"a : b"), ecMISPLACED_COLON);
950 iStat += ThrowTest(
_T(
"1 : 2"), ecMISPLACED_COLON);
951 iStat += ThrowTest(
_T(
"(1) ? 1 : 2 : 3"), ecMISPLACED_COLON);
955 iStat += ThrowTest(
_T(
"1?2:0?(7:1)"), ecMISPLACED_COLON);
966 iStat += EqnTest(
_T(
"1 ? 128 : 255"), 128,
true);
967 iStat += EqnTest(
_T(
"1<2 ? 128 : 255"), 128,
true);
968 iStat += EqnTest(
_T(
"a<b ? 128 : 255"), 128,
true);
969 iStat += EqnTest(
_T(
"(a<b) ? 128 : 255"), 128,
true);
970 iStat += EqnTest(
_T(
"(1) ? 10 : 11"), 10,
true);
971 iStat += EqnTest(
_T(
"(0) ? 10 : 11"), 11,
true);
972 iStat += EqnTest(
_T(
"(1) ? a+b : c+d"), 3,
true);
973 iStat += EqnTest(
_T(
"(0) ? a+b : c+d"), 1,
true);
974 iStat += EqnTest(
_T(
"(1) ? 0 : 1"), 0,
true);
975 iStat += EqnTest(
_T(
"(0) ? 0 : 1"), 1,
true);
976 iStat += EqnTest(
_T(
"(a<b) ? 10 : 11"), 10,
true);
977 iStat += EqnTest(
_T(
"(a>b) ? 10 : 11"), 11,
true);
978 iStat += EqnTest(
_T(
"(a<b) ? c : d"), 3,
true);
979 iStat += EqnTest(
_T(
"(a>b) ? c : d"), -2,
true);
981 iStat += EqnTest(
_T(
"(a>b) ? 1 : 0"), 0,
true);
982 iStat += EqnTest(
_T(
"((a>b) ? 1 : 0) ? 1 : 2"), 2,
true);
983 iStat += EqnTest(
_T(
"((a>b) ? 1 : 0) ? 1 : sum((a>b) ? 1 : 2)"), 2,
true);
984 iStat += EqnTest(
_T(
"((a>b) ? 0 : 1) ? 1 : sum((a>b) ? 1 : 2)"), 1,
true);
986 iStat += EqnTest(
_T(
"sum((a>b) ? 1 : 2)"), 2,
true);
987 iStat += EqnTest(
_T(
"sum((1) ? 1 : 2)"), 1,
true);
988 iStat += EqnTest(
_T(
"sum((a>b) ? 1 : 2, 100)"), 102,
true);
989 iStat += EqnTest(
_T(
"sum((1) ? 1 : 2, 100)"), 101,
true);
990 iStat += EqnTest(
_T(
"sum(3, (a>b) ? 3 : 10)"), 13,
true);
991 iStat += EqnTest(
_T(
"sum(3, (a<b) ? 3 : 10)"), 6,
true);
992 iStat += EqnTest(
_T(
"10*sum(3, (a>b) ? 3 : 10)"), 130,
true);
993 iStat += EqnTest(
_T(
"10*sum(3, (a<b) ? 3 : 10)"), 60,
true);
994 iStat += EqnTest(
_T(
"sum(3, (a>b) ? 3 : 10)*10"), 130,
true);
995 iStat += EqnTest(
_T(
"sum(3, (a<b) ? 3 : 10)*10"), 60,
true);
996 iStat += EqnTest(
_T(
"(a<b) ? sum(3, (a<b) ? 3 : 10)*10 : 99"), 60,
true);
997 iStat += EqnTest(
_T(
"(a>b) ? sum(3, (a<b) ? 3 : 10)*10 : 99"), 99,
true);
998 iStat += EqnTest(
_T(
"(a<b) ? sum(3, (a<b) ? 3 : 10,10,20)*10 : 99"), 360,
true);
999 iStat += EqnTest(
_T(
"(a>b) ? sum(3, (a<b) ? 3 : 10,10,20)*10 : 99"), 99,
true);
1000 iStat += EqnTest(
_T(
"(a>b) ? sum(3, (a<b) ? 3 : 10,10,20)*10 : sum(3, (a<b) ? 3 : 10)*10"), 60,
true);
1003 iStat += EqnTest(
_T(
"(a<b)&&(a<b) ? 128 : 255"), 128,
true);
1004 iStat += EqnTest(
_T(
"(a>b)&&(a<b) ? 128 : 255"), 255,
true);
1005 iStat += EqnTest(
_T(
"(1<2)&&(1<2) ? 128 : 255"), 128,
true);
1006 iStat += EqnTest(
_T(
"(1>2)&&(1<2) ? 128 : 255"), 255,
true);
1007 iStat += EqnTest(
_T(
"((1<2)&&(1<2)) ? 128 : 255"), 128,
true);
1008 iStat += EqnTest(
_T(
"((1>2)&&(1<2)) ? 128 : 255"), 255,
true);
1009 iStat += EqnTest(
_T(
"((a<b)&&(a<b)) ? 128 : 255"), 128,
true);
1010 iStat += EqnTest(
_T(
"((a>b)&&(a<b)) ? 128 : 255"), 255,
true);
1012 iStat += EqnTest(
_T(
"1>0 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64"), 255,
true);
1013 iStat += EqnTest(
_T(
"1>0 ? 1>2 ? 128 : 255 :(1>0 ? 32 : 64)"), 255,
true);
1014 iStat += EqnTest(
_T(
"1>0 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64"), 128,
true);
1015 iStat += EqnTest(
_T(
"1>0 ? 1>0 ? 128 : 255 :(1>2 ? 32 : 64)"), 128,
true);
1016 iStat += EqnTest(
_T(
"1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64"), 32,
true);
1017 iStat += EqnTest(
_T(
"1>2 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64"), 64,
true);
1018 iStat += EqnTest(
_T(
"1>0 ? 50 : 1>0 ? 128 : 255"), 50,
true);
1019 iStat += EqnTest(
_T(
"1>0 ? 50 : (1>0 ? 128 : 255)"), 50,
true);
1020 iStat += EqnTest(
_T(
"1>0 ? 1>0 ? 128 : 255 : 50"), 128,
true);
1021 iStat += EqnTest(
_T(
"1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 1>2 ? 64 : 16"), 32,
true);
1022 iStat += EqnTest(
_T(
"1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 :(1>2 ? 64 : 16)"), 32,
true);
1023 iStat += EqnTest(
_T(
"1>0 ? 1>2 ? 128 : 255 : 1>0 ? 32 :1>2 ? 64 : 16"), 255,
true);
1024 iStat += EqnTest(
_T(
"1>0 ? 1>2 ? 128 : 255 : (1>0 ? 32 :1>2 ? 64 : 16)"), 255,
true);
1025 iStat += EqnTest(
_T(
"1 ? 0 ? 128 : 255 : 1 ? 32 : 64"), 255,
true);
1028 iStat += EqnTest(
_T(
"a= 0 ? 128 : 255, a"), 255,
true);
1029 iStat += EqnTest(
_T(
"a=((a>b)&&(a<b)) ? 128 : 255, a"), 255,
true);
1030 iStat += EqnTest(
_T(
"c=(a<b)&&(a<b) ? 128 : 255, c"), 128,
true);
1031 iStat += EqnTest(
_T(
"0 ? a=a+1 : 666, a"), 1,
true);
1032 iStat += EqnTest(
_T(
"1?a=10:a=20, a"), 10,
true);
1033 iStat += EqnTest(
_T(
"0?a=10:a=20, a"), 20,
true);
1034 iStat += EqnTest(
_T(
"0?a=sum(3,4):10, a"), 1,
true);
1036 iStat += EqnTest(
_T(
"a=1?b=1?3:4:5, a"), 3,
true);
1037 iStat += EqnTest(
_T(
"a=1?b=1?3:4:5, b"), 3,
true);
1038 iStat += EqnTest(
_T(
"a=0?b=1?3:4:5, a"), 5,
true);
1039 iStat += EqnTest(
_T(
"a=0?b=1?3:4:5, b"), 2,
true);
1041 iStat += EqnTest(
_T(
"a=1?5:b=1?3:4, a"), 5,
true);
1042 iStat += EqnTest(
_T(
"a=1?5:b=1?3:4, b"), 2,
true);
1043 iStat += EqnTest(
_T(
"a=0?5:b=1?3:4, a"), 3,
true);
1044 iStat += EqnTest(
_T(
"a=0?5:b=1?3:4, b"), 3,
true);
1049 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
1055 int ParserTester::TestException()
1080 iStat += ThrowTest(
_T(
"valueof(\"xxx\")"), 999,
false);
1088 iStat += ThrowTest(
_T(
"valueof(\"\\\"abc\\\"\")"), 999,
false);
1126 mu::console() <<
_T(
"\n failed with ") << iStat <<
_T(
" errors") << endl;
1133 void ParserTester::AddTest(testfun_type a_pFun)
1135 m_vTestFun.push_back(a_pFun);
1139 int ParserTester::Run()
1144 for (
int i = 0; i < (int)m_vTestFun.size(); ++i)
1145 iStat += (this->*m_vTestFun[i])();
1153 catch (std::exception& e)
1166 mu::console() <<
"Test passed (" << ParserTester::c_iCount <<
" expressions)" << endl;
1171 <<
" errors (" << ParserTester::c_iCount
1172 <<
" expressions)" << endl;
1174 ParserTester::c_iCount = 0;
1180 int ParserTester::ThrowTest(
const string_type& a_str,
int a_iErrc,
bool a_expectedToFail)
1182 ParserTester::c_iCount++;
1208 if (a_expectedToFail ==
false || (a_expectedToFail ==
true && a_iErrc != e.
GetCode()))
1211 <<
_T(
"Expression: ") << a_str
1213 <<
_T(
" Expected:") << a_iErrc;
1216 return (a_iErrc == e.
GetCode()) ? 0 : 1;
1220 bool bRet((a_expectedToFail ==
false) ? 0 : 1);
1224 <<
_T(
"Expression: ") << a_str
1225 <<
_T(
" did evaluate; Expected error:") << a_iErrc;
1236 int ParserTester::EqnTestWithVarChange(
const string_type& a_str,
1242 ParserTester::c_iCount++;
1261 if (fabs(a_fRes1 - fVal[0]) > 0.0000000001)
1262 throw std::runtime_error(
"incorrect result (first pass)");
1264 if (fabs(a_fRes2 - fVal[1]) > 0.0000000001)
1265 throw std::runtime_error(
"incorrect result (second pass)");
1272 catch (std::exception& e)
1274 mu::console() <<
_T(
"\n fail: ") << a_str.c_str() <<
_T(
" (") << e.what() <<
_T(
")");
1279 mu::console() <<
_T(
"\n fail: ") << a_str.c_str() <<
_T(
" (unexpected exception)");
1291 int ParserTester::EqnTest(
const string_type& a_str,
double a_fRes,
bool a_fPass)
1293 ParserTester::c_iCount++;
1295 value_type fVal[5] = { -999, -998, -997, -996, -995 };
1299 std::unique_ptr<Parser> p1;
1310 p1->DefineConst(
_T(
"const"), 1);
1311 p1->DefineConst(
_T(
"const1"), 2);
1312 p1->DefineConst(
_T(
"const2"), 3);
1314 p1->DefineStrConst(
_T(
"str1"),
_T(
"1.11"));
1315 p1->DefineStrConst(
_T(
"str2"),
_T(
"2.22"));
1318 p1->DefineVar(
_T(
"a"), &vVarVal[0]);
1319 p1->DefineVar(
_T(
"aa"), &vVarVal[1]);
1320 p1->DefineVar(
_T(
"b"), &vVarVal[1]);
1321 p1->DefineVar(
_T(
"c"), &vVarVal[2]);
1322 p1->DefineVar(
_T(
"d"), &vVarVal[3]);
1325 p1->AddValIdent(&ParserTester::IsHexVal);
1328 p1->DefineFun(
_T(
"ping"), Ping);
1329 p1->DefineFun(
_T(
"f0"), f0);
1330 p1->DefineFun(
_T(
"f1of1"), f1of1);
1331 p1->DefineFun(
_T(
"f1of2"), f1of2);
1332 p1->DefineFun(
_T(
"f2of2"), f2of2);
1333 p1->DefineFun(
_T(
"f1of3"), f1of3);
1334 p1->DefineFun(
_T(
"f2of3"), f2of3);
1335 p1->DefineFun(
_T(
"f3of3"), f3of3);
1336 p1->DefineFun(
_T(
"f1of4"), f1of4);
1337 p1->DefineFun(
_T(
"f2of4"), f2of4);
1338 p1->DefineFun(
_T(
"f3of4"), f3of4);
1339 p1->DefineFun(
_T(
"f4of4"), f4of4);
1340 p1->DefineFun(
_T(
"f1of5"), f1of5);
1341 p1->DefineFun(
_T(
"f2of5"), f2of5);
1342 p1->DefineFun(
_T(
"f3of5"), f3of5);
1343 p1->DefineFun(
_T(
"f4of5"), f4of5);
1344 p1->DefineFun(
_T(
"f5of5"), f5of5);
1347 p1->DefineOprt(
_T(
"add"), add, 0);
1348 p1->DefineOprt(
_T(
"++"), add, 0);
1349 p1->DefineOprt(
_T(
"&"), land, prLAND);
1352 p1->DefineFun(
_T(
"min"), Min);
1353 p1->DefineFun(
_T(
"max"), Max);
1354 p1->DefineFun(
_T(
"sum"), Sum);
1355 p1->DefineFun(
_T(
"valueof"), ValueOf);
1356 p1->DefineFun(
_T(
"atof"), StrToFloat);
1357 p1->DefineFun(
_T(
"strfun1"), StrFun1);
1358 p1->DefineFun(
_T(
"strfun2"), StrFun2);
1359 p1->DefineFun(
_T(
"strfun3"), StrFun3);
1360 p1->DefineFun(
_T(
"strfun4"), StrFun4);
1361 p1->DefineFun(
_T(
"strfun5"), StrFun5);
1362 p1->DefineFun(
_T(
"lastArg"), LastArg);
1363 p1->DefineFun(
_T(
"firstArg"), FirstArg);
1364 p1->DefineFun(
_T(
"order"), FirstArg);
1369 p1->DefineInfixOprt(
_T(
"$"), sign,
prPOW + 1);
1370 p1->DefineInfixOprt(
_T(
"~"), plus2);
1371 p1->DefineInfixOprt(
_T(
"~~"), plus2);
1372 p1->DefinePostfixOprt(
_T(
"{m}"), Milli);
1373 p1->DefinePostfixOprt(
_T(
"{M}"), Mega);
1374 p1->DefinePostfixOprt(
_T(
"m"), Milli);
1375 p1->DefinePostfixOprt(
_T(
"meg"), Mega);
1376 p1->DefinePostfixOprt(
_T(
"#"), times3);
1377 p1->DefinePostfixOprt(
_T(
"'"), sqr);
1382 fVal[0] = p1->Eval();
1383 fVal[1] = p1->Eval();
1384 if (fVal[0] != fVal[1])
1391 std::vector<mu::Parser> vParser;
1392 vParser.push_back(*(p1.get()));
1399 fVal[2] = p4.
Eval();
1406 fVal[3] = p5.
Eval();
1412 fVal[4] = v[nNum - 1];
1414 catch (std::exception& e)
1420 bool bCloseEnough(
true);
1421 for (
unsigned i = 0; i <
sizeof(fVal) /
sizeof(
value_type); ++i)
1423 bCloseEnough &= (fabs(a_fRes - fVal[i]) <= fabs(fVal[i] * 0.00001));
1429 #pragma warning(push)
1430 #pragma warning(disable:4127)
1432 if (std::numeric_limits<value_type>::has_infinity)
1434 #pragma warning(pop)
1437 bCloseEnough &= (fabs(fVal[i]) != numeric_limits<value_type>::infinity());
1441 iRet = ((bCloseEnough && a_fPass) || (!bCloseEnough && !a_fPass)) ? 0 : 1;
1447 <<
_T(
" (incorrect result; expected: ") << a_fRes
1448 <<
_T(
" ;calculated: ") << fVal[0] <<
_T(
",")
1449 << fVal[1] <<
_T(
",")
1450 << fVal[2] <<
_T(
",")
1451 << fVal[3] <<
_T(
",")
1452 << fVal[4] <<
_T(
").");
1459 if (fVal[0] != fVal[2] && fVal[0] != -999 && fVal[1] != -998)
1460 mu::console() <<
_T(
"\n fail: ") << a_str.c_str() <<
_T(
" (copy construction)");
1466 catch (std::exception& e)
1468 mu::console() <<
_T(
"\n fail: ") << a_str.c_str() <<
_T(
" (") << e.what() <<
_T(
")");
1473 mu::console() <<
_T(
"\n fail: ") << a_str.c_str() <<
_T(
" (unexpected exception)");
1481 int ParserTester::EqnTestInt(
const string_type& a_str,
double a_fRes,
bool a_fPass)
1483 ParserTester::c_iCount++;
1502 if (fVal[0] != fVal[1])
1505 iRet = ((a_fRes == fVal[0] && a_fPass) ||
1506 (a_fRes != fVal[0] && !a_fPass)) ? 0 : 1;
1510 <<
_T(
" (incorrect result; expected: ") << a_fRes
1511 <<
_T(
" ;calculated: ") << fVal[0] <<
_T(
").");
1524 mu::console() <<
_T(
"\n fail: ") << a_str.c_str() <<
_T(
" (unexpected exception)");
1533 int ParserTester::EqnTestBulk(
const string_type& a_str,
double a_fRes[4],
bool a_fPass)
1535 ParserTester::c_iCount++;
1555 p.
Eval(vResults, nBulkSize);
1557 bool bCloseEnough(
true);
1558 for (
int i = 0; i < nBulkSize; ++i)
1560 bCloseEnough &= (fabs(a_fRes[i] - vResults[i]) <= fabs(a_fRes[i] * 0.00001));
1563 iRet = ((bCloseEnough && a_fPass) || (!bCloseEnough && !a_fPass)) ? 0 : 1;
1567 <<
_T(
" (incorrect result; expected: {") << a_fRes[0] <<
_T(
",") << a_fRes[1] <<
_T(
",") << a_fRes[2] <<
_T(
",") << a_fRes[3] <<
_T(
"}")
1568 <<
_T(
" ;calculated: ") << vResults[0] <<
_T(
",") << vResults[1] <<
_T(
",") << vResults[2] <<
_T(
",") << vResults[3] <<
_T(
"}");
1581 mu::console() <<
_T(
"\n fail: ") << a_str.c_str() <<
_T(
" (unexpected exception)");
1590 void ParserTester::Abort()
const
1592 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
An unexpected comma has been found. (Example: "1,23")
void DefineVar(const string_type &a_sName, value_type *a_fVar)
Add a user defined variable.
std::ostream & console()
Encapsulate cout.
Token can't be identified.
An unexpected argument has been found.
std::map< string_type, value_type * > varmap_type
Type used for storing variables.
unterminated string constant. (Example: "3*valueof("hello)")
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.
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.
A template class for providing wrappers for essential math functions.
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.
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.
A string has been found at an inapropriate position.
const varmap_type & GetUsedVar() const
Return a map containing the used variables only.