Processadors de Llenguatge II Compiladores Que es un compilador Un traductor es cualquier programa que toma un texto escrito en un lengiaje y da como salida en otro lenguaje(llamado objeto) texto lenguaje fuente TRADUCTOR texto lenguaje objeto Que es un compilador Source program Compiler input Target program output Que es un interprete Un interprete executa directamente las operaciones en el programa fuente. Source program input INTERPRETER output Hybrid Compiler Source program Translator Intermediate program input Virtual Machine output Java: Bytecodes Just in time compilers translate bytecodes into ML just before runing IP Intérpretes vs. compiladores Inicialmente interpretes eran mas comunes hoy en dia, compiladores mas comunes Porque? Intérpretes vs. compiladores Inicialmente interpretes eran mas comunes mem(programa fuente + interprete) ≤ mem(compilador) hoy en dia, compiladores mas comunes Compila una vez, ejecuta muchas veces Ejecucion programa objeto mas rapida Compilador tiene una vision mas global del programa Interprete sin embargo da mejor diagnostico de errores Tipos de compiladores Ensamblador: lenguaje fuente = ensamblador Compilador con montador: compila modulos independientes y luego los enlaza Autocompilador: escrito en el mismo lenguaje que va a compilar Descompilador: realiza proceso inverso a la compilacion. Estructura de un compilador Analisis léxico Analizador léxico = scanner Lee caracteres uno a uno y forma grupos de caracteres con alguna relación entre sí (tokens) Cada token es una secuencia de caracteres tratados como una unica entidad. Los tokens son la entrada para la siguiente etapa del compilador. Dos tipos de tokens: palabras reservadas (p.e. if, while, begin) cadenas no especificas (p.e. identificadores, constantes) Frecuentemente va unido al analizador sintáctico (p.e. como subrutina) Analisis sintáctico Analizador sintáctico = parser Recibe como entrada los tokens que le pasa el analizador lexico Comprueba si los tokens llegan en order correcto (orden permitido por el lenguaje) La salida es un arbol sintáctico (arbol de parse). Cuando el programa fuente es incorrecto (sintacticamente) el analizador sintactico es el responsable de producir un mensaje de error. Analisis semántico Analizador semántico es dificil de formalizar Comprueba que lo que el significado de lo que se va leyendo es válido. P.e. determina el tipo de los resultados intermedios, si los operandos son validos, si son compatibles entre si. En caso de los operadores polimórficos (un símbolo con varios significados), el analizador semantico detremina cual es el aplicable. P.e. A := B + C en Pascal Código intermedio Una empresa que implementa un compilador normalmente implementa mas de uno (p.e. C de GNU). Para evitar implementar M*N compiladores (M fuentes, N objetos), la solución es utilizar un lenguaje intermedio. Asi solo hay que construir M programas que traduzcan al lenguaje intermedio (los front ends) y N que traduzcan del intermedio a cada lenguaje objeto (los back ends). Lenguaje intermedio es suficientemente sencillo para luego generar código de máquina. Código intermedio WHILE (A>B) AND (A<=2*B-5) DO A:=A+B L1: L2: L4: L3: IF A>B GOTO L2 GOTO L3 T1:=2*B T2:=T1-5 IF A<=T2 GOTO L4 GOTO L3 A:=A+B GOTO L1 … (* nivel mas alto que ensamblador *) (* pero mas sencillo que pascal *) Optimizacion de Codigo Es posible realizar mejoras en al código intermedio y el código objeto. Optimizacion del código intermedio es independiente del lenguaje fuente y lenguaje objeto. Optimizacion del código objeto suele incluir optimizaciones dependiente de la maquina objeto. Optimizacion de Codigo Fragmento del ejemplo anterior quedaria asi: L1: L3: IF A<=B GOTO L3 T1:=2*B T2:=T1-5 IF A>T2 GOTO L3 A:=A+B GOTO L1 … Optimizacion de Codigo Eliminar expresiones comunes: A:=B+C+D E:=B+C+F Quedaria asi: T1:=B+C A:=T1+D E:=T1+F Generación de código objeto En esta parte, el código intermedio optimizado es traducido a una secuencia de instrucciones en ensamblador o en codigo de maquina del procesador que nos interese. Por ejemplo: A:=B+C se convertira en: LOAD B ADD C STORE A Existen técnicas para mejorar el codigo objeto (normalmente no óptimo), p.e. utilizar al maximo los registros de acceso rapido en vez de direcciones de memoria. Tabla de símbolos Un compilador necesita guardar y usar la informacion de los objetos que va encontrando en el texto fuente. P.e. variables, declaraciones de tipos. Esta información se almacena en una estructura de datos interna: tabla de símbolos El compilador debe desarrollar funciones para manipular esta tabla. P.e. insertar, borrar, … Accesos a la tabla deben ser rapidos.