Vous êtes sur la page 1sur 17

UNIDAD 2

ESTRUCTURA DE COMPILADORES
OBJETIVO GENERAL: Estudiar y aplicar a las aplicaciones de software, las
herramientas de trabajo y desarrollo de compiladores, para as poder entender
con claridad y dar la importancia a cada una de las fases que intervienen en un
compilador, y de esta manera entender de mejor forma la optimizacin de
cdigo.

OBJETIVOS ESPECFICOS:
Conocer las definiciones de compiladores y de cada una de sus partes
Entender el funcionamiento e importancia de los compiladores en los
lenguajes de programacin actuales.
Estudiar las ventajas y desventajas de los compiladores v/s los
intrpretes.
Analizar la importancia de la optimizacin de cdigo en el desarrollo de
software a nivel comercial.

COMPILADORES
El nombre de compilador viene desde los aos 50 del siglo pasado, utilizado
por Murray Hooper. En esa poca la compilacin se vea como la compilacin
de una secuencia de subprogramas tomados de una librera (biblioteca) de
programas.
En la actualidad a la compilacin se le llama programacin automtica.
Los primeros compiladores modernos se desarrollaron desde finales de los
aos 50, como el FORTLAN.

Se utilizan para editores de texto, lenguajes de consulta, transformacin de


datos de ficheros entre otros.

Definicin de un compilador: Es un programa que lee un programa (fuente)


en un lenguaje. Lo traduce a otro lenguaje equivalente con otro lenguaje
(objeto). Tambin da mensajes de error, realiza determinadas correcciones
(recuperacin de errores) y puede optimizar el cdigo generado.

PROGRAMA FUENTE

COMPILADOR

Programa Objeto

Errores

Permite programar independientemente a la mquina


Lo que un compilador no comprueba. Cuando un programa infringe alguna
de las normas del lenguaje (lxica, sintctica o semntica) el traductor no
puede traducir correctamente el programa, pues no est escrito en el lenguaje
que el conoce. No obstante, que el programa cumpla todas las reglas del
lenguaje no garantiza que el programa sea correcto, an quedan los errores de
concepto, y estos son errores que el traductor no puede detectar. Por ejemplo,
el siguiente programa para calcular la media de dos nmeros es correcto para
un compilador de C++.
scanf(%f,&B);
C=((A+B)/38);
printf (%f,C);

Pero, evidentemente, no es un programa correcto, pues no consigue su


propsito que era calcular la media de dos nmeros, tiene un error de concepto
(dividir por 38 y no por 2).

Tratamientos de los errores. Durante la fase de anlisis, que es donde se lee


el programa fuente y se entiende (comprobando adems todas las reglas del
lenguaje), el compilador realiza una de sus funciones ms importantes (y ms
complicadas) que es tratar los errores que se produzcan de la mejor manera
que sepa.
Hay una solucin bastante fcil que consiste en leer el programa fuente
secuencialmente comprobando todas las reglas (primero las lxicas, despus
las sintcticas y por ltimo las semnticas), y si en un momento dado se
incumple alguna de ellas se informa de qu regla se incumpli en que lnea del
programa, abortando el proceso de traduccin. Pero esto no es lo que hacen
los compiladores, conoces alguno que no sea capaz de encontrar varios (y no
solo uno) errores de compilacin en una sola ejecucin?, los hay pero esta no
es la solucin ms profesional, ya que si estamos utilizando un compilador
externo que tarda 2 minutos en compilar nuestro programa y tenemos que
ejecutarlo para ver que nos hemos olvidado declarar la variable Contador,
arreglarlo, volver a compilar para ver que tambin se nos olvid un punto y
coma, arreglarlo, ... cuando podra habernos informado de todos los errores en
la primera compilacin, posiblemente nos acordemos de la familia del que-sellama-programador y tuvo la feliz idea de Si con un solo error vas que te
matas.
Pero pensemos un momento, que tiene que hacer entonces un compilador
cuando se produce un error?, Si escribimos en nuestro programa (por ejemplo
en Visual C++):
Mijugada_es = mejor que la_tuya;

