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