next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Diseño de Analizadores con Sup: Análisis Sintáctico con Parse::Eyapp Ant: Bypass Automático Err: Si hallas una errata ...


La opción alias de %tree

La opción alias de la directiva %tree da lugar a la construcción de métodos de acceso a los hijos de los nodos para los cuales se haya explicitado un nombre a través de la notación punto o de la notación dolar.

Veamos un ejemplo:

nereida:~/src/perl/YappWithDefaultAction/examples> cat -n ./alias.pl
  1  #!/usr/bin/perl -w
  2  use strict;
  3  use Parse::Eyapp;
  4
  5  my $grammar = q{
  6  %right  '='
  7  %left   '-' '+'
  8  %left   '*' '/'
  9  %left   NEG
!10  %tree bypass alias
 11
 12  %%
 13  line: $exp  { $_[1] }
 14  ;
 15
 16  exp:
 17      %name NUM
 18            $NUM
 19          | %name VAR
 20            $VAR
 21          | %name ASSIGN
 22            $VAR '=' $exp
 23          | %name PLUS
 24            exp.left '+' exp.right
 25          | %name MINUS
 26            exp.left '-' exp.right
 27          | %name TIMES
 28            exp.left '*' exp.right
 29          | %name DIV
 30            exp.left '/' exp.right
 31          | %no bypass UMINUS
 32            '-' $exp %prec NEG
 33    |   '(' exp ')'  { $_[2] } /* Let us simplify a bit the tree */
 34  ;
 35
 36  %%
 37
 38  sub _Error {
 39          exists $_[0]->YYData->{ERRMSG}
 40      and do {
 41          print $_[0]->YYData->{ERRMSG};
 42          delete $_[0]->YYData->{ERRMSG};
 43          return;
 44      };
 45      print "Syntax error.\n";
 46  }
 47
 48  sub _Lexer {
 49      my($parser)=shift;
 50
 51          $parser->YYData->{INPUT}
 52      or  $parser->YYData->{INPUT} = <STDIN>
 53      or  return('',undef);
 54
 55      $parser->YYData->{INPUT}=~s/^\s+//;
 56
 57      for ($parser->YYData->{INPUT}) {
 58          s/^([0-9]+(?:\.[0-9]+)?)//
 59                  and return('NUM',$1);
 60          s/^([A-Za-z][A-Za-z0-9_]*)//
 61                  and return('VAR',$1);
 62          s/^(.)//s
 63                  and return($1,$1);
 64      }
 65  }
 66
 67  sub Run {
 68      my($self)=shift;
 69      $self->YYParse( yylex => \&_Lexer, yyerror => \&_Error,
 70                      #yydebug =>0xFF
 71                    );
 72  }
 73  }; # end grammar
 74
 75
 76  Parse::Eyapp->new_grammar(
 77    input=>$grammar,
 78    classname=>'Alias',
 79    firstline =>7,
 80  );
 81  my $parser = Alias->new();
 82  $parser->YYData->{INPUT} = "a = -(2*3+5-1)\n";
 83  my $t = $parser->Run;
 84  $Parse::Eyapp::Node::INDENT=0;
!85  print $t->VAR->str."\n";             # a
 86  print "***************\n";
!87  print $t->exp->exp->left->str."\n";  # 2*3+5
 88  print "***************\n";
!89  print $t->exp->exp->right->str."\n"; # 1
Este programa produce la salida:
nereida:~/src/perl/YappWithDefaultAction/examples> ./alias.pl
TERMINAL
***************
PLUS(TIMES(NUM,NUM),NUM)
***************
NUM
El efecto de la opción alias en una regla como:
 27          | %name TIMES
 28            exp.left '*' exp.right
es crear dos métodos left y right en la clase TIMES. El método left permite acceder al hijo izquierdo del nodo en el AST y el método right al hijo derecho.

El efecto de la opción alias en una regla como:

 21          | %name ASSIGN
 22            $VAR '=' $exp
es crear dos métodos en la clase ASSIGN denominados VAR y exp los cuales permiten acceder a los correspondientes hijos de uno nodo ASSIGN.

Los métodos son construidos durante la compilación de la gramática. Por tanto, las modificaciones al AST que el programa introduzca en tiempo de ejecución (por ejemplo la supresión de hijos de ciertos nodos) invalidarán el uso de estos métodos.


next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Diseño de Analizadores con Sup: Análisis Sintáctico con Parse::Eyapp Ant: Bypass Automático Err: Si hallas una errata ...
Casiano Rodríguez León
2012-05-22