=begin pod

=TITLE class Grammar

=SUBTITLE Formal grammar made up of named regexes

    class Grammar is Cursor { ... }

Every type declared with C<grammar> (which doesn't explicitly states its
superclass) becomes a subclass of I<Grammar>.

    grammar Thingy {
        token TOP {
            <a> <b>
        }
        token a { a }
        token b { b }
    }
    say Thingy ~~ Grammar;      # True
    my $match = Thingy.parse('ab');
    say so $match;              # True
    say ~$match<a>;             # a

More L<documentation on grammars|/language/grammars> is available.

=head1 Methods

=head2 method parse

Defined as:

    method parse($target, :$rule = 'TOP',  Capture() :$args = \(), Mu :$actions = Mu, *%opt) {

Usage:

    GRAMMAR.parse(TARGET, RULE?, ARGS?, ACTIONS?, OPTIONS?)

Parses the C<$target> (which will be coerced to L<Str|/type/Str> if it isn't
one), using C<$rule> as the starting rule. Additional C<$args> will be given
to the starting rule if provided.

If the C<action> named argument is provided, it will be used as an action
object, that is, for each successful regex match, a method of the same name
(if it exists) is called on the action object, passing the match object as the
sole positional argument.

Additional named arguments are used as options for matching, so you can
specify things like C<:c(4)> to start parsing from the fourth character. All
L<matching adverbs|/language/regexes#Adverbs> are allowed.

Method C<parse> only succeeds if the cursor has arrived at the end of the
target string when the match is over. Use L<method subparse|/routine/subparse>
if you want to be able to stop in the middle.

Returns a L<Match object|/type/Match> on success, and L<Nil|/type/Nil> on
failure.

    grammar CSV {
        token TOP { [ <line> \n? ]+ }
        token line {
            ^^            # Beginning of a line
            <value>* % \, # Any number of <value>s with commas in between them
            $$            # End of a line
        }
        token value {
            [
            | <-[",\n]>     # Anything not a double quote, comma or newline
            | <quoted-text> # Or some quoted text
            ]*              # Any number of times
        }
        token quoted-text {
            \"
            [
            | <-["\\]> # Anything not a " or \
            | '\"'     # Or \", an escaped quotation mark
            ]*         # Any number of times
            \"
        }
    }.parse( q:to/EOCSV/ ).say;
        Year,Make,Model,Length
        1997,Ford,E350,2.34
        2000,Mercury,Cougar,2.38
        EOCSV

This outputs:

    ｢Year,Make,Model,Length
    1997,Ford,E350,2.34
    2000,Mercury,Cougar,2.38
    ｣
     line => ｢Year,Make,Model,Length｣
      value => ｢Year｣
      value => ｢Make｣
      value => ｢Model｣
      value => ｢Length｣
     line => ｢1997,Ford,E350,2.34｣
      value => ｢1997｣
      value => ｢Ford｣
      value => ｢E350｣
      value => ｢2.34｣
     line => ｢2000,Mercury,Cougar,2.38 ｣
      value => ｢2000｣
      value => ｢Mercury｣
      value => ｢Cougar｣
      value => ｢2.38 ｣

=head2 method subparse

Defined as:

    method subparse($target, :$rule = 'TOP', Capture() :$args = \(),  Mu :$actions = Mu, *%opt) {

Usage:

    GRAMMAR.subparse(TARGET, RULE?, ARGS?, ACTIONS?, OPTIONS?)

Does exactly the same as L<method parse|/routine/parse>, except that cursor
doesn't have to reach the end of the string to succeed. (That is, it doesn't
have to match the whole string).

    grammar A {
        token as { a+ };
    }
    my $match = A.subparse('aaab', :rule<as>);
    say ~$match;        # aaa
    say $match.to;      # 3

=head2 method parsefile

Defined as:

    method parsefile(Str(Cool) $filename, :$enc, *%opts) {

Usage:

    GRAMMAR.parsefile(FILE, OPTIONS?)

Reads file C<$filename>, and parses it. All named arguments are passed on to
L<method parse|/routine/parse>.

=end pod
