-
Notifications
You must be signed in to change notification settings - Fork 0
/
scanner.dart
81 lines (74 loc) · 1.75 KB
/
scanner.dart
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
part of notex2;
/**
* トークンリーダ
*/
class Scanner {
List<Token> tokens;
int pos = -1;
Scanner(List<Token> tokens) {
this.tokens = tokens;
}
/**
* 指定された位置にあるトークンを読み出します。
*/
Token pick(int pos) {
if (pos >= this.tokens.length) {
Token token = new Token();
token.token = 'null';
token.lexeme = '';
return token;
//throw new Exception("Reader over");
} else if (pos == -1) {
Token token = new Token();
token.id = -1;
token.token = 'newline';
token.lexeme = '\n';
return token;
} else if (pos < 0) {
Token token = new Token();
token.token = 'null';
token.lexeme = '';
return token;
//throw new Exception("Reader over");
} else {
return this.tokens[pos];
}
}
/**
* トークンリーダを指定した分だけ進めます。
*/
void next([int step = 1]) {
this.pos += step;
}
/**
* トークンリーダを指定した分だけ巻き戻します。
*/
void back([int step = 1]) {
this.pos -= step;
}
/**
* 現在のトークンリーダの位置にあるトークンを読み出します。
*/
Token read([int relative_pos = 0]) {
int pos = this.pos + relative_pos;
return this.pick(pos);
}
/**
* ソースを走査します。トークンに出会う度に指定されたスキャナが呼ばれます。
* スキャナが [true] を返した場合、そこで直ちに走査は終了し、関数が終了します。
*/
void scan(bool scanner(Token token), [scanEnd()]) {
while ((this.pos) < this.tokens.length) {
Token token = this.read();
//print(token);
if (scanner(token) == true) {
break;
}
}
if (scanEnd != null) {
if (this.pos >= (this.tokens.length - 1)) {
scanEnd();
}
}
}
}