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 ) # EXPEs 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 ) # EXPA esta maniobra, consistente en obviar un nodo sustituyéndolo por el único hijo que realmente importa, la denominaremos bypass de un nodo.