Generación interactiva de analizadores Yapp

En el siguiente código, la subrutina create_yapp_package nos muestra como crear un analizador Yapp en tiempo de ejecución. Las dos líneas:
  my $p = new Parse::Yapp(input => $grammar);
  $p = $p->Output(classname => $name);
crean una cadena en $p conteniendo el código de la clase que implanta el analizador. Todo el truco está en hacer
  eval $p;
para tener el paquete a mano:
$ cat left.pl
#!/usr/local/bin/perl5.8.0 -w
#use strict;
use Parse::Yapp;

sub lex{
    my($parser)=shift;

    return('',undef) unless $parser->YYData->{INPUT};
    for ($parser->YYData->{INPUT}) {
        s/^\s*//;
        s/^(.)//;
        my $ret = $1;
        return($ret, $ret);
    }
}

sub yapp {
  my $grammar = shift
     or die "Must specify a grammar as first argument";
  my $name = shift
     or die "Must specify the name of the class as second argument";

  my $p = new Parse::Yapp(input => $grammar) or die "Bad grammar.";
  $p = $p->Output(classname => $name) or die "Can't generate parser.";

  eval $p;
  $@ and die "Error while compiling your parser: $@\n";
}

######## main #########
my $grammar = q {
%left '*'
%%
S:  A
;

A:  A '*' A  { "($_[1] $_[2] $_[3])" }
 |  B
;

B:  'a' | 'b' | 'c' | 'd'
;

%%
};

&yapp($grammar, "Example");
my $p = new Example(yylex => \&lex, yyerror => sub {});

print "Expresion: ";
$p->YYData->{INPUT} = <>;
$p->YYData->{INPUT} =~ s/\s*$//;

my $out=$p->YYParse;
print "out = $out\n";
Sigue un ejemplo de ejecución:
$ ./left.pl
Expresion: a*b*c*d
out = (((a * b) * c) * d)

Casiano Rodríguez León
2013-04-23