2012-09-08 11 views
9

dado un ref CODE, es posible:¿Cómo creo un subperio de Perl especificando su árbol de análisis sintáctico?

  1. acceso al árbol de análisis sintáctico de ese código de ref
  2. Crear una nueva ref CÓDIGO especificando el árbol de análisis sintáctico de la ref código que puede contener elementos del análisis sintáctico árbol devuelto en

Normalmente creamos subrutinas en Perl especificando código fuente que a continuación se analiza y se convierte en un árbol de análisis sintáctico.

Me gustaría escribir una función perl que puede crear una subrutina especificando su árbol de análisis sintáctico, y ese árbol de análisis sintáctico podría derivarse de otro árbol de análisis de alguna otra subrutina.

¿Posible?

+3

Por un lado, una pregunta fascinante. Por otro lado, suena como algo para correr, no para alejarse. Tengo curiosidad por saber cuál es tu caso de uso –

+2

Yous say "y ese árbol de análisis sintáctico podría derivarse de otro árbol de análisis de alguna otra subrutina.", Sin embargo, su pregunta no tiene absolutamente nada que ver con eso. ¿Qué está tratando de hacer realmente? – ikegami

Respuesta

7

No conozco la respuesta completa a su pregunta, pero sé que Data :: Dumper puede rastrear una referencia de código. Mirando su documentación, veo que usa B::Deparse para hacer el trabajo pesado (los módulos B:: son los que interactúan con el compilador). Desafortunadamente, parece que esto solo da como resultado una representación textual del coderef.

En su lugar he buscado Op en metacpan y obtuve muchas más posibilidades interesantes. Como ahora estoy muy lejos de mi profundidad en la magia Perl más profunda, te dejo mirar esos resultados. Quizás algo será útil.

+0

Gracias por el cable 'Op'. Quiero trabajar con cierres, así que estoy seguro de que será necesario acceder a los nodos subyacentes en el árbol de análisis sintáctico para poder crear nuevos cierres que se cierren sobre las mismas variables. – ErikR

+3

Asegúrese de revisar ['PadWalker'] (http://p3rl.org/PadWalker) también, creo que esto es lo que mucha gente usa para investigar cierres. –

1

Esto no tiene nada que ver con los códigos de operación, pero encierra las mismas dos variables en tres cierres diferentes. Las variables están encerradas dentro de subrutinas que recuerdan las rutinas get/set de clase, y las variables cerradas son compartidas por otros cierres a través de su rutina de acceso.

Esta es una respuesta al comentario: Estoy seguro de que será necesario acceder a los nodos subyacentes en el árbol de análisis sintáctico para que pueda crear nuevos cierres que se cierran sobre las mismas variables.

use strict; 
use warnings; 
use v5.14; 

# create closed vars 
my $v1 = access_closure(6); 
my $v2 = access_closure(42); 

# play with them 
say "v1 ", &$v1; 
say "v2 ", &$v2; 
say "v1 ", &$v1(5); 
say "v2 ", &$v2(43); 
say "v1 ", &$v1; 
say "v2 ", &$v2; 

# create silly closures that use them 
my $test1 = test_closure(2); 
my $test2 = test_closure(17); 
my $test3 = test_closure(50); 

# play with those 
&$test1; 
&$test2; 
&$test3; 

# create the get/set routine for a closed var 
sub access_closure { 
    my $val = shift; 
    return sub { 
     $val = shift if @_; 
     return $val; 
    } 
} 

# create a silly closure that encloses a control var and uses the two other vars 
sub test_closure { 
    my $val = shift; 
    return sub { 
     say "\nval is $val"; 
     printf "v1 is %2d, v2 is %2d\n", 
      &$v1, &$v2; 
     if (&$v1 < $val) { 
      say "Increment v1"; 
      &$v1(&$v1+1); 
     } 
     if (&$v2 > $val) { 
      say "Decrement v2"; 
      &$v2(&$v2-1); 
     } 
     printf "v1 is %2d, v2 is %2d\n", 
      &$v1, &$v2; 
    } 
} 
Cuestiones relacionadas