-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathExprInterpreter.h
75 lines (66 loc) · 2.35 KB
/
ExprInterpreter.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
/**
* @file ExprInterpreter.h
* @author NULL0x7f
* @brief #&Ef@i$Lt^on_Y$hw
* @date 2022-09-15
*/
#ifndef _EXPR_INTERPRETER_H_
#define _EXPR_INTERPRETER_H_
#include "ASTVisitor.h"
#include "ExprParser.h"
class ExprInterpreter : ASTVisitor {
private:
ExprParser parser;
public:
ExprInterpreter() {}
ExprInterpreter(const ExprParser& parser) : parser(parser) {}
ExprParser getParser() const { return parser; }
void setParser(const ExprParser& parser) {this->parser = parser; }
double visitNum(Num* node) { return node->getValue(); }
double visitUnaryOp(UnaryOp* node) {
if (node->getToken().getType() == PLUS) {
return visit(node->getOperands());
} else if (node->getToken().getType() == MINUS) {
return -visit(node->getOperands());
}
throw Exception("Invalid syntax");
}
double visitBinOp(BinOP* node) {
if (node->getToken().getType() == PLUS) {
return visit(node->getLeft()) + visit(node->getRight());
}
if (node->getToken().getType() == MINUS) {
return visit(node->getLeft()) - visit(node->getRight());
}
if (node->getToken().getType() == MUL) {
return visit(node->getLeft()) * visit(node->getRight());
}
if (node->getToken().getType() == DIV) {
double num1 = visit(node->getLeft());
double num2 = visit(node->getRight());
if (fabs(num2) < EPS)
throw Exception("dived by 0");
return num1 / num2;
}
if (node->getToken().getType() == POW) {
return pow(visit(node->getLeft()), visit(node->getRight()));
}
throw Exception("Invalid syntax");
}
double visit(AST* node) {
if ("Num" == node->className())
return visitNum(dynamic_cast<Num*>(node));
if ("UnaryOp" == node->className())
return visitUnaryOp(dynamic_cast<UnaryOp*>(node));
if ("BinOp" == node->className())
return visitBinOp(dynamic_cast<BinOP*>(node));
throw Exception("Invalid syntax");
}
double interpret() {
AST* node = parser.expr();
if (parser.getCurToken()->getType() != EoF)
throw Exception("Invalid syntax");
return visit(node);
}
};
#endif