El producto de la traducción - que es la entrada para el intérprete - es un árbol. Cada operación del intérprete es un nodo del árbol. Los argumentos de la operación son los hijos del nodo.
Hay diferentes tipos de operadores. Por ejemplo el operador binario add toma dos valores de la pila y empuja la suma. El operador unario readline toma un manejador de ficheros de la pila y empuja el valor leído.
Algunos operadores actúan sobre listas. Por ejemplo print toma un número variable de elementos de la pila. Los operadores de listas se apoyan en un uso previo del operador pushmark para marcar el comienzo de la lista de argumentos.
Los módulos en la familia B::* permiten acceder a dicho árbol
( B ,  B::Deparse ,  B::Bytecode ,  B::ByteLoader , etc.).
El módulo B representa cada operador como una subclase
de la clase  B::OP . 
Existe un conjunto de clases que heredan de B::OP . Estas son: B::OP , B::UNOP (nodos unarios), B::BINOP (nodos binarios), B::LOGOP , B::LISTOP , B::PMOP , B::SVOP (valores escalares), B::PADOP , B::PVOP , B::LOOP , B::COP (código).
La siguiente figura muestra la jerarquía de herencia:
                              B::OP
                                |
                +---------------+--------+--------+
                |               |        |        |
             B::UNOP          B::SVOP B::PADOP  B::COP
              ,'  `-.
             /       `--.
        B::BINOP     B::LOGOP
            |
            |
        B::LISTOP
          ,' `.
         /     \
     B::LOOP B::PMOP
Estas clases contienen métodos que nos permiten obtener información sobre o modificar el estado interno del operador. Por ejemplo obtener los hijos de un operador.
Los módulos de la familia B:: se soportan en otros dos módulos:
B:: en cuestión.
Para tener una visión en profundidad del tema puede consultar los libros de Simon Cozens [7] y [8].
El siguiente programa Btree3.pl implanta una subrutina
treetrav que muestra el árbol
generado por el compilador para una subrutina dada. 
pp2@nereida:~/src/perl/B$ cat -n Btree3.pl
 1  #!/usr/local/bin/perl -w
 2  use strict;
 3  use B::Utils;
 4
 5  my $s = sub {
 6    my $a = shift;
 7    print $a+1;
 8  };
 9
10  sub treetrav {
..    ...........
22  }
23
24  my $b = B::svref_2object($s); # Objeto B::CV 
25  print "*** Tree ***\n";
26  my $op = $b->ROOT;
27  treetrav($op, 0);
Hay dos formas de acceder al árbol de código. Una es através de las funciones B::main_root y B::main_start :
pp2@nereida:~/src/perl/B$ perl -MB -le 'print B::main_root,"\n",B::main_start' B::LISTOP=SCALAR(0x814fb60) B::OP=SCALAR(0x814f8e4)
La otra forma - que es la usada en el ejemplo - es llamando a la función B::svref_2object con argumento una referencia al código. Nos retorna un objeto B::CV que representa el árbol de codigo resultante.
Cuando treetrav es llamada con el objeto y un sangrado inicial igual a 0
nos produce la siguiente
salida:
pp2@nereida:~/src/perl/B$ Btree3.pl
*** Tree ***
leavesub(               #subroutine exit
  lineseq(              #line sequence
    sassign(            #scalar assignment
      shift(            #shift
        rv2av(          #array dereference
          gv(           #glob value
          ) # end gv
        ) # end rv2av
      ) # end shift
      padsv(            #private variable
      ) # end padsv
    ) # end sassign
    nextstate(          #next statement
    ) # end nextstate
    print(              #print
      add(              #addition (+)
        padsv(          #private variable
        ) # end padsv
        const(          #constant item
        ) # end const
      ) # end add
    ) # end print
  ) # end lineseq
) # end leavesub
 | 
 5  my $s = sub {
 6    my $a = shift;
 7    print $a+1;
 8  };
 | 
