next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Transformaciones Arbol con treereg Sup: Transformaciones Árbol con Parse::Eyapp Ant: Patrones Árbol y Transformaciones Err: Si hallas una errata ...


El método m

El método $yatw_object->m($t) permite la búsqueda de los nodos que casan con una expresión regular árbol dada. En un contexto de lista devuelve una lista con nodos del tipo Parse::Eyapp::Node::Match que referencian a los nodos que han casado. Los nodos en la lista se estructuran según un árbol (atributos children y father) de manera que el padre de un nodo $n del tipo Parse::Eyapp::Node::Match es el nodo $f que referencia al inmediato antecesor en el árbol que ha casado.

Los nodos Parse::Eyapp::Node::Match son a su vez nodos (heredan de) Parse::Eyapp::Node y se estructuran según un árbol.

Los nodos aparecen en la lista retornada en orden primero profundo de recorrido del árbol $t.

Un nodo $r de la clase Parse::Eyapp::Node::Match dispone de varios atributos y métodos:

La clase Parse::Eyapp::Node::Match hereda de Parse::Eyapp::Node. Dispone además de otros métodos para el caso en que se usan varios patrones en la misma búsqueda.

Por ejemplo, método $r->names retorna una referencia a los nombres de los patrones que han casado con el nodo.

En un contexto escalar m devuelve el primer elemento de la lista de nodos Parse::Eyapp::Node::Match.

El método m: Ejemplo de uso

La siguiente expresión regular árbol casa con los nodos bloque:

nereida:~/doc/casiano/PLBOOK/PLBOOK/code/Simple-Types/lib/Simple> sed -ne '2p' Trans.trg
blocks:  /BLOCK|FUNCTION|PROGRAM/

Utilizaremos el siguiente programa de entrada:

nereida:~/doc/casiano/PLBOOK/PLBOOK/code/Simple-Types/script> cat -n blocks.c
 1  test (int n)
 2  {
 3    while (1) {
 4      if (1>0) {
 5        int a;
 6        break;
 7      }
 8      else if (2> 0){
 9        char b;
10        continue;
11      }
12    }
13  }
Ejecutamos la versión con análisis de tipos de nuestro compilador de simple C. SimpleC es una versión simplificada de C (véase el capítulo 12 y las secciones 12.3 y 12.4), bajo el control del depurador:
nereida:~/doc/casiano/PLBOOK/PLBOOK/code/Simple-Types/script> perl -wd usetypes.pl blocks.c
Loading DB routines from perl5db.pl version 1.28
Editor support available.
Enter h or `h h' for help, or `man perldebug' for more help.
main::(usetypes.pl:6):  my $filename = shift || die "Usage:\n$0 file.c\n";
  DB<1> b Simple::Types::compile
  DB<2> c
Simple::Types::compile(Types.eyp:529):
529:     my($self)=shift;
  DB<2> l 540,545
540:     our $blocks;
541:     my @blocks = $blocks->m($t);
542:     $_->node->{fatherblock} = $_->father->{node} for (@blocks[1..$#blocks]);
543
544      # Type checking
545:     set_types($t);
  DB<3> c 545
Simple::Types::compile(Types.eyp:545):
545:     set_types($t);
Nos detenemos en la línea 545 justo después de la llamada a m (línea 541) y de actualizar el atributo fatherblock de los nodos bloque. La línea 542 crea una jerarquía árbol con los nodos bloque que se superpone a la jerarquía del árbol sintáctico abstracto. En esta línea $_->father->{node} es el nodo del AST que es un ancestro de $_->node y que ha casado con la expresión regular árbol.

Este sub-árbol de bloques puede ayudarnos en la fase de ubicar que declaración se aplica a una aparición de un objeto dado en el texto del programa. Para cada ocurrencia debemos determinar si fué declarada en el bloque en el que ocurre o bien en uno de los nodos bloque antepasados de este.

  DB<4> $Parse::Eyapp::Node::INDENT = 2
  DB<5> x $blocks[0]->str
0  '
Match[[PROGRAM:0:blocks]](
  Match[[FUNCTION:1:blocks:test]](
    Match[[BLOCK:6:blocks:8:4:test]],
    Match[[BLOCK:5:blocks:4:4:test]]
  )
) # Parse::Eyapp::Node::Match'
La orden x $blocks[0]->str nos permite visualizar el árbol de casamientos. El método coord nos devuelve una cadena con las coordenadas del nodo que ha casado. Las coordenadas son una secuencia de puntos y números que describe el camino para llegar al nodo desde la raíz del árbol. Veamos las coordenadas de los nodos en el AST del ejemplo:
  DB<6> x map {$_->coord} @blocks
0  ''
1  '.0'
2  '.0.0.1.0.1'
3  '.0.0.1.0.2.1'
  DB<7> x $t->child(0)->child(0)->child(1)->child(0)->child(2)->child(1)->str
0  '
BLOCK[8:4:test]^{0}(
  CONTINUE[10,10]
)
  DB<8> x $t->descendant('.0.0.1.0.2.1')->str
0  '
BLOCK[8:4:test]^{0}(
  CONTINUE[10,10]
)
  DB<9> x $t->descendant('.0.0.1.0.1')->str
0  '
BLOCK[4:4:test]^{0}(
  BREAK[6,6]
)
El método descendant es un método de los objetos Parse::Eyapp::Node y retorna una referencia al nodo descrito por la cadena de coordenadas que se le pasa como argumento. En este sentido el método child es una especialización de descendant .

La profundidad de los nodos que han casado puede conocerse con el método depth :

  DB<9> x  map {$_->depth } @blocks
0  0
1  1
2  5
3  6
  DB<16> x  map {ref($_->node) } @blocks
0  'PROGRAM'
1  'FUNCTION'
2  'BLOCK'
3  'BLOCK'
  DB<17> x  map {ref($_->father) } @blocks
0  ''
1  'Parse::Eyapp::Node::Match'
2  'Parse::Eyapp::Node::Match'
3  'Parse::Eyapp::Node::Match'
  DB<19> x  map {ref($_->father->node) } @blocks[1..3]
0  'PROGRAM'
1  'FUNCTION'
2  'FUNCTION'



Subsecciones
next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Transformaciones Arbol con treereg Sup: Transformaciones Árbol con Parse::Eyapp Ant: Patrones Árbol y Transformaciones Err: Si hallas una errata ...
Casiano Rodríguez León
2012-05-22