El compilador no puede saber que es lo que pretendamos escribir: si es una


sentencia, si son varias y se nos olvido separarlas por puntos y coma, si es un
comentario que se nos olvido iniciar, etc. Y qu hacen los compiladores en
este caso? Pues informarnos, no de uno, sino de cuatrocientos veintisiete
errores de compilacin, por que? Pues porque no puede adivinar cual es el
error que realmente hemos cometido, y si quiere seguir compilando para poder
detectar ms errores en la misma ejecucin debe hacer una suposicin. Y es
realmente muy difcil hacer una suposicin y que esta sea correcta, quiz lo
ms fcil es suponer que toda la parte errnea era un comentario, y pasar de
ella, pero si cometimos un error al declarar una variable y el compilador supone
que esa declaracin es un comentario sin importancia, se producirn un
montn de errores por todo el programa cada vez que utilicemos esa variable
que, para el compilador, no ha sido declarada. An as, las cosas no son tan
sencillas, ya que cuando se produce un error debemos decidir cuanto cdigo
vamos a ignorar cerca del error, y decidir tambin cuando el cdigo vuelve a
tener sentido tras el error. Los lenguajes de alto nivel modernos suelen tener un
smbolo para separar sentencias, y su principal cometido es precisamente este,
cuando se produce un error, se supone que la sentencia actual no es vlida y
se ignora todo lo que venga hasta el siguiente smbolo separador (que en C++
es un punto y coma).

LA ESTRUCTURA Y FUNCIONAMIENTO DE UN COMPILADOR

La interaccin entre los algoritmos utilizados por las fases de un compilador y


las estructuras de datos que soportan estas fases es, naturalmente, muy fuerte.
El autor del compilador se esfuerza por implementar estos algoritmos de una
manera tan eficaz como sea posible, sin aumentar demasiado la complejidad.
De manera ideal, un compilador debera poder compilar un programa en un
tiempo proporcional al tamao del programa, es decir, en 0(n) tiempo, donde n
es una medida del tamao del programa (por lo general el nmero de
caracteres).

Algunas de las principales estructuras de datos que son necesarias para las
fases como parte de su operacin y que sirven para comunicar la informacin
entre las fases son las siguientes:

TOKENS: Cuando un rastreador o analizador lxico rene los caracteres en un


token, generalmente representa el token de manera simblica, es decir, como
un valor de un tipo de datos enumerado que representa el conjunto de tokens
del lenguaje fuente. En ocasiones tambin es necesario mantener la cadena de
caracteres misma u otra informacin derivada de ella, tal como el nombre
asociado con un token identificador o el valor de un token de nmero. En la
mayora de los lenguajes el analizador lxico slo necesita generar un token a
la vez (esto se conoce como bsqueda de smbolo simple). En este caso se
puede utilizar una variable global simple para mantener la informacin del
token. En otros casos (cuyo ejemplo ms notable es FORTRAN), puede ser
necesario un arreglo de tokens.

RBOL SINTCTICO Si el analizador sintctico genera un rbol sintctico, por


lo regular se construye como una estructura estndar basada en un apuntador
que se asigna de manera dinmica a medida que se efecta el anlisis
sintctico. El rbol entero puede entonces conservarse como una variable
simple que apunta al nodo raz. Cada nodo en la estructura es un registro
cuyos campos representan la informacin recolectada tanto por el analizador
sintctico como, posteriormente, por el analizador semntico. Por ejemplo, el
tipo de datos de una expresin puede conservarse como un campo en el nodo
del rbol sintctico para la expresin. En ocasiones, para ahorrar espacio,
estos campos se asignan de manera dinmica, o se almacenan en otras
estructuras de datos, tales como la tabla de smbolos, que permiten una
asignacin y desasignacin selectivas. En realidad, cada nodo de rbol
sintctico por s mismo puede requerir de atributos diferentes para ser
almacenado, de acuerdo con la clase de estructura del lenguaje que represente
(por ejemplo, un nodo de expresin tiene requerimientos diferentes de los de
un nodo de sentencia o un nodo de declaracin). En este caso, cada nodo en el