La función treetrav usa los métodos  name  y  desc 
de la subclase  B::OP  
para obtener el nombre y la descripción de la operación actual.
El método  kids  en  B::Utils 
devuelve la lista de hijos:
10  sub treetrav {
11    my $op = shift;
12    my $indent = shift;
13
14    my $spaces = " "x$indent;
15    print $spaces.$op->name."(\t\t#".$op->desc;
16      print "\n";
17      for ($op->kids()) {
18        treetrav($_, $indent+2);
19      }
20      print "$spaces) # end ".$op->name;
21    print "\n";
22  }
Una alternativa a nuestra función de recorrido 
habría sido usar una de las proveídas por B::Utils.
Hay varias subrutinas de recorrido del árbol de 
códigos. Una de las mas sencillas es  walkoptree_simple 
(en B::Utils):
     walkoptree_simple($op, \&callback, [$data])
La función  &callback es llamada para cada 
operación pasándole como argumentos la operación y cuales quiera datos adicionales
en $data.
Todas las funciones de recorrido establecen las
variables $B::Utils::file y $B::Utils::line
al fichero y número de línea actual. Sólo los nodos de clase
COP disponen de esa información.
En el párrafo anterior recorríamos el árbol según su orden jerárquico. Sin embargo el árbol está a su vez hilvanado en orden de ejecución. Esto es: superpuesta a la estructura de árbol existe una lista que recorre el árbol según el flujo de control. A esta estructura de datos se la denomina Grafo de Flujo de Control o Control flow Graph (CFG).
El método  START  de un objeto B::CV nos da el punto de 
entrada en la ejecución. El método  next  de un objeto B::OP
proporciona el siguiente nodo a ejecutar.
pp2@nereida:~/src/perl/B$ cat -n bex2.pl
 1  #!/usr/local/bin/perl -w
 2  use strict;
 3  use B;
 4
 5  my $s = sub {
 6    my $a = shift;
 7    print $a+1;
 8  };
 9
10  my $b = B::svref_2object($s); 
11  my $op = $b->START;
12  my ($class, $name, $desc);
13  format STDOUT =
14  @<<<<<<<<<@|@<<<<<<<<<<<<@|@<<<<<<<<<<<<<<<<<<<<<<<<<
15  $class,   '|', $name,    '|', $desc
16  .
17  do {
18    ($class, $name, $desc) = (B::class($op), $op->name, $op->desc);
19    write;
20  } while $op = $op->next and !$op->isa("B::NULL");
Es necesario comprobar que $op no es un objeto  B::NULL 
ya que el puntero next es un puntero C que B
deja disponible sin envoltorio alguno.
La ejecución produce la secuencia de operaciones en orden de ejecución:
pp2@nereida:~/src/perl/B$ bex2.pl | cat -n 1 COP | nextstate | next statement 2 PADOP | gv | glob value 3 UNOP | rv2av | array dereference 4 UNOP | shift | shift 5 OP | padsv | private variable 6 BINOP | sassign | scalar assignment 7 COP | nextstate | next statement 8 OP | pushmark | pushmark 9 OP | padsv | private variable 10 SVOP | const | constant item 11 BINOP | add | addition (+) 12 LISTOP | print | print 13 UNOP | leavesub | subroutine exit  | 
 my $s = sub {
   my $a = shift;
   print $a+1;
 };
 | 
El módulo  B::Terse  tiene una opción -exec que permite ver 
el orden de ejecución de un código:
pp2@nereida:~/src/perl/B$ perl -MO=Terse,-exec -e 'my $s = 4' OP (0x816d298) enter COP (0x816d300) nextstate SVOP (0x816d588) const [2] IV (0x8150388) 4 OP (0x816d4a0) padsv [1] BINOP (0x816d5e0) sassign LISTOP (0x816d468) leave [1] -e syntax OK
 
