The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!/usr/bin/perl -w
use strict;
use Data::Dumper;
use Test::More tests => 3;
use_ok qw(Parse::Eyapp) or exit;

my $translationscheme = q{
%{
#use Data::Dumper;
%}

%metatree

%left   '-' '+'
%left   '*' 
%left   NEG

%%
line:       %name EXP  
              $exp 
                { $_[0]->{s} = $exp->{s}."\n"; $_[0]->{n} = $exp->{n}; }
;

exp:    
            %name PLUS  
              exp.left 
                      { 
                        $_[0]->{s} = "PLUS ". $left->{n}."\n" 
                      } 
              '+'    
                      { $_[0]->{s} .= "after plus ".$left->{n}."\n" } 
              exp.right         
                      { 
                        $_[0]->{s} .= $left->{s} . $right->{s};
                        $_[0]->{n} .= $left->{n} + $right->{n} 
                      }
        |   %name TIMES 
              exp.left '*' exp.right         
                { 
                  $_[0]->{n} = $left->{n} * $right->{n} 
                }
        |   %name NUM   $NUM                 
              { 
                $_[0]->{s} = $NUM->{attr}." "; 
                $_[0]->{n} = $NUM->{attr} 
              }
        |   %name PAREN  '(' $exp ')'        
              { 
                $_[0]->{s} = " ( $exp->{s} )"; 
                $_[0]->{n} = $exp->{n} 
              }
        |   exp.left '-' exp.right         
              { $_[0]->{n} = $left->{n} - $right->{n} }

        |   '-' $exp %prec NEG   
              { $_[0]->{n} = -$exp->{n} }
;

%%

sub _Error {
        exists $_[0]->YYData->{ERRMSG}
    and do {
        print $_[0]->YYData->{ERRMSG};
        delete $_[0]->YYData->{ERRMSG};
        return;
    };
    print "Syntax error.\n";
}

sub _Lexer {
    my($parser)=shift;

        $parser->YYData->{INPUT}
    or  return('',undef);

    $parser->YYData->{INPUT}=~s/^\s*//;

    for ($parser->YYData->{INPUT}) {
        s/^([0-9]+(?:\.[0-9]+)?)//
                and return('NUM',$1);
        s/^([A-Za-z][A-Za-z0-9_]*)//
                and return('VAR',$1);
        s/^(.)//
                and return($1,$1);
        s/^\s*//;
    }
}

sub Run {
    my($self)=shift;
    return $self->YYParse( yylex => \&_Lexer, yyerror => \&_Error );
}
}; # end translation scheme

$Data::Dumper::Indent = 1;
$Data::Dumper::Terse = 1;
$Data::Dumper::Deepcopy  = 1;
Parse::Eyapp->new_grammar(input=>$translationscheme,
  classname=>'main', 
  firstline => 7, 
  ); #outputfile => 'main.pm');
my $parser = main->new();
$parser->YYData->{INPUT} = "2+(3)";
my $t = $parser->Run() or die "Syntax Error analyzing input";
$t->translation_scheme;
#print Dumper($t);
my $expected_result =<<"ENDOFEXPECTED";
PLUS 2
after plus 2
2  ( 3  )
ENDOFEXPECTED
is($t->{s},$expected_result, "intermediate actions");
is($t->{n}, 5, "plus");
#print "Resultado $t->{s}\n";