-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.h
More file actions
88 lines (71 loc) · 2.39 KB
/
parser.h
File metadata and controls
88 lines (71 loc) · 2.39 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
#pragma once
#include "AST.h"
#include "AST.inl"
#include <memory>
class parser{
std::string exp;
std::unique_ptr<AST> ast;
public:
std::string namely_name;
private:
void obtain_namely_name(tokenizer const& tn);
void implicit_mul(tokenizer& tn);
void make_equation(tokenizer& tn);
public:
parser(std::string const& str): exp{str}
{}
parser(std::string&& str): exp{std::move(str)}
{}
void parse(){
tokenizer tn(exp);
obtain_namely_name(tn);
implicit_mul(tn); // 0.5x -> 0.5 * x
make_equation(tn); // (3+(4-1))*5 -> ((3+(4-1))*5) = result
ast = std::make_unique<AST>(tn);
}
float eval(){
auto res = ast->root->eval(); // a*x + b = 0
float ret = -(res.b / res.a);
if(ret == 0){
return 0; // getting rid of -0
}
return ret;
}
};
void parser::obtain_namely_name(tokenizer const& tn){
bool is_equation = false;
for(auto const& t : tn.token_list){
if(typeid(*t) == typeid(token::variable)){
if(namely_name == ""){
namely_name = static_cast<token::variable *>(t.get())->content;
}else if(static_cast<token::variable *>(t.get())->content != namely_name){
throw parse_error("Only one namely supported!");
}
}else if(typeid(*t) == typeid(token::eq)){
is_equation = true;
}
}
if(namely_name == "" && is_equation){
throw parse_error("There must be namely in equation");
}else if(namely_name != "" && !is_equation){
throw parse_error("Namely possible only in equations");
}
}
void parser::implicit_mul(tokenizer& tn){
auto end = tn.token_list.end() - 1;
for(auto i = tn.token_list.begin(); i != end; i++){
if(typeid(**i) == typeid(token::number)
&&( typeid(**(i+1)) == typeid(token::par_left)
|| typeid(**(i+1)) == typeid(token::log)
|| typeid(**(i+1)) == typeid(token::variable))){
tn.token_list.insert(i+1, std::make_unique<token::mul>());
i++;
}
}
}
void parser::make_equation(tokenizer& tn){
if(namely_name == ""){
tn.token_list.emplace_back(std::make_unique<token::eq>());
tn.token_list.emplace_back(std::make_unique<token::variable>("result"));
}
}