-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTokenList.cpp
138 lines (119 loc) · 2.98 KB
/
TokenList.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include "TokenList.h"
#include "Error.h"
#include <fstream>
#include <iostream>
TokenList::TokenList(const string& filename){
ifstream ifs(filename);
if(ifs.fail()){
throw FileNotFoundError("Can't open source file");
}
char c;
string buf;
bool line_comment_mode = false;
int line = 1, count = 1;
while(ifs.get(c)){
// 改行文字があれば1行コメント終了
if(c == '\n'){
line_comment_mode = false;
}
if(line_comment_mode) goto end_of_while;
if(c == '\n'){
add(buf, line, count);
buf = "";
}
else{
buf += c;
}
// コメント
if(buf == "//"){
buf = "";
line_comment_mode = true;
}
end_of_while:
if(c == '\n'){
line++;
count = 1;
}
else{
count++;
}
}
add(buf, line, count);
}
Token TokenList::current() const{
if(has_current())
return tokens[index];
else
return Token();
}
Token TokenList::next(const int i) const{
if(has_next(i))
return tokens[index + i];
else
return Token();
}
bool TokenList::has_current() const{
return 0 <= index && index < tokens.size();
}
bool TokenList::has_next(const int i) const{
return 0 <= index + i && index + i < tokens.size();
}
void TokenList::advance(){
if(index < tokens.size()){
index++;
}
}
size_t TokenList::size() const{
return tokens.size();
}
bool TokenList::is_statement_start() const{
Token token = current();
return
token.id == Token::Id::sident ||
token.is_type_name() ||
token.is_literal() ||
token.is_control() ||
token.is_loop_control() ||
token.id == Token::Id::sreturn;
}
Token& TokenList::operator[](const int n){
return tokens[n];
}
TokenList::iterator TokenList::begin() const noexcept{
return tokens.begin();
}
TokenList::iterator TokenList::end() const noexcept{
return tokens.end();
}
void TokenList::add(string buf, int line, int count){
while(true){
Token token = find_token(buf, line, count);
if(token.id != Token::Id::error){
tokens.push_back(token);
}
else if(buf != ""){
// 字句解析エラー
cout << "Tokenize Error: '" << buf << "'" << endl;
return;
}
else{
break;
}
}
}
Token TokenList::find_token(string& str, int line, int count) const{
// 先頭の空白は読み飛ばす
while(str.size() > 0 && str[0] == ' '){
str = str.substr(1);
}
for(int pos = str.size() - 1; pos >= 0; pos--){
Token token(str.substr(0, pos + 1));
if(token.id != Token::Id::error){
str = str.substr(pos + 1);
token.line = line;
token.count = count - str.size() - token.str.size();
return token;
}
}
return Token("");
}