Repository navigation
Expand file tree
/
Copy pathlexer.cpp
More file actions
80 lines (71 loc) · 2.94 KB
/
Copy pathlexer.cpp
File metadata and controls
80 lines (71 loc) · 2.94 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
#include "../include/Lexer.hpp"
#include "../include/Errors.hpp"
std::optional<TokenType> Lexer::check(std::string word){
for(char &c: word)
c = static_cast<char>(std::toupper((unsigned char)c));
if(keywordTable.contains(word)){
return keywordTable[word];
}
return std::nullopt;
}
std::vector<Token> Lexer::tokenize( std::string query) {
std::vector<Token> tokens;
size_t i = 0;
const size_t n = query.size();
while (i < n) {
char c = query[i];
if (std::isspace((unsigned char)c)) { i++; continue; }
size_t start = i;
if (std::isalpha((unsigned char)c) || c == '_') {
while (i < n && (std::isalnum((unsigned char)query[i]) || query[i] == '_'))
i++;
std::string word = query.substr(start, i - start);
auto kw = check(word);
if (kw.has_value())
tokens.push_back({kw.value(), word, start});
else {
for (char& ch : word)
ch = static_cast<char>(std::tolower((unsigned char)ch));
tokens.push_back({TokenType::IDENTIFIER, word, start});
}
}
else if (std::isdigit((unsigned char)c)) {
bool seenDot = false;
while (i < n && (std::isdigit((unsigned char)query[i]) ||
(query[i] == '.' && !seenDot && i + 1 < n &&
std::isdigit((unsigned char)query[i + 1])))) {
if (query[i] == '.') seenDot = true;
i++;
}
tokens.push_back({TokenType::NUMBER, query.substr(start, i - start), start});
}
else if (c == '\'') {
size_t close = query.find('\'', i + 1);
if (close == std::string::npos)
throw LexicalError("unterminated string literal", start);
tokens.push_back({TokenType::STRING,
query.substr(i + 1, close - i - 1),
start});
i = close + 1;
}
else if (c == '<' || c == '>' || c == '=') {
if (i + 1 < n && (query.substr(i, 2) == "<=" ||
query.substr(i, 2) == ">=" ||
query.substr(i, 2) == "<>")) {
tokens.push_back({TokenType::COMPARATOR, query.substr(i, 2), start});
i += 2;
} else {
tokens.push_back({TokenType::COMPARATOR, std::string(1, c), start});
i += 1;
}
}
else if (c == ',') { tokens.push_back({TokenType::COMMA, ",", start}); i++; }
else if (c == '*') { tokens.push_back({TokenType::STAR, "*", start}); i++; }
else if (c == '.') { tokens.push_back({TokenType::DOT, ".", start}); i++; }
else {
throw LexicalError(std::string("unexpected character '") + c + "'", start);
}
}
tokens.push_back({TokenType::END, "", n});
return tokens;
}