rbol sintctico puede estar representado por un registro variable, con cada
clase de nodo conteniendo solamente la informacin necesaria para ese caso.

TABLA DE SMBOLOS Esta estructura de datos mantiene la informacin


asociada con los identificadores: funciones, variables, constantes y tipos de
datos. La tabla de smbolos interacta con casi todas las fases del compilador:
el rastreador o analizador lxico, el analizador sintctico o el analizador
semntico puede introducir identificadores dentro de la tabla; el analizador
semntico agregar tipos de datos y otra informacin; y las fases de
optimizacin y generacin de cdigo utilizarn la informacin proporcionada por
la tabla de smbolos para efectuar selecciones apropiadas de cdigo objeto.
Puesto que la tabla de smbolos tendr solicitudes de acceso con tanta
frecuencia, las operaciones de insercin, eliminacin y acceso necesitan ser
eficientes, preferiblemente operaciones de tiempo constante. Una estructura de
datos estndar para este propsito es la tabla de dispersin o de clculo de
direccin, aunque tambin se pueden utilizar diversas estructuras de rbol. En
ocasiones se utilizan varias tablas y se mantienen en una lista o pila.

TABLA DE LITERALES: La bsqueda y la insercin rpida son esenciales


tambin para la tabla de literales, la cual almacena constantes y cadenas
utilizadas en el programa. Sin embargo, una tabla de literales necesita impedir
las eliminaciones porque sus datos se aplican globalmente al programa y una
constante o cadena aparecer slo una vez en esta tabla. La tabla de literales
es importante en la reduccin del tamao de un programa en la memoria al
permitir la reutilizacin de constantes y cadenas. Tambin es necesaria para
que el generador de cdigo construya direcciones simblicas para las literales y
para introducir definiciones de datos en el archivo de cdigo objetivo.

CDIGO INTERMEDIO De acuerdo con la clase de cdigo intermedio (por


ejemplo, cdigo de tres direcciones y cdigo P) y de las clases de
optimizaciones realizadas, este cdigo puede conservarse como un arreglo de
cadenas de texto, un archivo de texto temporal o bien una lista de estructuras
ligadas. En los compiladores que realizan optimizaciones complejas debe
ponerse particular atencin a la seleccin de representaciones que permitan
una fcil reorganizacin.

ARCHIVOS TEMPORALES Al principio las computadoras no posean


suficiente memoria para guardar un programa completo durante la compilacin.
Este problema se resolvi mediante el uso de archivos temporales para
mantener los productos de los pasos intermedios durante la traduccin o bien
al compilar al vuelo, es decir, manteniendo slo la informacin suficiente de
las partes anteriores del programa fuente que permita proceder a la traduccin.
Las limitantes de memoria son ahora un problema mucho menor, y es posible
requerir que una unidad de compilacin entera se mantenga en la memoria, en
especial si se dispone de la compilacin por separado en el lenguaje. Con todo,
los compiladores ocasionalmente encuentran til generar archivos intermedios
durante alguna de las etapas del procesamiento. Algo tpico de stos es la
necesidad de direcciones de correccin hacia atrs durante la generacin del
cdigo. Por ejemplo, cuando se traduce una sentencia condicional tal como:

If x = O then... else...

debe generarse un salto desde la prueba para la parte bicondicional else


antes de conocer la ubicacin del cdigo para el else:

CMP X,O
JNE NEXT ;; ubicacin del NEXT an no conocida

<cdigo para la parte then


NEXT:
<cdigo para la parte else>

Por lo regular debe dejarse un espacio en blanco para el valor de NEXT, el cual
se llena una vez que se logra conocer el valor. Esto se consigue fcilmente con
el uso de un archivo temporal.

