blob: 6f590eda179bd10a68dc7326d46cfa6c903b6ea1 [file] [log] [blame] [edit]
import '../core/parser.dart';
/// Returns a lazy iterable over all parsers reachable from [root] using
/// a [depth-first traversal](https://en.wikipedia.org/wiki/Depth-first_search)
/// over the connected parser graph.
///
/// For example, the following code prints the two parsers of the
/// defined grammar:
///
/// final parser = range('0', '9').star();
/// allParser(parser).forEach((each) {
/// print(each);
/// });
///
Iterable<Parser> allParser(Parser root) => _ParserIterable(root);
class _ParserIterable extends Iterable<Parser> {
_ParserIterable(this.root);
final Parser root;
@override
Iterator<Parser> get iterator => _ParserIterator(root);
}
class _ParserIterator extends Iterator<Parser> {
_ParserIterator(Parser root)
: todo = [root],
seen = {root};
final List<Parser> todo;
final Set<Parser> seen;
@override
late Parser current;
@override
bool moveNext() {
if (todo.isEmpty) {
seen.clear();
return false;
}
current = todo.removeLast();
for (final parser in current.children.reversed) {
if (seen.add(parser)) {
todo.add(parser);
}
}
return true;
}
}