This repository has been archived by the owner on Feb 15, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
eval.h
136 lines (112 loc) · 3.88 KB
/
eval.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
125
126
127
128
129
130
131
132
133
134
135
136
//
// Created by brinza on 19.05.22.
//
#ifndef SHUNTING_YARD_EVAL_H
#define SHUNTING_YARD_EVAL_H
#include <string>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <stdexcept>
#include <cmath>
#include <cctype>
class InvalidInput: public std::invalid_argument {
using std::invalid_argument::invalid_argument;
};
class SyntaxError: public std::invalid_argument {
using std::invalid_argument::invalid_argument;
};
namespace Eval {
struct Operator {
enum class Associativity {
Left = 0,
Right = 1
};
const std::string name;
unsigned int priority = 0;
Associativity assoc = Associativity::Left;
double(*func)(double, double);
Operator(const std::string& name,
unsigned int priority,
double(*func)(double, double),
Associativity assoc = Associativity::Left);
};
struct Function {
const std::string name;
size_t argc = 1;
double(*func)(std::vector<double>&);
Function(const std::string& name, size_t argc, double(*func)(std::vector<double>&));
};
struct Token {
enum class Type {
Number = 0,
Operator,
Function,
LeftBrace,
RightBrace,
ArgsSep
};
union UValue {
double number = 0;
Operator* oper;
Function* func;
} value;
Type type = Type::Number;
Token() = default;
Token(Type type);
Token(double number);
Token(Operator* oper);
Token(Function* func);
Token(char brace);
};
std::ostream& operator<<(std::ostream& stream, Token token);
using OperatorMap = typename std::unordered_map<char, Operator*>;
using FunctionMap = typename std::unordered_map<std::string, Function*>;
const OperatorMap operators({
{'+', new Operator("+", 100, [](double a, double b){ return a + b; })},
{'-', new Operator("-", 100, [](double a, double b){ return a - b; })},
{'*', new Operator("*", 200, [](double a, double b){ return a * b; })},
{'/', new Operator("/", 200, [](double a, double b){ return a / b; })},
{'^', new Operator("^", 300, [](double a, double b){
return std::pow(a, b);
}, Operator::Associativity::Right)}
});
const FunctionMap functions({
{"sin", new Function("sin", 1, [](std::vector<double>& args){
return std::sin(args[0]);
})},
{"cos", new Function("cos", 1, [](std::vector<double>& args){
return std::cos(args[0]);
})},
{"tan", new Function("tan", 1, [](std::vector<double>& args) {
return std::tan(args[0]);
})},
{"cot", new Function("cot", 1, [](std::vector<double>& args){
return (1 / std::tan(args[0]));
})},
{"abs", new Function("abs", 1, [](std::vector<double>& args){
return std::abs(args[0]);
})},
{"pow", new Function("pow", 2, [](std::vector<double>& args){
return std::pow(args[0], args[1]);
})},
{"sgn", new Function("sgn", 1, [](std::vector<double>& args){
double x = args[0];
if (x > 0) return 1.0;
else if (x < 0) return -1.0;
else return 0.0;
})}
});
const std::unordered_set<char> whitespaces ({
' ', '\n', '\t'
});
enum class MinusState {
UNARY = 0,
BINARY = 1
};
std::vector<Token> tokenize(const std::string& expression);
std::vector<Token> shuntingYard(const std::vector<Token>& input);
double eval(const std::vector<Token>& rpnExpression);
double eval(const std::string& expression);
}
#endif //SHUNTING_YARD_EVAL_H