Introducción a ANTLR Procesadores de Lenguaje 1 de 25
Introducción a ANTLR Qué es ANTLR? ANother Tool for Language Recognition Herramienta para construir traductores entre lenguajes informáticos Genera analizador léxico y sintáctico a partir de gramática y acciones semánticas El analizador sintáctico utiliza el algoritmo LL(*), una generalización de LL(k) Lenguajes para acciones semánticas: Java, C#, C++, Python, C, etc. 2 de 25
Introducción a ANTLR Escribiendo gramáticas para ANTLR (I) Fichero Gramatica.g: grammar Gramatica; @header { /* Cabecera: antes de la definición de la clase. Importar paquetes. */ } @members {/* Miembros de la clase del analizador sintáctico */ } @lexer::members { /* Miembros de la clase del analizador léxico*/}... 3 de 25
Introducción a ANTLR Escribiendo gramáticas para ANTLR (II) Reglas en notación EBNF: noterminal1 : noterminal2 {acción semántica} TOKEN1 ( TOKEN2 noterminal3 {acción semántica} )* noterminal4 noterminal5? noterminal6+ TOKEN3 { acción semántica} ; Analizador léxico: TOKEN1: ('a'..'z' 'A'..'Z')+ ; TOKEN2: ('\r'? '\n' ' ' '\t')+ {skip();} ; 4 de 25
Introducción a ANTLR Escribiendo gramáticas para Atributos sintetizados ANTLR (III) nta returns [int i, String s] : {$i=valor_de_retorno;} ; ntb : var=nta{uso de $var.i $var.s $nta.i $nta.s}; Atributos heredados y variables locales nta[int j, String t] returns [int i, String s] : { uso de $j y $t } ; ntb @init { int k; String u; } :TOKEN{ dar valor a k y u } nta[k,u]; 5 de 25
Introducción a ANTLR Escribiendo gramáticas para ANTLR (IV) Ejemplo: de notación infija a prefija 3 + 4 -b res(sum(3,4),b) grammar ShortPrefix; @header {import java.lang.string; } e : t e_prima[$t.trad] {System.out.println($e_prima.trad);} ; t returns [String trad]: NUMERO {$trad=$numero.text;} ID {$trad=$id.text;} ; 6 de 25
Introducción a ANTLR Escribiendo gramáticas para ANTLR (V) e_prima [String th] returns [String trad] @init { String k; } : OPSUM t { if ($OPSUM.text.equals("+")) k="sum("+$th+","+$t.trad+")"; else k="res("+$th+","+$t.trad+")"; } epr=e_prima[k] {$trad=$epr.trad;} {$trad=$th;} ; NUMERO: ('0'..'9')+ ; ID: ('a'..'z' 'A'..'Z')+ ; OPSUM: '+' '-' ; BLANCO: ('\n' ' ' '\t')+ {skip();} ; 7 de 25
Introducción a ANTLR Instalación de ANTLR Requiere Java Development Kit (paquete sun-java6- jdk en Ubuntu). Seleccionar el de Sun con: sudo update-alternatives --config java sudo update-alternatives --config javac Descargar y descomprimir versión 3.1 desde: http://www.antlr.org/download/antlr-3.1.tar.gz Crear variable de entorno con classpath: export ANTLR_HOME=/tmp/antlr-3.1 export ANTLR_CLASSPATH=$ANTLR_HOME/lib/stringtemplate- 3.2.jar:$ANTLR_HOME/lib/antlr-3.1.jar: $ANTLR_HOME/lib/antlr-runtime-3.1.jar: $ANTLR_HOME/lib/antlr-2.7.7.jar 8 de 25
Introducción a ANTLR Generación de analizador léxico y Generación de las clases: sintáctico java -classpath $ANTLR_CLASSPATH:. org.antlr.tool Gramatica.g Es necesario emplear una clase Main que invoque a ambos analizadores: import org.antlr.runtime.*; public class Main { public static void main(string[] args) throws Exception { CharStream input = new ANTLRFileStream(args[0]); GramaticaLexer lex = new GramaticaLexer(input); CommonTokenStream tokens = new CommonTokenStream(lex); GramaticaParser parser = new GramaticaParser(tokens); parser.raiz(); } } 9 de 25
Introducción a ANTLR Ejecución del traductor Se debe usar el classpath definido anteriormente para la compilación y ejecución de las clases generadas: javac -classpath $ANTLR_CLASSPATH:. Main.java GramaticaParser.java GramaticaLexer.java java -classpath $ANTLR_CLASSPATH:. Main entrada.fnt 10 de 25
Introducción a ANTLR Recursos y herramientas Wiki de la asignatura (http://pelele.pbworks.com): Introducción a ANTLR Instalación de ANTLR Gramáticas expresadas en EBNF Herramientas: ANTLRWorks: http://www.antlr.org/works/ ANTLRArbol: http://code.google.com/p/antlrarbol/ 11 de 25
ANTLRArbol Procesadores de Lenguaje 12 de 25
ANTLRArbol Qué es ANTLRArbol? Herramienta de código abierto para depurar traductores desarrollados con ANTLR Genera el árbol de análisis sintáctico, incluyendo los valores de los atributos (heredados y sintetizados), y sus dependencias Desarrollado especialmente para las prácticas de Procesadores de Lenguaje. Proyecto de Sistemas Informáticos de Víctor M. Sánchez Cartagena. 13 de 25
ANTLRArbol Instalación Requiere JDK 6, Graphviz y ANTLR 3.1. Descargar ANTLRArbol-0.9.2.jar de http://code.google.com/p/antlrarbol/downloads/list Añadir al classpath de ANTLR: export ANTLR_HOME=/tmp/antlr-3.1 export ANTLR_CLASSPATH=$ANTLR_HOME/lib/stringtemplate- 3.2.jar:$ANTLR_HOME/lib/antlr-3.1.jar: $ANTLR_HOME/lib/antlr-runtime-3.1.jar: $ANTLR_HOME/lib/antlr-2.7.7.jar:/ruta/a/ANTLRArbol- 0.92.jar 14 de 25
ANTLRArbol Cómo funciona? (I) Se generan las clases del analizador léxico y sintáctico con ANTLRArbol: java -classpath $ANTLR_CLASSPATH:. org.antlrarbol.bin.createtree [Opciones] Gramatica.g Opciones: -l maxlong. Muestra como máximo maxlong caracteres de los valores de los atributos. -v v1 v2.... Muestra sólo los valores de los atributos de las reglas cuya parte izquierda es v1, v2, etc. -ns Oculta las flechas de de los atributos sintetizados. -ni Oculta las flechas de de los atributos heredados. 15 de 25
ANTLRArbol Cómo funciona? (II) Debemos modificar la clase Main para obtener los datos de depuración: ( ) FileWriter file= new FileWriter("tree.dot"); file.write(parser.gettreeantlrarbol()); file.close(); También se puede generar una clase Main automáticamente: java -classpath $ANTLR_CLASSPATH:. org.antlrarbol.bin.generatemain Gramatica NoTerminalRaiz FicheroDepuración 16 de 25
ANTLRArbol Cómo funciona (III)? La compilación y ejecución del traductor se realizan de la manera habitual: javac -classpath $ANTLR_CLASSPATH:. Main.java GramaticaParser.java GramaticaLexer.java java -classpath $ANTLR_CLASSPATH:. Main entrada.fnt La ejecución ha generado un fichero con información de depuración, a partir del cual generamos la imagen con el árbol de análisis sintáctico: dot -Tsvg -otree.svg tree.dot 17 de 25
ANTLRArbol Ejemplo: notación prefija Empleando las opciones por defecto 18 de 25
ANTLRArbol Ejemplo: notación prefija Opciones: -v e_prima 19 de 25
ANTLRArbol Ejemplo: notación prefija Opciones: -v e_prima -l 5 -ns -ni 20 de 25
ANTLRArbol Consideraciones adicionales Evita el uso de instrucciones break, pueden hacer que el árbol no se genere correctamente. La detección de dependencias no es perfecta; en algunos casos faltarán flechas. Utiliza las opciones -l (limitar la longitud de los atributos que se muestran) y -v (mostrar sólo los atributos de algunas variables) para evitar la generación de árboles muy grandes. Más información: http://code.google.com/p/antlrarbol/ 21 de 25
Práctica 2 Procesadores de Lenguaje 22 de 25
Práctica 2 Resumen Implementación de un traductor similar al de la práctica 1. Uso de ANTLR para implementar el analizador léxico y el analizador sintáctico. Fechas entrega: 1ª: 13 de enero de 2011 2ª: 20 de enero de 2011 Ficheros: plp2.txt, plp2.g, Main.java y clases auxiliares. Debe funcionar con JDK 6 y ANTLR 3.1. 23 de 25
Práctica 2 Especificación Especificación léxica: práctica 1 Especificación sintáctica (EBNF): S C* C class id llavei D llaved D (V M )* V double id pyc V int id pyc M void Mid pari pard llavei Decl Cuerpo llaved Mid id Mid main Decl V* Cuerpo Instr* Instr id Asig pyc Asig asig Factor Asig pari pard Factor real Factor entero Factor id 24 de 25
Práctica 2 Mensajes de error Mensajes de error léxico y sintáctico: ANTLR. Detención tras el primer error. Errores semánticos 5, 6, 7, 8 y 9: igual que en práctica 1. Más información: http://pelele.pbworks.com/; sección Práctica 2. 25 de 25