

En el programa eyapp visto en la sección anterior generabamos una representación
del árbol de análisis sintáctico utilizando la directiva %tree. Asi para la entrada:
pl@nereida:~/LEyapp/examples$ cat prueba2.exp a=(2+b)*3Obteníamos el árbol:
pl@nereida:~/LEyapp/examples$ usecalcsyntaxtree.pl prueba2.exp | cat -n
1
2 EXP(
3 ASSIGN(
4 TERMINAL[a],
5 TIMES(
6 PAREN(
7 PLUS(
8 NUM(
9 TERMINAL[2]
10 ),
11 VAR(
12 TERMINAL[b]
13 )
14 ) # PLUS
15 ) # PAREN,
16 NUM(
17 TERMINAL[3]
18 )
19 ) # TIMES
20 ) # ASSIGN
21 ) # EXP
Es evidente que el árbol contiene información redundante: el nodo PAREN
puede ser obviado sin que afecte a la interpretación del árbol.
La directiva %tree es un caso particular de la directiva %default action.
De hecho usarla es equivalente a escribir:
%default action { goto &Parse::Eyapp::Driver::YYBuildAST }
La subrutina Parse::Eyapp::Driver::YYBuildAST se encarga de la construcción
del nodo correspondiente a la regla de producción actual. De hecho el método
retorna una referencia al objeto nodo recién construído.
Puesto que la directiva %tree es un caso particular de la directiva %default action
la ubicación de acciones semánticas explícitas para una regla puede ser usada
para alterar la forma del árbol de análisis.
Un ejemplo de uso lo motiva el comentario anterior sobre los nodos PAREN.
Sería deseable que tales nodos no formaran parte del árbol.
Observe la nueva versión de la gramática en la sección anterior (página
). El programa eyapp trabaja bajo la directiva
%tree. Se ha introducido una acción explícita en la línea 21.
pl@nereida:~/LEyapp/examples$ sed -ne '/^exp:/,/^;/p' CalcSyntaxTree4.eyp | cat -n
1 exp:
2 %name NUM
3 NUM
4 | %name VAR
5 VAR
6 | %name ASSIGN
7 VAR '=' exp
8 | %name PLUS
9 exp '+' exp
10 | %name MINUS
11 exp '-' exp
12 | %name TIMES
13 exp '*' exp
14 | %name DIV
15 exp '/' exp
16 | %name UMINUS
17 '-' exp %prec NEG
18 | %name EXP
19 exp '^' exp
20 | %name PAREN
21 '(' exp ')' { $_[2] }
22 ;
Como consecuencia de la acción de la línea 21 la referencia al nodo hijo
asociado con exp es retornado y el nodo PAREN desparece
del árbol:
pl@nereida:~/LEyapp/examples$ usecalcsyntaxtree4.pl prueba2.exp
EXP(
ASSIGN(
TERMINAL[a],
TIMES(
PLUS(
NUM(
TERMINAL[2]
),
VAR(
TERMINAL[b]
)
) # PLUS,
NUM(
TERMINAL[3]
)
) # TIMES
) # ASSIGN
) # EXP
A esta maniobra, consistente en obviar un nodo sustituyéndolo
por el único hijo que realmente importa, la denominaremos bypass
de un nodo.

