The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
# Marpa::R3 is Copyright (C) 2017, Jeffrey Kegler.
#
# This module is free software; you can redistribute it and/or modify it
# under the same terms as Perl 5.10.1. For more details, see the full text
# of the licenses in the directory LICENSES.
#
# This program is distributed in the hope that it will be
# useful, but it is provided "as is" and without any express
# or implied warranties. For details, see the full text of
# of the licenses in the directory LICENSES.

=head1 NAME

Marpa::R3::Tracing - Tracing your grammar

=head1 Description

This document is an overview of
the techniques for tracing and
debugging parses and grammars using Marpa's SLIF interface.

=head1 Basic techniques

=head2 Check the input location where parsing failed

If parsing failed in the recognizer,
look at the input location where it happened.
Compare the input against the grammar.
This step is fairly obvious,
but I include it because
even experts (actually, especially experts)
will sometimes overlook the obvious
in a rush to use more advanced techniques.

=head2 Dump the parse value

Sometimes, even when there is a parse error, you can still evaluate the parse
using the L<SLIF recognizer's C<value()>
method|Marpa::R3::Scanless::R/"value()">.
If you are fortunate enough to have a parse value at the point of failure,
it can be an excellent way
to determine what the parser thinks it has seen so far.
It is more likely that there will be a parse value if you are
using incremental development,
and the parse values will be especially helpful
if your parse values are AST's.

If you are trying to run diagnostics on a failed parse,
it is useful to catch the exception using C<eval>:

=for Marpa::R3::Display:
name: SLIF debug example, part 2
partial: 1
normalize-whitespace: 1

    my $eval_error = $EVAL_ERROR if not eval { $recce->read( \$test_input ); 1 };
    $progress_report = $recce->progress_show( 0, -1 );

=for Marpa::R3::Display::End

=head2 Trace terminals

Set the L<C<trace_terminals> recognizer named
argument|Marpa::R3::Scanless::R/"trace_terminals">
to 1.
This tells you which tokens the recognizer is looking for and which ones it thinks it found.
If the problem is in lexing, C<trace_terminals> tells you the whole story.
Even if the problem is not in the lexing,
tracing terminals can tell you a lot.

=head2 Trace progress

Tracing the recognizer's progress
with
C<progress_show>
is the most powerful tool available
in the basic toolkit.
C<progress_show>
should provide all the
information necessary to
debug an application's grammar.
L<A separate document|Marpa::R3::Progress>
explains how to interpret the progress reports.
That document includes an
example of the use of C<progress_show>
to debug an error in a grammar.

=head2 Double check rules and symbols

It sometimes helps to look carefully at the output of
L<C<symbols_show>|Marpa::R3::Scanless::G/"symbols_show()">
and
L<C<productions_show>|Marpa::R3::Scanless::G/"productions_show()">.
Check if anything there is
not what you expected.
For thorough checking, it can be helpful to use a
verbosity level higher than 1.

=head2 Other traces

Setting the L<SLIF recognizer's C<trace_values> named argument|Marpa::R3::Scanless::R/"trace_values">
to a trace level of 1
traces the values of the parse tree nodes as they are pushed on, and
popped off, the evaluation stack.

=head2 Basic checklist

A full investigation of a parse
includes the following:

=over 4

=item * Of course, the error message.

=item * If the failed parse returns a value, a dump of that value.

=item * Set the
L<SLIF recognizer's C<trace_terminals> named
argument|Marpa::R3::Scanless::R/"trace_terminals">
to level 1.

=item * Run
L<C<productions_show>|Marpa::R3::Scanless::G/"productions_show()">
on the SLIF grammar.

=item * Run
L<C<symbols_show>|Marpa::R3::Scanless::G/"symbols_show()">
on the SLIF grammar.

=item * Run
L<C<progress_show()>|Marpa::R3::Progress>
on the SLIF recognizer.

=back

When considering how much tracing to turn on,
remember that if the input text to the grammar is large,
the outputs from
C<trace_terminals>,
C<progress_show>,
and C<trace_values>,
and the dump of the parse value,
can be very lengthy.
You want to work with short inputs when possible.

=head1 COPYRIGHT AND LICENSE

=for Marpa::R3::Display
ignore: 1

  Marpa::R3 is Copyright (C) 2017, Jeffrey Kegler.

  This module is free software; you can redistribute it and/or modify it
  under the same terms as Perl 5.10.1. For more details, see the full text
  of the licenses in the directory LICENSES.

  This program is distributed in the hope that it will be
  useful, but without any warranty; without even the implied
  warranty of merchantability or fitness for a particular purpose.

=for Marpa::R3::Display::End

=cut

# vim: expandtab shiftwidth=4: