next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Práctica: Traductor de Términos Sup: Análisis Sintáctico con Parse::Eyapp Ant: Acciones y Acciones por Err: Si hallas una errata ...

Traducción de Infijo a Postfijo

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
    );
  }


next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Práctica: Traductor de Términos Sup: Análisis Sintáctico con Parse::Eyapp Ant: Acciones y Acciones por Err: Si hallas una errata ...
Casiano Rodríguez León
2012-05-22