Las partes de un Compilador: El compilador tiene seis fases las cuales las
dividimos de la siguiente forma:

LAS SEIS FASES DE UN COMPILADOR

PROGRAMA FUENTE

ANALISIS
LEXICOGRAFICO

Stream de tokens

ANALISIS
SINTACTICO

FRONT END
rbol de parser

ANALISIS
SEMANTICO

ANLISIS

rbol semntica

MANEJO
DE
ERRORES

GENERACIN DE
CDIGO
INTERMEDIO

TABLA
DE
SIMBOLOS

Intermedio

OPTIMIZACIN DE
CDIGO
SINTESIS
BACK END

GENERACIN DE
CDIGO

PROGRAMA OBJETO

Las fases de manejo de errores y tabla de smbolos interactan con todas las
dems.

Generacin de cdigo: Si ha pensado que lo ms complicado de un


compilador no es eso de los errores, ni el ver si se cumplen o no todas las
reglas, sino que es el generar cdigo destino, est en lo cierto.

Un compilador, en la fase de sntesis, con la informacin sobre el programa ya


estructurada, suele dividir el trabajo de generar cdigo destino en varias partes.
En la primera ya genera todo el cdigo, pero no el definitivo, es decir, se
traduce todo el programa completo de golpe, pero no se traduce directamente
al cdigo destino, sino que se pasa a un cdigo intermedio, similar al cdigo
mquina, aunque ms sencillo y potente, que por decirlo as, est a medio
camino entre el lenguaje fuente que tenamos que traducir y el lenguaje destino
que tenemos que generar. Algunos de los motivos para hacer esto son: es ms
fcil generar este cdigo que el cdigo destino directamente (pues se disea
con ese fin), y se puede optimizar ms fcilmente este cdigo que el cdigo
destino.

FUNCIONES DE LAS FASES


ANALISIS LEXICOGRAFICO O SCANNER

LOS
GENERAD
ORES DE

agrupa caracteres en tokens, es decir, la unidad bsica de


la sintaxis.
los strings de caracteres que forman un token tam bien
elimina espacios en blanco(tabs y returns)
un aspecto clave en su diseo es la velocidad.
produce mensajes de errores lexicografitos e intenta
recuperarse.

ETAPA

DEL
TRABAJO
EN ESTA

MECANIZA
N GRAN
PARTE

SCANNER
S

se conocen con el nombre de lexema.

GENERAD
ORES DE
PARSERS

LOS

ANALISIS SINTACTICO O PARSER

agrupa los tokens en frases gramaticales.


representa las frases gramaticales como un rbol de
parser.
cuando se le incorpora el mecanismo correspondiente
intenta detectar y recuperarse de los errores.

TRABAJO
DE ESTA
ETAPA

MECANIZA
N GRAN
PARTE
DEL

produce mensajes significativos de errores sintcticos

ANALISIS SEMANTICO O CHEQUEADOR DE TIPOS

controla los errores semnticas del programa:


