Академический Документы
Профессиональный Документы
Культура Документы
1.- INTRODUCCION. 2.- COMPILADOR SIMPLE ORIENTADO A LA SINTAXIS. 3.- ANALISIS LEXICO. 4.- ANALISIS SINTACTICO. 5.- TRADUCCION ORIENTADA A LA SINTAXIS. 6.- GENERACION DE CODIGO INTERMEDIO.
INTRODUCCION
Los lenguajes de programacion son notaciones empleadas para describir los calculos para las computadoras y personas. El software que se ejecuta en las computadoras ha sido escrito en algun lenguaje de programacion. Antes de ejecutar el programa debe ser traducido al formato en el que una computadora lo puede ejecutar. Los sistemas de software encargados de la traduccion se denominan compiladores. Este curso trata de cmo disear e implementar compiladores. Los fundamentos son aplicables para la construccion de compiladores para una amplia gama de lenguajes y maquinas. Los principios y tecnicas de diseo de compiladores tambien son aplicables a otras areas de sistemas. La contruccion de compiladores esta relacionada con los lenguajes de programacion, la arquitectura de las maquinas, la teoria de lenguajes, los algoritmos y la ingenieria de software.
INTRODUCCION
PROCESADORES DE LENGUAJE Compilador: programa que puede leer un programa en un lenguaje fuente y traducirlo a un programa equivalente en otro lenguaje destino. El compilador reporta los errores del programa fuente detectados en el proceso de traduccion. Programa Fuente Programa Destino
Compilador
Si el programa destino es un programa ejecutable en lenguaje de maquina, el usuario lo puede ejecutar para procesar entradas y producir salidas. Entrada Programa Destino salida
Interprete: Es otra clase comun de procesador de lenguaje. No produce un programa destino como una traduccion. Aparenta ejecutar directamente las operaciones especificadas en el programa fuente con las entradas del usuario. Programa Fuente Salida Entrada CONTINUACION
Traductor
Salida
Programa Fuente en Java: puede compilarse primero a un formato intermedio llamado bytecodes. Luego una maquina virtual los interpreta. Ventaja: los bytecodes compilados en una maquina, pueden interpretarse en otra (talvez atraves de una red). Ciertos compiladores Java para un procesamiento mas rapido de entradas a salidas, conocidos como just in time, traducen los bytecodes en lenguaje de maquina justo antes de ejecutar el programa intermedio para procesar la entrada.
CONTINUACION:
LA ESTRUCTURA DE UN COMPILADOR
Hemos considerado al compilador como una caja simple que trasforma un programa fuente a un programa destino sematicamente equivalente. Al analizar la caja se pueden distinguir dos grandes etapas: una de analisis y otra de sintesis. El analisis divide al programa fuente en componentes y usa esta informacion para crear una representacion intermedia del programa fuente.
Si se detecta mal formacion del programa o semantica incorrecta, deben emirse mensajes de error, para que el usuario los corrija. La informacion obtenida en el analisis se guarda en una estructura llamada tabla de simbolos La sintesis construye el programa destino requerido, en base a la representacion intermedia y la informacion de la tabla de simbolos. La parte de analisis se conoce como FRONT-END y la parte de sintesis se conoce como BACK-END. Examinando el proceso de compilacion con mayor detalle se puede comprender que opera como una secuencia de fases, cada de las cuales transforma la representacion del programa fuente de una representacion a otra. En la actualidad se tiene una descomposicion tipica de las fases de un compilador que son empleadas de manera general en la construccion de compiladores. En la practica las fases pueden agruparse. La informacion de la tabla de simbolos pude usarse en todas las fases de la compilacion.
FASES DE UN COMPILADOR
Flujo de caracteres Analizador lexico Flujo de tokens Analizador sintactico Arbol sintactico Administrador de la tabla de simbolos Analizador semantico Arbol sintactico Generador de codigo intermedio Representacion intermedia Optimizador de codigo Codigo maquina destino Generador de codigo Codigo de maquina destino Manejador de errores
El analizador lexico lee el flujo de caracteres que componen el programa fuente y los agrupa en secuencia significativas denominadas lexemas. Para cada lexema el analizador lexico produce como salida un token de la forma: (nombretoken, valor-atributo) que pasa a la siguiente fase de analisis sintactico. El nombre-token es un simbolo abstracto empleado en el analisis sintactico. El valor atributo apunta a una entrada en la tabla de simbolos para dicho token. La informacion de la tabla de simbolos se usa en el analisis semantico y generacion de codigo intermedio. Ejemplo: suponemos que el programa fuente esta constituido por la sentencia de asignacion: posicion = inicial + velocidad * 60 Los caracteres de esta sentencia podrian agruparse en los siguientes lexemas y mapearse a los tokens correspondientes, que se pasan al analizador sintactico 1.- posicion: token de la forma (id, 1) id es simbolo abstracto representa identificador; 1 apunta a la tabla de simbolos para posicion y contiene informacion sobre su nombre y tipo. 2.- Simbolo de asignacion = , es un lexema asiganado al token ( = ) no requiere valor de atributo, por conveniencia el nombre del lexema es igual al nombre del simbolo abstracto. 3.- inicial: es tambien lexema de la forma (id, 2) donde 2 apunta a la entrada en la tabla de simbolos para inicial. 4.- +: es un lexema que se asigna al token ( + ) 5.- velocidad: es tambien lexema de la forma ( id, 3) done 3 apunta a la entrada en la tabla de simbolos para velecidad. 6.- *: es un lexema que se asigna al token ( * ) 7.- es un lexema que se asigna al token ( 60 ) El analizador lexico ignora los espacios en blanco que separan los lexemas .
ANALISIS SEMANTICO
El analizador semantico usa el arbol sintactico y la informacion de la tabla de simbolos para comprobar la consistencia semantica del programa fuente con la definicion del lenguaje Tambien recopila informacion de tipo y la guarda ya sea en el arbol sintactico o en la tabla de simbolos, para usarla luego en la generacion de codigo intermedio. Una parte importante del analisis semantico es la comprobacion de tipos, donde se comprueba que los operandos de una operacin sean del mismo tipo, o del tipo correcto. El lenguaje de programacion puede permitir cietas conversiones de tipo denominadas coerciones de tipo. Un ejemplo sobre coercion de tipo se observa en el grafico sobre las fases de la compilacion, cuando la constante 60 se convierte a tipo flotante. La conversion es necesaria ya que los identificadores posicion, inicial y velocidad se supone han sido declarados de coma foltante. La necesidad de la conversion detecta el analizador semantico cuando descubre que el operador * tiene un operando de coma flotante que es velocidad y el 60 es de tipo entero; entonces aplica la conversion de entero a real a la constante 60. La conversion es realizada por el operador intofloat, que etiqueta a un nodo.
OPTIMIZACION DE CODIGO
La fase de optimizacion de codigo independiente de la maquina , trata de mejorar el codigo intermedio, de tal manera que se produzca un mejor codigo destino, lo que generalmente implica que el codigo sea mas rapido; pero tambien pueden lograrse otros objetivos como codigo destino mas corto, oque consuma menos poder. Ejemplo: Un algoritmo directo genera el codigo como en el grafico de las fases de la compilacion, empleando una instruccin para para operador de la representacion tipo arbol, que produjo el analizador semantico. Luego la fase de optimizacion de codigo trata de mejorar el codigo, como en el ejemplo de las fases de la compilacion, cuando el optimizador deduce que la conversion del 60 a coma flotante se puede realizar en la compilacion, razon por la cual se puede eliminar la operacin inttofloat, sustituyendo al entero 60 por el numero de punto flotante 60.0; pero adicionalmente debido a que t3, es usado solo una vez para transmitir el valor a id1, se reduce la secuencia de instrucciones como en el ejemplo de la s fases de la compilacion. Hay mucha variedad de optimizaciones de codigo que realizan los distintos compiladores y aquellos que realizan la mayor optimizacion se les denomina compiladores optimizadores, pero invierten mucho tiempo. Hay optimizaciones simples que mejoran de forma considerable el tiempo de ejecucuion del programa destino sin reducir demasiado la velocidad de compilacion.
GENERACION DE CODIGO
El generador de codigo recibe como entrada la representacion intermedia que representa semanticamente al programa fuente y la traduce a lenguaje destino. Si el lenguaje destino es codigo de maquina, se seleccionan los registros o ubicaciones de memoria para cada una de las variables empleadas por el programa. Luego las instrucciones intermedias se traducen en secuencias de instrucciones de maquina que realizan la misma tarea. Se debe elegir con cuidado los registros para guardar las variables. En el ejemplo tenemos lo siguiente: LDF R2, id3 MULF R2, #60.0 LDF R1, id2 ADDF R1, R2 STF id1, R1 El primer operando de cada instruccionespecifica un destino; la F en cada instruccin indica que se trata de numeros de coma flotante. El # indica que se va a tratar como una constante inmediata.
* 60
+ * inttofloat