-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathparser.cpp
More file actions
118 lines (94 loc) · 3.26 KB
/
parser.cpp
File metadata and controls
118 lines (94 loc) · 3.26 KB
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
#include <string>
#include <vector>
#include <iostream>
#include "parser.h"
#include "tokens.h"
#include "nodes.h"
namespace Parser {
Parser::Parser(std::vector<Tokens::Token> tokens) {
tokens.push_back(Tokens::Token(Tokens::EOF_));
this->tokens = tokens;
index = 0;
}
Parser::~Parser() {
Nodes::free_node(node);
}
void Parser::advance() {
index++;
}
Tokens::Token Parser::current() {
return tokens[index];
}
Nodes::Node *Parser::parse() {
if (current().type == Tokens::EOF_) {
PARSER_EMPTY_NODE;
return node;
}
node = expr();
if (current().type != Tokens::EOF_) {
PARSER_EMPTY_NODE;
throw std::string("Invalid syntax");
}
return node;
}
Nodes::Node *Parser::expr() {
Nodes::Node *result = term();
while (current().type != Tokens::EOF_ && (current().type == Tokens::PLUS || current().type == Tokens::MINUS)) {
if (current().type == Tokens::PLUS) {
advance();
result = new Nodes::Node(Nodes::AddNode, result, term());
} else if (current().type == Tokens::MINUS) {
advance();
result = new Nodes::Node(Nodes::SubtractNode, result, term());
}
}
return result;
}
Nodes::Node *Parser::term() {
Nodes::Node *result = exponent();
while (current().type != Tokens::EOF_ && (current().type == Tokens::MULTIPLY || current().type == Tokens::DIVIDE)) {
if (current().type == Tokens::MULTIPLY) {
advance();
result = new Nodes::Node(Nodes::MultiplyNode, result, exponent());
} else if (current().type == Tokens::DIVIDE) {
advance();
result = new Nodes::Node(Nodes::DivideNode, result, exponent());
}
}
return result;
}
Nodes::Node *Parser::exponent() {
Nodes::Node *result = factor();
while (current().type != Tokens::EOF_ && current().type == Tokens::POWER) {
if (current().type == Tokens::POWER) {
advance();
result = new Nodes::Node(Nodes::PowerNode, result, factor());
}
}
return result;
}
Nodes::Node *Parser::factor() {
Tokens::Token current_token = current();
if (current_token.type == Tokens::LPAREN) {
advance();
Nodes::Node *result = expr();
if (current().type != Tokens::RPAREN) {
PARSER_EMPTY_NODE;
throw std::string("Syntax error");
}
advance();
return result;
} else if (current_token.type == Tokens::NUMBER) {
advance();
return new Nodes::Node(Nodes::NumberNode, current_token.value);
} else if (current_token.type == Tokens::PLUS) {
advance();
return new Nodes::Node(Nodes::PlusNode, factor());
} else if (current_token.type == Tokens::MINUS) {
advance();
return new Nodes::Node(Nodes::MinusNode, factor());
}
PARSER_EMPTY_NODE;
throw std::string("Syntax error");
}
}