-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtokenizer.cpp
123 lines (113 loc) · 3.95 KB
/
tokenizer.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//
// Created by tconto on 7/5/24.
//
#include "tokenizer.h"
#include <string>
#include <vector>
#include <cctype>
#include <unordered_map>
#include <iostream>
std::vector<token> tokenize(const std::string& input) {
std::vector<token> tokens;
std::string number;
if (input.empty()) {
return tokens;
}
std::unordered_map<char, token_t> charToToken = {
{'+', token_t::PLUS},
{'-', token_t::MINUS},
{'*', token_t::MULTIPLY},
{'^', token_t::EXPONENT},
{'/', token_t::DIVIDE},
{'(', token_t::LPAREN},
{')', token_t::RPAREN}
};
for (size_t i = 0; i < input.size(); ++i) {
char c = input[i];
if (std::isdigit(c) || (c == '-' && i + 1 < input.size() && std::isdigit(input[i + 1]))) {
number += c;
} else {
if (!number.empty()) {
tokens.push_back({token_t::NUMBER, number});
number.clear();
}
// if (c == '(') {
// if (i > 0 && (std::isdigit(input[i - 1]) || input[i - 1] == ')')) {
// tokens.push_back({token_t::MULTIPLY, "*"});
// }
// tokens.push_back({token_t::LPAREN, "("});
// } else if (c == ')') {
// tokens.push_back({token_t::RPAREN, ")"});
// if (i + 1 < input.size() && (std::isdigit(input[i + 1]) || input[i + 1] == '(')) {
// tokens.push_back({token_t::MULTIPLY, "*"});
// }
// }
if (charToToken.count(c)) {
tokens.push_back({charToToken[c], std::string(1, c)});
} else if (c == 's' && input.substr(i, 3) == "sin") {
tokens.push_back({token_t::SIN, "sin"});
i += 2;
} else if (c == 'c' && input.substr(i, 3) == "cos") {
tokens.push_back({token_t::COS, "cos"});
i += 2;
} else if (c == 't' && input.substr(i, 3) == "tan") {
tokens.push_back({token_t::TAN, "tan"});
i += 2;
} else if (c == 's' && input.substr(i, 4) == "sqrt") {
tokens.push_back({token_t::SQRT, "sqrt"});
i += 3;
} else if (c == 'l' && input.substr(i, 3) == "log") {
if (i + 3 < input.size() && std::isdigit(input[i + 3])) {
std::string base;
i += 3;
while (i < input.size() && std::isdigit(input[i])) {
base += input[i++];
}
--i; // roll back the last increment
tokens.push_back({token_t::LOG_BASE, base});
} else {
tokens.push_back({token_t::LOG, "log"});
i += 2;
}
} else if (c == 'a' && input.substr(i, 3) == "abs") {
tokens.push_back({token_t::ABS, "abs"});
i += 2;
} else if (!std::isspace(c)) {
tokens.push_back({token_t::UNKNOWN, std::string(1, c)});
}
}
}
if (!number.empty()) {
tokens.push_back({token_t::NUMBER, number});
}
return tokens;
}
std::string tokenTypeToString(token_t type) {
switch (type) {
case token_t::NUMBER:
return "NUMBER";
case token_t::PLUS:
return "PLUS";
case token_t::MINUS:
return "MINUS";
case token_t::MULTIPLY:
return "MULTIPLY";
case token_t::DIVIDE:
return "DIVIDE";
case token_t::LPAREN:
return "LPAREN";
case token_t::RPAREN:
return "RPAREN";
case token_t::EXPONENT:
return "EXPONENT";
case token_t::SIN:
return "SIN";
case token_t::COS:
return "COS";
case token_t::TAN:
return "TAN";
case token_t::UNKNOWN:
default:
return "UNKNOWN";
}
}