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