1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
#include <gtest/gtest.h>
#include <pog/rule.h>
class TestRule : public ::testing::Test {};
using namespace pog;
TEST_F(TestRule,
SimpleRule) {
Symbol<int> s1(1, SymbolKind::Nonterminal, "1");
Symbol<int> s2(2, SymbolKind::Nonterminal, "2");
Symbol<int> s3(3, SymbolKind::Nonterminal, "3");
Rule<int> rule(42, &s1, std::vector<const Symbol<int>*>{&s2, &s3}, [](std::vector<int>&&) -> int { return 0; });
EXPECT_EQ(rule.get_index(), 42u);
EXPECT_EQ(rule.get_lhs(), &s1);
EXPECT_EQ(rule.get_rhs(), (std::vector<const Symbol<int>*>{&s2, &s3}));
EXPECT_FALSE(rule.has_precedence());
}
TEST_F(TestRule,
Precedence) {
Symbol<int> s1(1, SymbolKind::Nonterminal, "1");
Symbol<int> s2(2, SymbolKind::Nonterminal, "2");
Symbol<int> s3(3, SymbolKind::Nonterminal, "3");
Rule<int> rule(42, &s1, std::vector<const Symbol<int>*>{&s2, &s3}, [](std::vector<int>&&) -> int { return 0; });
rule.set_precedence(1, Associativity::Right);
EXPECT_EQ(rule.get_index(), 42u);
EXPECT_EQ(rule.get_lhs(), &s1);
EXPECT_EQ(rule.get_rhs(), (std::vector<const Symbol<int>*>{&s2, &s3}));
EXPECT_TRUE(rule.has_precedence());
EXPECT_EQ(rule.get_precedence(), (Precedence{1, Associativity::Right}));
}
TEST_F(TestRule,
RightmostTerminalWhileThereIsNone) {
Symbol<int> s1(1, SymbolKind::Nonterminal, "1");
Symbol<int> s2(2, SymbolKind::Nonterminal, "2");
Symbol<int> s3(3, SymbolKind::Nonterminal, "3");
Rule<int> rule(42, &s1, std::vector<const Symbol<int>*>{&s2, &s3}, [](std::vector<int>&&) -> int { return 0; });
EXPECT_EQ(rule.get_rightmost_terminal(), nullptr);
}
TEST_F(TestRule,
RightmostTerminal) {
Symbol<int> s1(1, SymbolKind::Nonterminal, "1");
Symbol<int> s2(2, SymbolKind::Terminal, "2");
Symbol<int> s3(3, SymbolKind::Terminal, "3");
Symbol<int> s4(4, SymbolKind::Nonterminal, "4");
Rule<int> rule(42, &s1, std::vector<const Symbol<int>*>{&s2, &s3, &s4}, [](std::vector<int>&&) -> int { return 0; });
EXPECT_EQ(rule.get_rightmost_terminal(), &s3);
}
TEST_F(TestRule,
ToString) {
Symbol<int> s1(1, SymbolKind::Nonterminal, "1");
Symbol<int> s2(2, SymbolKind::Terminal, "2");
Symbol<int> s3(3, SymbolKind::Terminal, "3");
Symbol<int> s4(4, SymbolKind::Nonterminal, "4");
Rule<int> rule(42, &s1, std::vector<const Symbol<int>*>{&s2, &s3, &s4}, [](std::vector<int>&&) -> int { return 0; });
EXPECT_EQ(rule.to_string(), "1 -> 2 3 4");
}
TEST_F(TestRule,
EpsilonToString) {
Symbol<int> s1(1, SymbolKind::Nonterminal, "1");
Rule<int> rule(42, &s1, std::vector<const Symbol<int>*>{}, [](std::vector<int>&&) -> int { return 0; });
EXPECT_EQ(rule.to_string(), "1 -> <eps>");
}
TEST_F(TestRule,
PerformAction) {
bool called = false;
Symbol<int> s1(1, SymbolKind::Nonterminal, "1");
Rule<int> rule(42, &s1, std::vector<const Symbol<int>*>{}, [&](std::vector<int>&& args) -> int {
called = true;
return static_cast<int>(args.size());
});
EXPECT_EQ(rule.perform_action(std::vector<int>{1, 2, 3, 4}), 4);
EXPECT_TRUE(called);
}
TEST_F(TestRule,
Equality) {
Symbol<int> s1(1, SymbolKind::Nonterminal, "1");
Symbol<int> s2(2, SymbolKind::Terminal, "2");
Symbol<int> s3(3, SymbolKind::Terminal, "3");
Symbol<int> s4(4, SymbolKind::Nonterminal, "4");
Rule<int> rule1(42, &s1, std::vector<const Symbol<int>*>{&s2, &s3, &s4}, [](std::vector<int>&&) -> int { return 0; });
Rule<int> rule2(42, &s1, std::vector<const Symbol<int>*>{}, [](std::vector<int>&&) -> int { return 0; });
Rule<int> rule3(43, &s1, std::vector<const Symbol<int>*>{&s2, &s3, &s4}, [](std::vector<int>&&) -> int { return 0; });
EXPECT_TRUE(rule1 == rule2);
EXPECT_FALSE(rule1 == rule3);
EXPECT_FALSE(rule1 != rule2);
EXPECT_TRUE(rule1 != rule3);
}
|