Las acción por defecto (en yacc $$ = $1
) puede ser modificada
de manera parecida a como lo hace la variable $::RD_AUTOACTION
en
Parse::RecDescent
usando la directiva %defaultaction
:
%defaultaction { perl code }
El código especificado en la acción por defecto se ejecutará siempre que se produzca una reducción por una regla en la que no se haya explicitado código.
El siguiente ejemplo traduce una expresión en infijo
como a=b*-3
a una en postfijo como a b 3 NEG * =
:
# File Postfix.yp %right '=' %left '-' '+' %left '*' '/' %left NEG %{ use IO::Interactive qw(interactive); %} %defaultaction { my $self = shift; return "$_[0]" if (@_==1); # NUM and VAR return "$_[0] $_[2] $_[1]" if (@_==3); # other operations die "Fatal Error\n"; } %% line: (exp { print "$_[1]\n" })? ; exp: NUM | VAR | VAR '=' exp | exp '+' exp | exp '-' exp | exp '*' exp | exp '/' exp | '-' exp %prec NEG { "$_[2] NEG" } | '(' exp ')' { $_[2] } ; %% sub _Error { my($token)=$_[0]->YYCurval; my($what)= $token ? "input: '$token'" : "end of input"; my @expected = $_[0]->YYExpect(); local $" = ', '; die "Syntax error near $what. Expected one of these tokens: @expected\n"; } my $x; sub _Lexer { my($parser)=shift; for ($x) { s/^\s+//; $_ eq '' and return('',undef); s/^([0-9]+(?:\.[0-9]+)?)// and return('NUM',$1); s/^([A-Za-z][A-Za-z0-9_]*)// and return('VAR',$1); s/^(.)//s and return($1,$1); } } sub Run { my($self)=shift; print {interactive} "Write an expression: "; $x = <>; $self->YYParse( yylex => \&_Lexer, yyerror => \&_Error, #yydebug => 0xFF ); }