Belle II Software  release-05-01-25
formula_parser.cc
1 #include <framework/utilities/FormulaParser.h>
2 #include <gtest/gtest.h>
3 
4 using namespace Belle2;
5 
6 namespace {
7  class FormulaParserTest: public ::testing::Test {
8  protected:
10  std::string parse(const std::string& s) { return m_parser.parse(s); }
11 
12  };
13 
14 #define EXPECT_FORMULA_OK(a, b) EXPECT_NO_THROW({EXPECT_EQ(parse(a), b);})
15 #define EXPECT_FORMULA_FLOAT_EQ(a, b) EXPECT_NO_THROW({EXPECT_FLOAT_EQ(std::stof(parse(a)), b);})
16 #define EXPECT_FORMULA_FAIL(a) EXPECT_THROW(parse(a), std::runtime_error)
17 
18  TEST_F(FormulaParserTest, Simple)
19  {
20  EXPECT_FORMULA_OK("a", "'a'");
21  EXPECT_FORMULA_OK("(a)", "'a'");
22  EXPECT_FORMULA_OK("[a]", "'a'");
23  EXPECT_FORMULA_OK("([a])", "'a'");
24  EXPECT_FORMULA_OK("[(a)]", "'a'");
25  EXPECT_FORMULA_OK("a + b", "('a'+'b')");
26  EXPECT_FORMULA_OK("a - b", "('a'-'b')");
27  EXPECT_FORMULA_OK("a * b", "('a'*'b')");
28  EXPECT_FORMULA_OK("a / b", "('a'/'b')");
29  EXPECT_FORMULA_OK("a ^ b", "('a'^'b')");
30  EXPECT_FORMULA_FAIL("(a");
31  EXPECT_FORMULA_FAIL("a)");
32  EXPECT_FORMULA_FAIL("[a");
33  EXPECT_FORMULA_FAIL("a]");
34  EXPECT_FORMULA_FAIL("(a]");
35  EXPECT_FORMULA_FAIL("[a)");
36  EXPECT_FORMULA_FAIL("([a)]");
37  EXPECT_FORMULA_FAIL("[(a])");
38  EXPECT_FORMULA_FAIL("+");
39  EXPECT_FORMULA_FAIL("+a");
40  EXPECT_FORMULA_FAIL("a+");
41  EXPECT_FORMULA_FAIL("a +- b");
42  EXPECT_FORMULA_FAIL("a +* b");
43  EXPECT_FORMULA_FAIL("a +/ b");
44  EXPECT_FORMULA_FAIL("a +^ b");
45  }
46  TEST_F(FormulaParserTest, Numbers)
47  {
48  EXPECT_FORMULA_OK("0", "0.000000");
49  EXPECT_FORMULA_OK("1", "1.000000");
50  EXPECT_FORMULA_OK("2.", "2.000000");
51  EXPECT_FORMULA_OK(".3", "0.300000");
52  EXPECT_FORMULA_OK("+4", "4.000000");
53  EXPECT_FORMULA_OK("-5", "-5.000000");
54  EXPECT_FORMULA_OK("+6e0", "6.000000");
55  EXPECT_FORMULA_OK("-7e0", "-7.000000");
56  EXPECT_FORMULA_OK("8.e-1", "0.800000");
57  EXPECT_FORMULA_FAIL("/9.0");
58  EXPECT_FORMULA_FAIL("*10.0");
59  EXPECT_FORMULA_OK("11**2", "121.000000");
60  EXPECT_FORMULA_OK("12^2", "144.000000");
61  }
62 
63  TEST_F(FormulaParserTest, OperatorPrecedence)
64  {
65  EXPECT_FORMULA_OK("a+b+c", "(('a'+'b')+'c')");
66  EXPECT_FORMULA_OK("a+b*c", "('a'+('b'*'c'))");
67  EXPECT_FORMULA_OK("a^b*c", "(('a'^'b')*'c')");
68 
69  EXPECT_FORMULA_OK("10.58-2+4", "12.580000"); // c/o. Racha
70  EXPECT_FORMULA_OK("10.58-(2+4)", "4.580000");
71  EXPECT_FORMULA_OK("10.58-[2+4]", "4.580000");
72  }
73 
74  TEST_F(FormulaParserTest, MiscMaths)
75  {
76  EXPECT_FORMULA_OK("2^(1/2)", "1.414214");
77  EXPECT_FORMULA_OK("2**(1/2)", "1.414214");
78  }
79 
80  TEST_F(FormulaParserTest, OrdersOfMagnitude)
81  {
82  EXPECT_FORMULA_OK("1e10", "10000000000.000000");
83  EXPECT_FORMULA_OK("1E10", "10000000000.000000");
84  EXPECT_FORMULA_OK("1*10**10", "10000000000.000000");
85  EXPECT_FORMULA_OK("1*10^10", "10000000000.000000");
86  EXPECT_FORMULA_FLOAT_EQ("((-3+5) * 10 ^ 2 / 3e-12)", 66666666666666.66);
87  }
88 }
Belle2::FormulaParser::parse
VariableType parse(const std::string &formula)
Parse the formula and return a varible object of the correct type.
Definition: FormulaParser.h:154
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::TEST_F
TEST_F(GlobalLabelTest, LargeNumberOfTimeDependentParameters)
Test large number of time-dep params for registration and retrieval.
Definition: globalLabel.cc:65
Belle2::FormulaParser
FormulaParser to parse a text formula like "a + b * c ^ d" where the separate parts can be either var...
Definition: FormulaParser.h:144