File: test_rule.cpp

package info (click to toggle)
libpog 0.5.3-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 3,644 kB
  • sloc: cpp: 51,038; ansic: 239; makefile: 14; python: 11; sh: 11
file content (106 lines) | stat: -rw-r--r-- 3,654 bytes parent folder | download
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);
}