This repository was archived by the owner on Sep 11, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtokenizer.cpp
More file actions
91 lines (85 loc) · 2.78 KB
/
Copy pathtokenizer.cpp
File metadata and controls
91 lines (85 loc) · 2.78 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
89
90
91
#include "./tokenizer.h"
#include <cctype>
#include <set>
#include <stdexcept>
#include "./error.h"
const std::set<char> TOKEN_END{'(', ')', '\'', '`', ',', '"'};
TokenPtr Tokenizer::nextToken(int& pos) {
while (pos < input.size()) {
auto c = input[pos];
if (c == ';') {
while (pos < input.size() && input[pos] != '\n') {
pos++;
}
} else if (std::isspace(c)) {
pos++;
} else if (auto token = Token::fromChar(c)) {
pos++;
return token;
} else if (c == '#') {
if (auto result = BooleanLiteralToken::fromChar(input[pos + 1])) {
pos += 2;
return result;
} else {
throw SyntaxError("Unexpected character after #");
}
} else if (c == '"') {
std::string string;
pos++;
while (pos < input.size()) {
if (input[pos] == '"') {
pos++;
return std::make_unique<StringLiteralToken>(string);
} else if (input[pos] == '\\') {
if (pos + 1 >= input.size()) {
throw SyntaxError("Unexpected end of string literal");
}
auto next = input[pos + 1];
if (next == 'n') {
string += '\n';
} else {
string += next;
}
pos += 2;
} else {
string += input[pos];
pos++;
}
}
throw SyntaxError("Unexpected end of string literal");
} else {
int start = pos;
do {
pos++;
} while (pos < input.size() && !std::isspace(input[pos]) &&
!TOKEN_END.contains(input[pos]));
auto text = input.substr(start, pos - start);
if (text == ".") {
return Token::dot();
}
if (std::isdigit(text[0]) || text[0] == '+' || text[0] == '-' || text[0] == '.') {
try {
return std::make_unique<NumericLiteralToken>(std::stod(text));
} catch (std::invalid_argument& e) {
}
}
return std::make_unique<IdentifierToken>(text);
}
}
return nullptr;
}
std::deque<TokenPtr> Tokenizer::tokenize() {
std::deque<TokenPtr> tokens;
int pos = 0;
while (true) {
auto token = nextToken(pos);
if (!token) {
break;
}
tokens.push_back(std::move(token));
}
return tokens;
}
std::deque<TokenPtr> Tokenizer::tokenize(const std::string& input) {
return Tokenizer(input).tokenize();
}