-
Notifications
You must be signed in to change notification settings - Fork 0
/
Production.h
76 lines (67 loc) · 1.3 KB
/
Production.h
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
#pragma once
#include "ProductionItem.h"
#include "Terminal.h"
#include <deque>
#include <set>
#include <algorithm>
#include <iterator>
class Production
{
public:
const std::deque<ProductionItem>& GetItems() const
{
return items;
}
const std::set<Terminal>& GetFirst() const
{
return first;
}
Production& AddItem(const Terminal& terminal)
{
items.emplace_back(terminal);
return *this;
}
Production& AddItem(const std::string& nonTerminal)
{
items.emplace_back(nonTerminal);
return *this;
}
Production& AddItem(const ProductionItem& item)
{
items.push_back(item);
return *this;
}
void RemoveFront()
{
if (items.empty())
throw std::runtime_error("Cannot remove the front of an empty production.");
items.pop_front();
}
void AddFirst(const Terminal& terminal)
{
first.insert(terminal);
}
void MergeFirst(const std::set<Terminal>& source)
{
std::copy_if(
source.begin(),
source.end(),
std::inserter(first, first.begin()),
[](auto& t){ return t != Terminal::EndOfFile(); });
}
bool IsEmpty() const
{
return items.empty();
}
bool operator==(const Production& rhs) const
{
return items == rhs.items;
}
bool operator!=(const Production& rhs) const
{
return !operator==(rhs);
}
public:
std::deque<ProductionItem> items;
std::set<Terminal> first;
};