progress<T> function Null safety

Parser<T> progress<T>(
  1. Parser<T> root,
  2. {VoidCallback<ProgressFrame> output = print,
  3. Predicate<Parser>? predicate}
)

Returns a transformed Parser that when being used to read input visually prints its progress while progressing.

For example, the snippet

final parser = letter() & word().star();
progress(parser).parse('f123');

prints the following output:

* Instance of 'SequenceParser'
* Instance of 'CharacterParser'[letter expected]
** Instance of 'PossessiveRepeatingParser'[0..*]
** Instance of 'CharacterParser'[letter or digit expected]
*** Instance of 'CharacterParser'[letter or digit expected]
**** Instance of 'CharacterParser'[letter or digit expected]
***** Instance of 'CharacterParser'[letter or digit expected]

Jumps backwards mean that the parser is back-tracking. Often choices can be reordered to avoid such expensive parses.

The optional output callback can be used to continuously receive ProgressFrame updates with the current progress information.

Implementation

Parser<T> progress<T>(Parser<T> root,
    {VoidCallback<ProgressFrame> output = print,
    Predicate<Parser>? predicate}) {
  return transformParser(root, <T>(parser) {
    if (predicate == null || predicate(parser)) {
      return parser.callCC((continuation, context) {
        output(_ProgressFrame(parser, context));
        return continuation(context);
      });
    } else {
      return parser;
    }
  });
}