OLD | NEW |
| (Empty) |
1 part of reflection; | |
2 | |
3 /** | |
4 * Returns a lazy iterable over all parsers reachable from a [root]. | |
5 * | |
6 * For example, the following code prints the two parsers of the | |
7 * defined grammar: | |
8 * | |
9 * var parser = range('0', '9').star(); | |
10 * allParser(parser).forEach((each) { | |
11 * print(each); | |
12 * }); | |
13 * | |
14 */ | |
15 Iterable<Parser> allParser(Parser root) => new _ParserIterable(root); | |
16 | |
17 class _ParserIterable extends IterableBase<Parser> { | |
18 final Parser root; | |
19 | |
20 _ParserIterable(this.root); | |
21 | |
22 @override | |
23 Iterator<Parser> get iterator => new _ParserIterator([root]); | |
24 } | |
25 | |
26 class _ParserIterator implements Iterator<Parser> { | |
27 final List<Parser> todo; | |
28 final Set<Parser> seen; | |
29 | |
30 _ParserIterator(Iterable<Parser> roots) | |
31 : todo = new List.from(roots), | |
32 seen = new Set.from(roots); | |
33 | |
34 @override | |
35 Parser current; | |
36 | |
37 @override | |
38 bool moveNext() { | |
39 if (todo.isEmpty) { | |
40 current = null; | |
41 return false; | |
42 } | |
43 current = todo.removeLast(); | |
44 for (var parser in current.children) { | |
45 if (!seen.contains(parser)) { | |
46 todo.add(parser); | |
47 seen.add(parser); | |
48 } | |
49 } | |
50 return true; | |
51 } | |
52 } | |
OLD | NEW |