PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un...

23
PROGRAMACION DE SISTEMAS JJTREE y JavaCC

Transcript of PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un...

Page 1: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

PROGRAMACION DE SISTEMASJJTREE y JavaCC

Page 2: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Introducción• JJTree, es una herramienta para

construir un árbol de representación del mismo parser.

• JJTree se acciona para emitir un parser el cual su principal trabajo durante su ejecución no es ejecutar acciones incrustadas de java, sino construir una representación independiente de árbol del análisis sintáctico de la expresión que se analiza por el compilador resultante.

Page 3: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

¿Qué hacer con el árbol que produce JJTree?• JJTree permite capturar el estado

de la sesión del análisis sintáctico en un solo árbol que es fácil de recorrer y verificar en tiempo de ejecución, independientemente del código de análisis sintáctico que lo produce.

Page 4: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Arbol de análisis sintáctico• Al árbol generado por JJTree, se le

denomina formalmente como Árbol de análisis sintáctico.

• Para trabajar con JJTree se requiere lo siguiente:– Crear un script con extensión .jjt el

cual JJTree toma como entrada– Escribir el código del lado cliente

para recorrer y evaluar el árbol sintáctico que se produce en la ejecución.

Page 5: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Aspectos básicos de JJTree• JJTree es un preprocesador y

genera un parser para un BNF particular.

• Es un proceso fácil de dos pasos:– Ejecutar JJTree contra un archivo

denominado .jjt; este producirá un archivo .jj

– Compilar el archivo .jj con JavaCC– Y por último, compilar el archivo .java

resultante

Page 6: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Sintaxis del archivo .jjt• La estructura de un archivo .jjt es de

menor extensión que el formato .jj• La principal diferencia es que JJTree

agrega un nuevo constructor sintáctico (node-constructor) el cual permite especificar donde y bajo que condiciones se tienen que generar los nodos del árbol sintáctico durante el análisis sintáctico.

Page 7: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Una gramática simpleSKIP:{“ “|”\t”|”\n”|”\r” }

TOKEN:{<INT : ([“0”-”9”])+ > }

void simpleLeng():{} {addExpr() <EOF>}

void addExpr():{} {integerLit() (“+” integerLit() ) ? }

void integerLit():{} {<INT>}

• En ésta gramática se establece que una expresión válida consiste de:– Una sola literal entera o– Una literal entera seguida del signo más y seguido por otra literal entera.

• A continuación, ligeramente modificada para emplear JJTree (se indican los cambios)

SKIP:{“ “|”\t”|”\n”|”\r” }

TOKEN:{<INT : ([“0”-”9”])+ > }

SimpleNode simpleLeng():#Root{} {addExpr()<EOF> {return jjtThis;}}

