The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
%{
=head1 SYNOPSIS

This example illustrate how the C<%tree> directive is implemented.

Compile it with:

        eyapp Rule3

run:

       ./userule3.pl

give as input a valid expression like C<a=2*3>

=cut

use Data::Dumper;
$Data::Dumper::Indent=1;
sub build_node { 
  my $self = shift;
  my @children = @_;
  my @right = $self->YYRightside();
  my $var = $self->YYLhs;
  my $rule = $self->YYRuleindex();

  for(my $i = 0; $i < @right; $i++) {
    $_ = $right[$i];
    if ($self->YYIsterm($_)) {
      $children[$i] = bless { token => $_, attr => $children[$i] }, __PACKAGE__.'::TERMINAL';
    }
  }
  bless { children => \@children, info => "$var -> @right" }, __PACKAGE__."::${var}_$rule" 
}
%}

%incremental lexer 'Try a valid expression like "a = b*2": '
%whites /([ \t]+)/
%token NUM = /([0-9]+(?:\.[0-9]+)?)/
%token VAR = /([A-Za-z][A-Za-z0-9_]*)/

%right  '='
%left   '-' '+'
%left   '*' '/'
%left   NEG

%defaultaction { build_node(@_) }

%%
input:                 { } 
        |   input line { }
;

line:     '\n'       { } 
        | exp '\n'   { print Dumper($_[1]);  } 
        | error '\n' { $_[0]->YYErrok; }
;

exp:        NUM    
        |   VAR   
        |   VAR '=' exp         
        |   exp '+' exp         
        |   exp '-' exp        
        |   exp '*' exp       
        |   exp '/' exp      
        |   '-' exp %prec NEG 
        |   '(' exp ')'  { $_[2] } /* Let us simplify a bit the tree */
;

%%