=head1 NAME

Parser::MGC::Tutorial

=head1 INTRODUCTION

L<Parser::MGC> is an abstract base class that provides useful features to
assist writing a parser.

A parser written using this module will be a subclass of C<Parser::MGC>, which
provides a C<parse> method. For example, the following trivial parser accepts
only input content matching the given regexp.

 package ExampleParser;
 use base qw( Parser::MGC );

 sub parse
 {
    my $self = shift;

    $self->expect( qr/hello world/i );

    return 1;
 }

A program using this parser constructs an instance of it, and uses this
instance to parse content. Content is passed either as string value to the
C<from_string> method, or from a named file or filehandle to the C<from_file>
method.

 use feature qw( say );
 use ExampleParser;

 my $parser = ExampleParser->new;

 say $parser->from_string( "Hello World" );

When run, this program outputs the return value of the C<from_string> method,
which itself is the value returned by the C<parse> method.

 $ perl tut01.pl
 1

Content can also be provided by C<from_file> instead:

 use feature qw( say );
 use ExampleParser;

 my $parser = ExampleParser->new;

 say $parser->from_file( \*STDIN );

=head2 Returning Values

Of course, a parser that simply returns 1 to say it matches may not be all
that useful. Almost always when a parser is being used to match some input, it
is because some values or structure are needed from this input, which should
be returned to the caller.

The C<expect> method attempts to match the next part of the input string with
the given regexp, and returns the matching substring. A subsequent C<expect>
call will continue parsing where the previous one finished. C<Parser::MGC>
will automatically skip over whitespace between these calls, so most grammars
that are whitespace-insensitive should not need to worry about this
explicitly.

By using two C<expect> calls, a parser can first examine that some given
literal is present, and then return a matched substring from the input.

 sub parse
 {
    my $self = shift;

    $self->expect( qr/hello/i );
    my $name = $self->expect( qr/\w+/ );

    return $name;
 }

Z<>

 say $parser->from_string( "Hello World" );

Z<>

 $ perl tut02.pl
 World

Token methods make this easier by providing convenient shortcuts to
commonly-used matching patterns.

 sub parse
 {
    my $self = shift;

    $self->expect( qr/hello/i );
    return $self->token_ident;
 }

If instead we pass in a value that does not match the regexp, an exception is
thrown, including details of how the parse failed.

 say $parser->from_string( "Hello, world!" );

Z<>

 $ perl tut03.pl
 Expected (?i-xsm:hello world) on line 1 at:
 Hello, world!
 ^

A typical use of a parser is to form an Abstract Syntax Tree (AST) from a
given input. In this case it is likely that the return value from the parse
method will be some object the application can use to inspect the syntax.

 sub parse
 {
    my $self = shift;

    my $num = $self->token_number;
    return MyGrammar::Expression::Number->new( $num );
 }

=head2 Indicating Failure

While the basic methods such as C<expect> and the varions token methods will
indicate a failure automatically, there may be cases in the grammar that more
logic is required by the parser. If this logic wishes to indicate a failure in
the input and cause back-tracking to occur, it can use the C<fail> method.

 sub parse
 {
    my $self = shift;

    my $num = $self->token_number;
    $num >= 0 or $self->fail( "Expected a non-negative number" );

    return $num;
 }

=head2 Structure

So far we've managed to parse simple patterns that could have been specified
with a simple regular expression. Any parser for a nontrivial grammar will
need other abilities as well; it will need to be able to choose from a list of
alternatives, to be able to repeat patterns, and to form nested scopes to
match other content within.

C<Parser::MGC> provides a set of methods that take one or more C<CODE>
references that perform some parsing step, and form a higher-level
construction out of them. These can be used to build more complex parsers out
of simple ones. It is this recursive structure that gives C<Parser::MGC> its
main power over simple one-shot regexp matching.

Any nontrivial grammar is likely to be formed from multiple named rules. It is
natural therefore to split the parser for such a grammar into methods whose
names reflect the structure of the grammar to be parsed. Each of the
structure-forming methods which takes C<CODE> references invokes each by
passing in the parser object itself as the first argument. This makes it
simple to invoke sub-rules by passing references to method subs themselves,
because the parser object will already be passed as the invocant.

The following examples will build together into a parser for a simple C-like
expression language.

=head3 Optional Rules

The simplest of the structure-forming methods, C<maybe>, attempts to run the
parser step it is given and if it succeeds, returns the value returned by that
step. If it fails by throwing an exception, then the C<maybe> call simply
returns C<undef> and resets the current parse position back to where it was
before it started. This allows writing a grammar that includes an optional
element, similar to the C<?> quantifier in a regular expression.

 sub parse_type
 {
    my $self = shift;

    my $storage = $self->maybe( sub {
       $self->token_kw(qw( static auto typedef ));
    } );

    return MyGrammar::Type->new( $self->parse_ident, $storage );
 }


I<TODO: This document remains incomplete; but I am releasing it for now as it's still useful for what exists.>