* Variables usadas y no definidas.
* Operndoos de tipos compatibles.
* Invocaciones a procedimientos con el nmero y tipo correctos de
Parmetros.
* Reales no pueden ser usados como subndices de arreglos.
* Conversin de tipos cuando las coersiones son permitidas.
para realizar esta tarea consulta la tabla de smbolos.
GENERADOR DE CDIGO INTERMEDIO
su funcin bsica es generar una representacin intermedia
explicita
propiedades importantes de las representaciones intermedias
* fcil de generar
* fcil de traducir a instrucciones del procesador
las formas de representacin intermedia ms utilizadas son:
* rboles de sintaxis abstracta
* grafos acclicos dirigidos (DAG`s).
* notacin postfija
* notacin de n-uplas
OPTIMIZACIN DE CDIGO
Analiza y mejora la representacin intermedia
Objetivo: reducir el tiempo de ejecucin
Debe preserva los valores
Optimizaciones tpicas:
* descubrir y programar algn valor constante
* mover determinadas computaciones a lugares frecuentemente
ejecutados
* descubrir computaciones redundantes y removerlas
* remover cdigo que es intil o inalcanzable
GENERADOR DE CDIGO
Bsicamente genera el cdigo objeto, esto es cdigo de mquina
reubicable o cdigo assembler.

LA ESTRUCTURA DEL COMPILADOR


Los compiladores pueden tener dos tipos de estructuras:
Compilador de una pasada
Compilador de una o ms pasadas
Un compilador a menudo encuentra conveniente procesar todo el programa
fuente varias veces antes de generar el cdigo. Estas repeticiones son
conocidas como pasadas. Despus del paso inicial, donde se construye un
rbol sintctico o un cdigo intermedio a partir de la fuente, una pasada
consiste en procesar la representacin intermedia, agregando informacin a
ella, alterando su estructura o produciendo una representacin diferente. Las
pasadas pueden corresponder o no a las fases, a menudo una pasada
consistir de varias etapas. En realidad, dependiendo del lenguaje, un
compilador puede ser de una pasada, en el que todas las fases se presentan
durante un paso nico. Esto resulta en una compilacin eficaz pero tambin en
(por lo regular) un cdigo objetivo menos eficiente. Tanto Pascal como C son
lenguajes que permiten la compilacin de una pasa da. (Modula-2 es un
lenguaje cuya estructura requiere que un compilador tenga por lo menos dos
pasadas.) La mayora de los compiladores con optimizaciones utilizan ms de
una pasada; por lo regular se emplea una pasada para anlisis lxico y
sintctico, otra pasada para anlisis semntico y optimizacin a nivel del
fuente, y una tercera pasada para generacin de cdigo y optimizacin a nivel
del objetivo. Los compiladores fuertemente optimizadotes pueden emplear
incluso ms pasadas: cinco, seis o incluso ocho no son algo fuera de lo comn.

COMPILADOR DE UNA PASADA


PARSER

SCANER

CHEQUEO DE
TIPOS

PROGRAMA

GENERACIN
DE CDIGO

PROGRAMA

FUENTE

OBJETO

El parser acta como rutina principal


El parser invoca al scanner cuando necesita un token
Cuando analiza la sentencia controla correccin semntica
Cuando analiza la sentencia invoca al generador de cdigo (intermedio u
objeto).

Sus caractersticas son:


Fcil de implementar,
cdigo no muy eficiente
mucha memoria requerida
til cuando el almacenamiento externo es lento o escaso.

COMPILADOR DE DOS PASADAS


PROGRAMA FUENTE

SCANER

PRIMERA PASADA

PARSER

FRONT
END

ANALIZADOR
SEMANTICO

SEGUNDA PASADA

GENERADOR DE
CDIGO
INTERMEDIO

BACK
END

GENERADOR
DE CDIGO

PROGRAMA OBJETO

Pasada 1: FRONT END.

OPTIMIZADOR DE
CDIGO

El parser acta como en el caso anterior


Pasada 2: BACK END.
DECISONES DE DISEO:
Los Compiladores de una pasada son convenientes cuando:
La velocidad es el aspecto ms importante
Sin embargo los lenguajes tipo PL/1 y ALGOL 68 no pueden ser
compilados en una sola pasada porque:
o Bsicamente las variables pueden ser usadas antes de su
definicin
Los Compiladores de mltiples pasadas favorecen:
Modularidad
La velocidad de ejecucin de los programas puesto que esquemas de
optimizacin de cdigo ms sofisticados pueden usarse
Cuando los recurso del sistema (por Ej. la memoria) estn limitados.

ACTIVIDADES

1. Tome el programa realizado en la unidad de refuerzo 1ro.1. y realice


manualmente el proceso de compilacin (cada una de las fases).
Digitalcelo y envelo a su tutor.

2.

Realice un ensayo donde exponga su punto de vista, sobre la


importancia de conocer el manejo y estructura de los compiladores, para
el desarrollo de sus programas en el futuro.

Vous aimerez peut-être aussi