Está en la página 1de 6

Introduccin a la construccin de compiladores

M. Luisa Gonzlez Daz* Departamento de Informtica Universidad de Valladolid

1. Esquema general de un compilador


Los principios y tcnicas que se usan en la escritura de compiladores se pueden emplear en muchas otras reas. Se basan en los conceptos de teora de autmatas y lenguajes formales que se estn exponiendo en la parte terica, y consituyen un campo de aplicacin prctica bastante directo.

1.1. Objetivo de un compilador


El objetivo es, bsicamente es traducir un programa (o texto) escrito en un lenguaje fuente, que llamaremos programa fuente, en un equivalente en otro lenguaje denominado objeto, al que llamaremos programa o cdigo objeto. Si el programa fuente es correcto (pertenece al lenguaje formado por los programas correctos), podr hacerse tal traduccin; si no, se desear obtener un mensaje de error (o varios) que permita determinar lo ms claramente posible los orgenes de la incorreccin. La traduccin podr hacerse en dos formas: interpretacin: la traduccin se hace frase a frase compilacin: la traduccin se hace del texto completo Concentraremos nuestra atencin en el segundo de los mtodos.

1.2. Entorno de un compilador


Es frecuente que, adems del compilador, se utilicen otros programas para crear un cdigo objeto ejecutable. Un esquema tpico es el que se describe a continuacin. La estructura del programa fuente se escribe, usando algn programa de edicin de texto (por ejemplo vi), y puede incluir texto en lenguaje fuente y algunas rdenes para el preprocesador. Este realizar algunas tareas, como eliminacin de comentarios, expansin de macros (#IF . . . ), inclusin de archivos (#include . . . ), sustitucin de constantes (#define . . . ), o algunas extensiones del lenguaje fuente. El compilador traducir el resultado del preproceso obteniendo un programa equivalente en lenguaje ensamblador, que a su vez ser traducido por el ensamblador a cdigo mquina relocalizable, en el cual las direcciones sern relativas a ciertas posiciones de origen, y quizs algunas llamadas a rutinas no estn resueltas. Finalmente, el editor de carga y enlace (o montador, o link) resolver las llamadas a rutinas, incluyndolas a partir de otros objetos de biblioteca si procede, y obtendr direcciones absolutas, de modo que ya se dispondr del cdigo mquina absoluto ejecutable.
* Esta seccin es un resumen del captulo I de Compiladores: Principios, Tcnicas y Herramientas de Aho, Sethi y Ullman

estructura del programa fuente

preprocesador programa fuente compilador programa objeto en ensamblador ensamblador cdigo mquina relocalizable editor de carga y enlace cdigo mquina absoluto No siempre todo este proceso es necesario, y, an cuando se realice, no siempre ser observado por el usuario, de forma que una sola orden (cc programa.c, por ejemplo) puede provocar el proceso completo. Los compiladores suelen incluir opciones que permiten obtener explcitamente (o conservar) los resultados intermedios. Cada uno de los componentes es realmente un traductor. La dicultad mxima de traduccin suele estar en la compilacin propiamente dicha.

biblioteca, archivos objeto relocalizables

1.3. Estructura de un compilador


Cuando se ha hablado de programas equivalentes en distintos lenguajes (fuente y objeto), nos referimos a tener el mismo signicado (aunque no jemos ahora exactamente el concepto signicado). Por ello, la compilacin requiere dos grandes partes o tareas: anlisis : en la que se analiza el programa fuente para dividirlo en componentes y extraer de algn modo el signicado sntesis : en la que el signicado obtenido se escribe en el lenguaje objeto De las dos, la sntesis es la que requiere tcnicas ms especializadas. Durante el anlisis, se determinan las operaciones que indica el programa fuente obteniendo una representacin del signicado, normalmente en una estructura jerrquica, de rbol, en la que cada nodo representa una operacin, y cuyos hijos son los argumentos de dicha operacin. De este modo, a partir de la representacin intermedia, diferentes partes de sntesis podran obtener distintos cdigos, para distintos lenguajes objeto; tambin, a partir de distintos lenguajes fuente, con partes de anlisis adecuadas, se podra obtener una representacin intermedia, que una parte de sntesis tradujera a su vez a un nico lenguaje objeto. Nuevamente cada una de estas partes es tambin un traductor. An se repite una vez ms este esquema de traducciones intermedias en cada una de las partes: el anlisis suele dividirse en tres fases: anlisis lxico, anlisis sintctico y anlisis semntico; y la sntesis en otras tres: generacin de cdigo intermedio, optimizacin de cdigo y generacin de cdigo. Se consideran por lo tanto 6 fases en el proceso de compilacin, cada una de las cuales transforma la fuente de entrada, progresivamente, hasta conseguir el objeto nal. Por otra parte, cada una de las fases puede detectar errores, y debe informar adecuadamente de ellos. Consideraremos, por simplicar el esquema, un slo bloque de manipulacin de errores, que se usa desde cada fase, puesto que, adems, la informacin de los errores deber estar relacionada con el lugar del texto en el que se encuentra, relacin que slo puede establecer la fase de anlisis lxico. La mayor parte de los errores se detecta en las dos primeras fases.

Adems, las diferentes fases crean y acceden a una estructura de datos llamada tabla de smbolos, en la que se anotan a lo largo de las fases variadas informaciones o atributos que es necesario intercambiar; por ejemplo, las variables, con sus nombres, tipos, mbito, posicin relativa de memoria en la generacin de cdigo, etc. Estos dos ltimos elementos, aunque no sean realmente fases del proceso, tienen suciente entidad como para ser consideradas bloques de similar importancia. Anlisis A. lxico

fuente


Gestor de errores



Tablas de smbolos

A. sintctico A. semntico

      !# $& ! !" $ $%

G. cd. inter Optimizacin

objeto

Gen. cdigo Sntesis

1.4. Fases de un compilador


Analizaremos algo ms las fases usando como ejemplo simple el fragmento de cdigo Pascal posicion := inicial + velocidad * 60 1.4.1. Anlisis lxico La cadena de entrada se recibe como una sucesin de caracteres. El anlisis lxico agrupa los caracteres en secuencias con signicado colectivo y mnimo en el lenguaje, llamadas componentes lxicos (palabras o token), con ciertos atributos lxicos. En el ejemplo, se detectaran 7 : 1. el identicador posicion 2. el operador de asignacin := 3. el identicador inicial 4. el operador + 5. el identicador velocidad 6. el operador * 7. la constante numrica 60 Cada vez que se detecta un nuevo identicador, se anota una entrada en la tabla de smbolos. El lenguaje de entrada tendr un catlogo de componentes posibles, que se podrn codicar (por ejemplo mediante constantes enteras). Normalmente habr al componentes como los siguientes: 3

palabras reservadas: codicadas mediante las constantes BEGIN, END, IF, VAR . . . identicadores: codicadas mediante la constante ID, y caracterizadas por ser sucesiones de letras y dgitos que comiencen por una letra, que no pertenezcan al catlogo de palabras reservadas. Se distinguirn unas de otras a partir de ahora por su posicin en la tabla de smbolos (atributo lxico). operadores relacionales: codicados mediante la constante OPREL, que pueden ser uno de los siguientes: <=, <, >, >=, = <>. Para distinguirlos en fases posteriores se codicarn respectivamente con valores lxicos que sern otras constantes, que llamaremos MEI, MEN, MAY, MAI, IGU, DIF operadores aritmticos de un solo carcter: +, -, * . . . . Se codicarn con su propio cdigo de carcter (lo que forzar a que el resto de las constantes deban usar nmeros diferentes, pongamos superiores a 257) La salida del analizador lxico es, entonces, una sucesin de pares: el tipo de componente lxico de que se trata y cul de ellos es. Llamaremos componente lxico al primer elemento del par y valor lxico al segundo. Por lo tanto, la salida del analizador lxico para el ejemplo sera: <ID, 25> <OPASIGN,> <ID, 24> <+,> <ID, 26> <*,> <CTE, 60> mientras que la tabla de smbolos tendr entradas para los tres identicadores (que realmente se habrn detectado antes, al leer la seccin de declaracin de variables, momento en el que se habrn instalado) 1 ... 24 25 26 ... 1.4.2. Anlisis sintctico Los componentes lxicos se agrupan para formar frases. El valor lxico de los componentes es en este momento irrelevante. Normalmente las frases se representan mediante una estructura de rbol sintctico, siguiendo reglas que describen el lenguaje. Las reglas determinarn en el caso del ejemplo un rbol como el siguiente, en el que se muestra que la expresin es en primera instancia una suma y no un producto, dadas las precedencias de los operadores implicados. ... inicial posicion velocidad ... ... ... ...

 

proposicin de asignacin  :=

ID 25 (posicion)



  expresin    
+



expresin

ID 24 (inicial) expresin

 expresin     
* expresin CTE (60)

ID 26 (velocidad)

La divisin entre anlisis lxico y sintctico es algo arbitraria. Normalmente el criterio de divisin es la simplicacin de ambas tareas, dejando las construcciones anidadas (parntesis, operadores . . . ) para el anlisis sintctico que utilizar tcnicas algo ms complejas que el lxico, que suele limitarse a construcciones de tipo regular. 1.4.3. Anlisis semntico En esta etapa se revisa el resultado del anlisis sintctico, recopilando por ejemplo informacin de tipos y construyendo una representacin an ms abstracta. En el ejemplo que estamos considerando, en esta fase se anotar el tipo de los identicadores cuando se revise la declaracin de variables (var inicial, posision, velocidad: real), de forma que la tabla de smbolos ahora contendr ms informacin: 1 ... 24 25 26 ... ... ... inicial posicion velocidad ... real real real ... ... ... ...

Por otra parte, puesto que la expresin 60 corresponde a un entero, ser necesario transformar su valor en real antes de realizar las operaciones (los algoritmos que operan con reales y enteros son distintos, dada la representacin interna de los datos). La salida del analizador semntico puede ser entonces un rbol de sintaxis abstracta, en el que, ms que la estructura sintctica de la entrada, aparece la estructura de operaciones a realizar, como el siguiente:

  
ID 25 (posicion)

:=



    

     
*

ID 24 (inicial)

  
InToReal 60

ID 26 (velocidad)

1.4.4. Generacin de cdigo intermedio Se genera en esta fase un cdigo intermedio para una mquina abstracta, y es posible que explcitamente . Esta representacin debe ser fcil de producir y fcil de traducir al programa objeto. Puede tener diversas formas. Una posible es la llamada cdigo de tres direcciones, que consiste en una secuencia de intrucciones, cada una de las cuales involucra a lo sumo un operador (unario o binario), adems de la asignacin tres direcciones a lo sumo (las de los operandos y la del resultado)

Adems, deber generar nombres temporales para almacenar los resultados intermedios. Para el ejemplo, la salida de esta fase podra ser: temp1 := InToReal(60) temp2 := id26 * temp1 temp3 := id24 + temp2 id25 := temp3 1.4.5. Optimacin de cdigo Se trata en esta fase de mejorar el cdigo, en el sentido de reducir la cantidad de resursos (tiempo y memoria) necesarios. Algunas optimaciones son triviales, como por ejemplo hacer algunas transformaciones directamente en la compilacin, en lugar de dejarlo para la ejecucin (sustituir InToReal(60) por 60.0). Otras pueden requerir un trabajo mucho mayor, pero mejorar signicativamente la eciencia, normalmente a costa de alejarse bastante del cdigo original, como eliminar cdigo inactivo (inaccesible), eliminar vaiables intermedias o resituar sentencias independientes de un bucle fuera de ste. Muchos compiladores permiten elegir la cantidad de optimacin a realizar o no hacerla. Para el ejemplo, una mejora sencilla lo convertira en: temp1 := id26 * 60.0 id25 := id24 + temp2 1.4.6. Generacin de cdigo En esta fase nal se genera por n el cdigo objeto, normalmente cdigo mquina relocalizable o ensamblador. Se seleccionan entonces posiciones de memoria relativas o registros para las variables y cada sentencia del cdigo intermedio se traduce a una secuencia de instrucciones que ejecutan la tarea. Por ejemplo: MOVF 0068, R2 MULF #60.0, R2 MOVF 0060, R1 ADDF R2, R1 MOVF R1, 0064 suponiendo que en la asignacin de posicin relativa de las variables se hubieran asociado 60H, 64H y 68H a las variables que en la tabla de smbolos ocupan las entradas 24, 25 y 26 respectivamente (valores que se habrn anotado tambin en las casillas correspondientes de la tabla de smbolos).

También podría gustarte