use 5.010;
use strict;
use warnings;

use YAML;

use Marpa::R2;

# grammar
my $grammar = Marpa::R2::Grammar->new({   
    start   => 'program',
    actions => __PACKAGE__,
    rules   => [
        { lhs => 'program', rhs => ['statement'], min => 1 },

        [ statement => [qw(lhs op rhs separator)] ],

        [ lhs => [qw(identifier)] ],
        [ rhs => [qw(identifier)] ],

        [ separator => [qw(separator_lex)] ],
# the below line
        [ separator => [] ],
# produces:
#   Can't locate object method "xsy_name" via package "Marpa::R2::Grammar" at /usr/lib/perl5/site_perl/5.14/i686-cygwin-threads-64int/Marpa/R2/Value.pm line 493.
# when trying to get the matched rule at line 43 below
# under
#   Marpa-R2-2.020000 
#   perl 5.14.2
#   CYGWIN_NT-5.1 gladius 1.7.16(0.262/5/3) 2012-07-20 22:55 i686 Cygwin
#   winxp pro sp3
# ======================================

    ],
    default_action => 'do_what_I_mean'
});
$grammar->precompute();

sub do_what_I_mean { 

    # get the matched rule's lhs
    my $lhs = ($Marpa::R2::Context::grammar->rule($Marpa::R2::Context::rule))[0];
    
    # handle children
    shift;
    my @children = grep { defined } @_;
    my $result = scalar @children > 1 ? \@children : [ shift @children ];

    # prepend matched rule's lhs to the children
    unshift @$result, $lhs;
    
    $result;
}

# recognizing
my $recognizer = Marpa::R2::Recognizer->new( {  grammar => $grammar } ) or die 'Failed to create recognizer';

for my $token (
# lhs ::= item
    [ qw(   identifier      lhs     )],
    [ qw(   op              ::=     )],
    [ qw(   identifier      item    )],
# the below line, if uncommented, clears the error
#    [ qw(   separator_lex   ;    )],
# end input
    ){
    defined $recognizer->read( @$token ) or say "Recognition failed at ", Dump $token;
}

# evaluation
while ( defined( my $value_ref = $recognizer->value() ) ) {
    my $value = $value_ref ? ${$value_ref} : 'No parse';
    say Dump $value;
}
