profile<R> function

  1. @useResult
Parser<R> profile<R>(
  1. Parser<R> root, {
  2. VoidCallback<ProfileFrame> output = print,
  3. Predicate<Parser>? predicate,
})

Returns a transformed Parser that when being used measures the activation count and total time of each parser.

For example, the snippet

final parser = letter() & word().star();
profile(parser).parse('f1234567890');

prints the following output:

 1  2006  SequenceParser
 1   697  PossessiveRepeatingParser[0..*]
11   406  SingleCharacterParser[letter or digit expected]
 1   947  SingleCharacterParser[letter expected]

The first number refers to the number of activations of each parser, and the second number is the microseconds spent in this parser and all its children.

The optional output callback can be used to receive ProfileFrame objects with the full profiling information at the end of the parse.

Implementation

@useResult
Parser<R> profile<R>(Parser<R> root,
    {VoidCallback<ProfileFrame> output = print, Predicate<Parser>? predicate}) {
  final frames = <ProfileFrame>[];
  return transformParser(root, <R>(parser) {
    if (predicate == null || predicate(parser)) {
      final frame = _ProfileFrame(parser);
      frames.add(frame);
      return parser.callCC((continuation, context) {
        frame.count++;
        frame.stopwatch.start();
        final result = continuation(context);
        frame.stopwatch.stop();
        return result;
      });
    } else {
      return parser;
    }
  }).callCC((continuation, context) {
    final result = continuation(context);
    frames.forEach(output);
    return result;
  });
}