-
Notifications
You must be signed in to change notification settings - Fork 39
/
Copy pathblock_parser.dart
70 lines (63 loc) · 1.79 KB
/
block_parser.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
import '../ast/block.dart';
import '../ast/exp.dart';
import '../ast/stat.dart';
import '../lexer/lexer.dart';
import '../lexer/token.dart';
import 'exp_parser.dart';
import 'stat_parser.dart';
class BlockParser {
// block ::= {stat} [retstat]
static Block parseBlock(Lexer lexer) {
Block block = Block(stats: parseStats(lexer), retExps: parseRetExps(lexer));
block.lastLine = lexer.line;
return block;
}
static List<Stat> parseStats(Lexer lexer) {
List<Stat> stats = <Stat>[];
while (!_isReturnOrBlockEnd(lexer.LookAhead())) {
Stat stat = StatParser.parseStat(lexer);
if (!(stat is EmptyStat)) {
stats.add(stat);
}
}
return stats;
}
static bool _isReturnOrBlockEnd(TokenKind? kind) {
switch (kind) {
case TokenKind.TOKEN_KW_RETURN:
case TokenKind.TOKEN_EOF:
case TokenKind.TOKEN_KW_END:
case TokenKind.TOKEN_KW_ELSE:
case TokenKind.TOKEN_KW_ELSEIF:
case TokenKind.TOKEN_KW_UNTIL:
return true;
default:
return false;
}
}
// retstat ::= return [explist] [‘;’]
// explist ::= exp {‘,’ exp}
static List<Exp>? parseRetExps(Lexer lexer) {
if (lexer.LookAhead() != TokenKind.TOKEN_KW_RETURN) {
return null;
}
lexer.nextToken();
switch (lexer.LookAhead()) {
case TokenKind.TOKEN_EOF:
case TokenKind.TOKEN_KW_END:
case TokenKind.TOKEN_KW_ELSE:
case TokenKind.TOKEN_KW_ELSEIF:
case TokenKind.TOKEN_KW_UNTIL:
return const <Exp>[];
case TokenKind.TOKEN_SEP_SEMI:
lexer.nextToken();
return const <Exp>[];
default:
List<Exp> exps = ExpParser.parseExpList(lexer);
if (lexer.LookAhead() == TokenKind.TOKEN_SEP_SEMI) {
lexer.nextToken();
}
return exps;
}
}
}