next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Transformaciones de Árboles con Sup: Transformaciones Árbol con Parse::Eyapp Ant: El método m Err: Si hallas una errata ...

Transformaciones Arbol con treereg

La distribución de Eyapp provee un conjunto de módulos que permiten la manipulación y transformación del AST. La formas mas usual de hacerlo es escribir el programa de transformaciones árbol en un fichero separado. El tipo .trg se asume por defecto. El ejemplo que sigue trabaja en cooperación con el programa Eyapp presentado en la sección 8.11 página 8.11. El programa árbol sustituye nodos producto por un número potencia de dos por nodos unarios de desplazamiento a izquierda. De este modo facilitamos la tarea de la generación de un código mas eficiente:

pl@nereida:~/LEyapp/examples$ cat -n Shift.trg
 1  # File: Shift.trg
 2  {
 3    sub log2 {
 4      my $n = shift;
 5      return log($n)/log(2);
 6    }
 7
 8    my $power;
 9  }
10  mult2shift: TIMES($e, NUM($m))
11    and { $power = log2($m->{attr}); (1 << $power) == $m->{attr} } => {
12      $_[0]->delete(1);
13      $_[0]->{shift} = $power;
14      $_[0]->type('SHIFTLEFT');
15    }
Obsérvese que la variable léxica $power es visible en la definición de la transformación mult2shift. Compilamos el programa de transformaciones usando el guión treereg :
nereida:~/src/perl/YappWithDefaultAction/examples> treereg Shift
nereida:~/src/perl/YappWithDefaultAction/examples> ls -ltr | tail -1
-rw-rw----  1 pl users   1405 2006-11-06 14:09 Shift.pm
Como se ve, la compilación produce un módulo que Shift.pm que contiene el código de los analizadores. El código generado por la versión 0.2 de treereg es el siguiente:
pl@nereida:~/LEyapp/examples$ cat -n Shift.pm
 1  package Shift;
 2
 3  # This module has been generated using Parse::Eyapp::Treereg
 4  # from file Shift.trg. Don't modify it.
 5  # Change Shift.trg instead.
 6  # Copyright (c) Casiano Rodriguez-Leon 2006. Universidad de La Laguna.
 7  # You may use it and distribute it under the terms of either
 8  # the GNU General Public License or the Artistic License,
 9  # as specified in the Perl README file.
10
11  use strict;
12  use warnings;
13  use Carp;
14  use Parse::Eyapp::_TreeregexpSupport qw(until_first_match checknumchildren);
15
16  our @all = ( our $mult2shift, ) = Parse::Eyapp::YATW->buildpatterns(mult2shift => \&mult2shift, );
17
18  #line 2 "Shift.trg"
19
20    sub log2 {
21      my $n = shift;
22      return log($n)/log(2);
23    }
24
25    my $power;
26
27
28    sub mult2shift {
29      my $mult2shift = $_[3]; # reference to the YATW pattern object
30      my $e;
31      my $NUM;
32      my $TIMES;
33      my $m;
34
35      {
36        my $child_index = 0;
37
38        return 0 unless (ref($TIMES = $_[$child_index]) eq 'TIMES');
39      return 0 unless defined($e = $TIMES->child(0+$child_index));
40      return 0 unless (ref($NUM = $TIMES->child(1+$child_index)) eq 'NUM');
41      return 0 unless defined($m = $NUM->child(0+$child_index));
42      return 0 unless do
43  #line 10 "Shift.trg"
44        { $power = log2($m->{attr}); (1 << $power) == $m->{attr} };
45
46      } # end block of child_index
47  #line 11 "Shift.trg"
48    {
49      $_[0]->delete(1);
50      $_[0]->{shift} = $power;
51      $_[0]->type('SHIFTLEFT');
52    }
53
54    } # end of mult2shift
55
56
57  1;

Uso de los Módulos Generados

El programa de análisis se limita a cargar los dos módulos generados, crear el analizador, llamar al método Run para crear el árbol y proceder a las sustituciones mediante la llamada $t->s(@Shift::all):

pl@nereida:~/LEyapp/examples$ cat -n useruleandshift.pl
 1  #!/usr/bin/perl -w
 2  use strict;
 3  use Rule5;
 4  use Parse::Eyapp::Base qw(insert_function);
 5  use Shift;
 6
 7  sub SHIFTLEFT::info { $_[0]{shift} }
 8  insert_function('TERMINAL::info', \&TERMINAL::attr);
 9
10  my $parser = new Rule5();
11  my $t = $parser->Run;
12  print "***********\n",$t->str,"\n";
13  $t->s(@Shift::all);
14  print "***********\n",$t->str,"\n";
Cuando alimentamos el programa con la entrada a=b*32 obtenemos la siguiente salida:
pl@nereida:~/LEyapp/examples$ useruleandshift.pl
a=b*32
***********
ASSIGN(TERMINAL[a],TIMES(VAR(TERMINAL[b]),NUM(TERMINAL[32])))
***********
ASSIGN(TERMINAL[a],SHIFTLEFT[5](VAR(TERMINAL[b])))



Subsecciones
next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Transformaciones de Árboles con Sup: Transformaciones Árbol con Parse::Eyapp Ant: El método m Err: Si hallas una errata ...
Casiano Rodríguez León
2012-05-22