CUP Diseño de compiladores CUP Cup es un generador de analizadores sintácticos LALR Recibe de entrada un archivo con la estructura de la gramática y su salida es un parser escrito en Java Manual oficial: http://www.cs.princeton.edu/~appel/modern/jav a/cup/manual.html Un archivo CUP tiene las siguientes secciones Imports Java Código del usuario para el parser Código del usuario para las acciones de la gramática Declaración de variables para la gramática La gramática en si (las producciones de la misma) Código del usuario para el parser El código Java generado por la herramienta es difícil de modificar Aquí podemos declarar métodos y variables que pensamos usar en la clase resultante Si se declaran variables o métodos públicos en esta sección, estos podrán ser accedidos por otras clases parser code {: /* Codigo del parser*/:} Código del usuario para las acciones de la gramática En esta sección pueden declararse métodos o variables que pueden ser usados por las acciones de la gramática (manejo de errores, logging, etc.) Se declara de la siguiente forma: action code {:/*Codigo para las acciones*/:} Declaración de variables para la gramática Estas pueden ser de dos tipos: Variables Terminales <terminal> Variables No Terminales <non terminal> Las variables terminales serán todos los símbolos terminales de la gramática Las variables no terminales serán todas las variables que representaran producciones 1
Declaración de variables para la gramática La sintaxis de declaración es la siguiente: <tipo de variable> <tipo de dato> <id de la variable> Tipo de dato, puede ser cualquier tipo de datos Java primitivo o complejo Si no lo especificamos, CUP utilizara por defecto el tipo Symbol (recordar ejemplo JFlex) Gramática En este sección se escriben las producciones de la misma Pueden ser de la forma: <no terminal> ::= <terminales o no-terminales>; <no terminal> ::= <terminales o no-terminales> <terminales o no-terminales> ; Un ejemplo Un ejemplo Otro ejemplo Un compilador sencillo de expresiones Soporta +, -, * y / Maneja enteros, flotantes e identificadores Construiremos el analizador léxico y el analizador sintáctico Lo vamos a embeber dentro de un proyecto Eclipse (para posterior reutilización) 2
Proyecto Eclipse Creamos un proyecto Eclipse estándar (Aplicación Java de consola) Separamos directorios src (fuentes) y bin (clases) Creamos un directorio lib (para almacenar bibliotecas externas) Creamos una carpeta language para almacenar los archivos relacionados con JFlex y Cup Sección Java del compilador Relacionada al modelado del lenguaje y al control del proceso de compilación Biblioteca de soporte utilizada para la ejecución del programa (Al ejecutar el parse en runtime necesitamos esto) Todo lo relacionado a la generación de los elementos de análisis (léxico y sintáctico) va en esta carpeta Físicamente, la dependencia anterior va en esta carpeta 3
Archivo con la especificación sintáctica del lenguaje (para CUP) Archivo con la especificación léxica del lenguaje (para JFlex) Script ANT para la ejecución del CUP y JFlex Modelado del lenguaje El proceso de análisis genera esta estructura para posterior procesamiento Clases generadas por el proceso de análisis (léxico y sintáctico) Tester 4
Fuente de JFlex Modelo del lenguaje Representación intermedia Fuente de JFlex Símbolos de la gramática Precedencia 5
Fuente de CUP Fuente de CUP Que hace nuestro compilador? Leer el fuente (en este caso un string, pero puede ser un archivo) Analizarlo lexicalmente Analizarlo sintácticamente Construir una estructura que nos permita procesar lo leído En este caso, solo lo recorremos para mostrarlo en otro formato Nuestro compilador es mas bien un traductor 6