-
Notifications
You must be signed in to change notification settings - Fork 0
/
Terminal.h
124 lines (112 loc) · 2.3 KB
/
Terminal.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
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#pragma once
#include "TokenType.h"
#include "Token.h"
#include "BinaryReader.h"
#include "BinaryWriter.h"
#include <string>
#include <sstream>
class Terminal
{
public:
Terminal() = default;
Terminal(TokenType type, const std::string& value)
: type(type), value(value)
{
}
TokenType GetType() const
{
return type;
}
const std::string& GetValue() const
{
return value;
}
bool operator==(const Token& token) const
{
if (type == TokenType::Keyword && value == "$")
return token == Token::EndOfFile();
return type == token.GetType() && (value.empty() || token == value);
}
bool operator!=(const Token& token) const
{
return !operator==(token);
}
bool operator==(const Terminal& rhs) const
{
return type == rhs.type && value == rhs.value;
}
bool operator!=(const Terminal& rhs) const
{
return !operator==(rhs);
}
bool operator<(const Terminal& rhs) const
{
return type < rhs.type || (type == rhs.type && value < rhs.value);
}
void Write(BinaryWriter& writer) const
{
writer.Write(static_cast<std::size_t>(type));
writer.Write(value);
}
void Read(BinaryReader& reader)
{
type = static_cast<TokenType>(reader.ReadSize());
value = reader.ReadString();
}
std::string ToString() const
{
std::ostringstream out;
switch (type)
{
case TokenType::Identifier:
if (value.empty())
out << "id";
else
out << "<id.," << value << ">";
break;
case TokenType::Constant:
if (value.empty())
out << "val";
else
out << value;
break;
case TokenType::Keyword:
if (value == "$" || value == "#" || value == "@")
out << value;
else
out << "\"" << value << "\"";
break;
case TokenType::Operator:
out << "'" << value << "'";
break;
}
return out.str();
}
static Terminal Keyword(const std::string& value)
{
return{ TokenType::Keyword, value };
}
static Terminal Operator(const std::string& value)
{
return{ TokenType::Operator, value };
}
static Terminal Identifier(const std::string& value = "")
{
return{ TokenType::Identifier, value };
}
static Terminal Constant()
{
return{ TokenType::Constant, "" };
}
static Terminal EndOfFile()
{
return{ TokenType::Keyword, "$" };
}
static Terminal LookAhead()
{
return{ TokenType::Keyword, "#" };
}
private:
TokenType type = TokenType::EndOfFile;
std::string value;
};