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