-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlexer.cpp
104 lines (88 loc) · 2.39 KB
/
lexer.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
#include "lexer.hpp"
#include <fstream>
#include <iostream>
void Lexer::lexicalAnalysis() {
std::ifstream ifs(input_filename);
if (!ifs) {
exit(1);
}
std::string cur_line;
while (getline(ifs, cur_line)) {
int idx = 0;
while (idx < cur_line.length()) {
auto next_token = read(cur_line, idx);
token_stream.push_back(std::move(next_token));
}
}
token_stream.push_back(std::make_unique<Token>(TOK_EOF, ""));
}
std::unique_ptr<Token> Lexer::read(const std::string& cur_line, int& idx) {
std::string token_str;
char next_char;
// skip whitespace
next_char = cur_line.at(idx);
while (isspace(next_char)) {
idx++;
next_char = cur_line.at(idx);
}
// EOF
if (next_char == EOF) return std::make_unique<Token>(TOK_EOF, token_str);
// identifier
if (isalpha(next_char)) {
token_str += next_char;
idx++;
if (idx == cur_line.length()) {
return std::make_unique<Token>(TOK_IDENTIFIER, token_str);
}
next_char = cur_line.at(idx);
while (isalnum(next_char)) {
token_str += next_char;
idx++;
if (idx == cur_line.length()) break;
next_char = cur_line.at(idx);
}
if (token_str == "def") {
return std::make_unique<Token>(TOK_DEF, token_str);
} else {
return std::make_unique<Token>(TOK_IDENTIFIER, token_str);
}
}
// number
if (isdigit(next_char)) {
token_str += next_char;
if (next_char == '0') return std::make_unique<Token>(TOK_NUMBER, token_str);
idx++;
if (idx == cur_line.length()) {
return std::make_unique<Token>(TOK_NUMBER, token_str);
}
next_char = cur_line.at(idx);
while (isdigit(next_char)) {
token_str += next_char;
idx++;
if (idx == cur_line.length()) break;
next_char = cur_line.at(idx);
}
return std::make_unique<Token>(TOK_NUMBER, token_str);
}
// Symbol
token_str += next_char;
idx++;
return std::make_unique<Token>(mapStringToTokenType(token_str), token_str);
}
Token* Lexer::getCurToken() { return token_stream[cur_index].get(); }
Token* Lexer::getNextToken() {
if (cur_index == token_stream.size() - 1) {
return nullptr;
} else {
cur_index++;
return getCurToken();
}
}
Token::Token(TokenType type, std::string str)
: token_type(type), token_string(str) {
if (type == TOK_NUMBER) {
number = atoi(str.c_str());
} else {
number = std::numeric_limits<int>::max();
}
}