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

biblioteca,
archivos objeto relocalizables

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 dificultad mxima de traduccin
suele estar en la compilacin propiamente dicha.

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 significado (aunque no fijemos ahora exactamente el concepto significado). 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 significado
sntesis : en la que el significado 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 significado,
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 final.
Por otra parte, cada una de las fases puede detectar errores, y debe informar adecuadamente de
ellos. Consideraremos, por simplificar 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 suficiente entidad como para ser consideradas bloques de similar importancia.


 


fuente


Gestor
de
errores

objeto


 
 


   




Anlisis
A. lxico

A. sintctico

A. semntico

Optimizacin 








G. cd. inter




Gen. cdigo

Tablas
de
smbolos

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 significado colectivo y mnimo en el lenguaje, llamadas componentes
lxicos (palabras o token), con ciertos atributos lxicos. En el ejemplo, se detectaran 7 :
1. el identificador posicion
2. el operador de asignacin :=
3. el identificador inicial
4. el operador +
5. el identificador velocidad
6. el operador *
7. la constante numrica 60
Cada vez que se detecta un nuevo identificador, se anota una entrada en la tabla de smbolos.
El lenguaje de entrada tendr un catlogo de componentes posibles, que se podrn codificar (por
ejemplo mediante constantes enteras). Normalmente habr al componentes como los siguientes:
3

palabras reservadas: codificadas mediante las constantes BEGIN, END, IF, VAR . . .
identificadores: codificadas 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: codificados mediante la constante OPREL, que pueden ser uno de
los siguientes: <=, <, >, >=, = <>. Para distinguirlos en fases posteriores se codificarn
respectivamente con valores lxicos que sern otras constantes, que llamaremos MEI, MEN,
MAY, MAI, IGU, DIF
operadores aritmticos de un solo carcter: +, -, * . . . . Se codificarn 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 identificadores (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
...

...

...

inicial
posicion
velocidad

...
...
...

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.

 

proposicin
de asignacin


ID
25 (posicion)

:=



expresin

 
expresin
 
 
+

 expresin
 

 

ID
24 (inicial) expresin

ID
26 (velocidad)



expresin
CTE
(60)

La divisin entre anlisis lxico y sintctico es algo arbitraria. Normalmente el criterio de divisin es la simplificacin 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 identificadores 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)

ID
26 (velocidad)

 

InToReal
60

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 significativamente la eficiencia, 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 final se genera por fin 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