void addExpr():{} {integerLit()

(“+” integerLit() #Add(2) ) ? }

void integerLit():#IntLit{} {<INT>}

Page 8: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Paso a paso por la gramática JJTree• La invocación a un parser sin

emplear JJTree sería como:SimpleParser parser = new SimpleParser(new StringReader(expresion));

parser.simpleLeng();

• Ahora la invocación a un parser empleando JJTree:SimpleParser parser = new SimpleParser(new StringReader(expresion));

SimpleNode rootNode = parser.simpleLeng();

Page 9: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Descripción del ejemplo• Las etiqueta insertada de la

forma #Root, indican que se insertará un nodo raíz (de tipo SimpleNode) en el árbol creado y referenciado en todo momento por jjtThis.

SimpleNode simpleLeng():#Root{}

{addExpr()<EOF> {return jjThis;}}

Page 10: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Descripción del ejemplo• La etiqueta #Add(2) dentro de la producción

addExpr() difiere de la etiqueta #Root en varios aspectos:– Es parametrizada. El constructor del árbol utiliza

una pila de nodos durante la construcción; el comportamiento normal para un constructor de nodos sin parámetros es colocarse en el tope del árbol sintáctico bajo construcción, sacando todos los nodos de la pila de nodos que fueron creados en su mismo alcance y colocando a dicho nodo como el nodo padre.

– El argumento 2 indica que el nuevo nodo padre (en éste caso #Add) adoptará exactamente dos nodos hijo, los dos sub nodos #IntLit descritos en la siguiente construcción.

Page 11: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Descripción del ejemplo• De igual importancia, la colocación de la

directiva #Root fuera del cuerpo de la producción significa que el nodo #Root es generado cada vez que se cumple la producción (lo cual en éste caso sólo sucede una vez).

• Sin embargo, la colocación de la directiva #Add(2) dentro de un término “cero o uno” significa que un nodo #Add se crea condicionalmente si la cláusula opcional se cumple, es decir si ésta producción representa una verdadera operación de suma.

Page 12: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Descripción del ejemplo• Siguiendo las reglas de producción, integerLit() se cumple dos veces, agregando al árbol un nodo #IntLit en cada invocación. Ambos nodos #IntLit se convierten en nodos hijos del nodo #Add que los invoca. Sin embargo si la expresión a analizar sintácticamente es de un solo entero, entonces el nodo resultante se convierte directamente en nodo hijo de #Root

Page 13: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Representación del árbol• Árbol sintáctico para una expresión de un

solo entero.

• Árbol sintáctico para una operación de suma.

Page 14: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Trabajando sobre el árbol resultante• Cada nodo que se declara en un archivo .jjt

instruye al parser a generar una subclase del tipo SimpleNode de JJTree.

• SimpleNode en turno, implementa una interface Java denominada Node.

• Los archivos fuente para estas clases son generadas automáticamente por cada archivo JJTree, acompañando al archivo .jj

• JJTree también emite archivos fuente para sus propias clases – Root, Add y IntLit del ejemplo – así como otras clases de apoyo.

Page 15: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Desplegando el contenido del árbol.• Todas las subclases de SimpleNode

heredan un comportamiento útil. El método dump() de SimpleNode es uno de estos.

• Las siguientes tres líneas de código inician el parser, lo invocan, obtienen en árbol sintáctico e imprimen directamente una representación textual del árbol en la consola.

Page 16: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Trabajando sobre el árbol resultante• Código dentro del método main() o método de la

clase “Cliente” del parser.

SimpleParser parser = new SimpleParser(new StringReader(expresion));

SimpleNode rootNode = parser.simpleLeng();

rootNode.dump(“ “);

• Representación del árbol de acuerdo al ejemplo

Root

Add

IntLit

IntLit

Page 17: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Navegando a través del árbol• Otro método útil de SimpleNode

es jjtGetChild(int). • De acuerdo al ejemplo, cuando se

navega a través del árbol sintáctico y se encuentre un nodo #Add, seguramente se buscará obtener sus nodos hijos tipo #IntLit, extraer sus valores enteros que representan y sumarlos.

Page 18: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Navegando a través del árbol• Asumiendo que addNode, mostrado en

el siguiente fragmento de código, es una variable que representa un nodo de tipo Add, podemos acceder a los dos nodos hijos de addNode.

SimpleNode izq = addNode.jjtGetChild(0);SimpleNode der = addNode.jjtGetChild(1);

Es importante aclarar que los dos nodos IntLit todavía no contienen los valores enteros que pretenden representar.

Page 19: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Almacenando y recuperando el estado.• Para almacenar el valor de los

tokens identificados en los nodos apropiados, hay que realizar las siguientes modificaciones a SimpleNode:

public class SimpleNode extends Node{String m_text;public void setText(String text) {m_text = text;}public String getText() { return m_text; }

}

Page 20: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Almacenar y recuperar el estado.• Cambiar la siguiente producción en el

archivo .jjtvoid integerLit(): #IntLit {} {<INT>}

• por éstovoid integerLit(): #IntLit {Token t}

{ t=<INT>{ jjtThis.setText(t.image);} }

Esta producción obtiene el texto crudo del valor del entero encontrado en t.image y usa el método setText() para almacenar la cadena en el nodo actual.

Page 21: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Desplegando los cambios• Fácilmente se puede modificar el

método SimpleNode.dump() para emitir el valor de m_text para cualquier nodo que sea almacenado durante el análisis.

• Por ejemplo, se puede modificar para visualizar la salida de dump(), para la expresión “42 + 1” y obtener el siguiente resultado:

Root Add

IntLit[42]IntLit[1]

Page 22: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Implementando la precedencia de operadores.• Ordenando correctamente las

reglas de producción, colocando en la parte inferior aquellas reglas que tienen mayor prioridad, se cubre la precedencia de los operadores ya que la representación del árbol sintáctico controlará efectivamente el orden correcto de evaluación.

Page 23: PROGRAMACION DE SISTEMAS JJTREE y JavaCC. Introducción JJTree, es una herramienta para construir un árbol de representación del mismo parser. JJTree se.

Ejemplo completo.• Revisar el archivo Calc.jjt y

realizar las siguientes modificaciones: