-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathparser.cpp
104 lines (83 loc) · 2.71 KB
/
parser.cpp
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
#include <string>
#include <memory>
#include <vector>
#include "parser.h"
namespace Math_Interpreter {
Parser::Parser(const std::vector<Token>& tokens)
: tokens(tokens),
pos(0),
current(Token(TokenType::EOF_))
{
if (this->tokens.empty()) {
this->tokens.push_back(TokenType::EOF_);
} else if (this->tokens.back().type != TokenType::EOF_) {
this->tokens.push_back(TokenType::EOF_);
}
advance();
}
void Parser::raise_error() const {
throw std::string("Invalid syntax");
}
void Parser::advance() {
current = tokens.at(pos++);
}
std::unique_ptr<Node> Parser::parse() {
if (!current) {
return std::unique_ptr<Node>();
}
std::unique_ptr<Node> result = expr();
if (current) {
raise_error();
}
return result;
}
std::unique_ptr<Node> Parser::expr() {
std::unique_ptr<Node> result = term();
while (current && (current.type == TokenType::PLUS || current.type == TokenType::MINUS)) {
if (current.type == TokenType::PLUS) {
advance();
result = std::unique_ptr<AddNode>(new AddNode(std::move(result), term()));
} else if (current.type == TokenType::MINUS) {
advance();
result = std::unique_ptr<SubtractNode>(new SubtractNode(std::move(result), term())); // Missin' std::make_unique :(
}
}
return result;
}
std::unique_ptr<Node> Parser::term() {
std::unique_ptr<Node> result = factor();
while (current && (current.type == TokenType::MULTIPLY || current.type == TokenType::DIVIDE)) {
if (current.type == TokenType::MULTIPLY) {
advance();
result = std::unique_ptr<MultiplyNode>(new MultiplyNode(std::move(result), factor()));
} else if (current.type == TokenType::DIVIDE) {
advance();
result = std::unique_ptr<DivideNode>(new DivideNode(std::move(result), factor()));
}
}
return result;
}
std::unique_ptr<Node> Parser::factor() {
Token token = current;
if (token.type == TokenType::LPAREN) {
advance();
std::unique_ptr<Node> result = expr();
if (current.type != TokenType::RPAREN) {
raise_error();
}
advance();
return result;
} else if (token.type == TokenType::NUMBER) {
advance();
return std::unique_ptr<NumberNode>(new NumberNode(token.value));
} else if (token.type == TokenType::PLUS) {
advance();
return std::unique_ptr<PlusNode>(new PlusNode(factor()));
} else if (token.type == TokenType::MINUS) {
advance();
return std::unique_ptr<MinusNode>(new MinusNode(factor()));
}
raise_error();
return std::unique_ptr<Node>();
}
} // namespace Math_Interpreter