2. Los compiladores son programas de computadora que traducen de un
lenguaje a otro. Un compilador toma como su entrada un programa
escrito en lenguaje fuente y produce un programa equivalente escrito en
lenguaje objeto.
Generalmente al lenguaje fuente se le asocia como lenguaje de alto
nivel, mientras al lenguaje objeto se le conoce como código objeto
(código de maquina) escrito específicamente para una maquina objeto. A
lo largo del proceso de traducción el compilador debe informar la
presencia de errores en el lenguaje fuente.
Diseñar y desarrollar un compilador, no es tarea fácil, y quizás pocos
profesionales de la computación se vean involucrados en esta tarea.
No obstante, los compiladores se utilizan en casi todas las formas de la
computación y cualquiera involucrado en esta área debería conocer la
organización y el funcionamiento básico de un compilador.
3. Utilización de un compilador
En las primeras épocas de la informática, el software de los
compiladores era considerado como uno de los más complejos
existentes.
Los primeros compiladores se realizaron programándolos
directamente en lenguaje máquina o en ensamblador. Una vez
que se dispone de un compilador, se pueden escribir nuevas
versiones del compilador (u otros compiladores distintos) en el
lenguaje que compila ese compilador.
Actualmente existen herramientas que facilitan la tarea de
escribir compiladores ó intérpretes informáticos. Estas
herramientas permiten generar el esqueleto del analizador
sintáctico a partir de una definición formal del lenguaje de
partida, especificada normalmente mediante una gramática
formal y barata, dejando únicamente al programador del
compilador la tarea de programar las acciones semánticas
asociadas.
4. Análisis: Se trata de la comprobación de la corrección del
programa fuente, e incluye las fases correspondientes al
Análisis léxico (que consiste en la descomposición del
programa fuente en componentes léxicos), Análisis
sintáctico (agrupación de los componentes léxicos en frases
gramaticales ) y Análisis semántico (comprobación de la
validez semántica de las sentencias aceptadas en la fase de
Análisis Sintáctico).
Para poder realizar esta interpretación es necesario contar
con sistemas de traducción que son conocidos bajo los
nombres de Compiladores, Intérpretes o Ensambladores,
entre otros sistemas de traducción, que son los encargados
de llevar estos lenguajes hacia un Sistema Binario de ceros y
unos.
5. Se traduce las instrucciones en un lenguaje de alto nivel a
instrucciones que la computadora puede interpretar y ejecutar.
Muchas herramientas de software que manipulan programas
fuente realizan primero algún tipo de análisis.
Algunos ejemplos de tales herramientas son:
o Editores de estructuras: un editor de estructuras toma como
entrada una secuencia de órdenes para construir un programa
fuente.
El editor de estructuras no sólo realiza las funciones de creación y
modificación de textos de un editor de textos ordinario, sino que
también analiza el texto del programa imponiendo al programa
fuente una estructura jerárquica apropiada.
6. o Verificadores estáticos: Un verificador estático lee un
programa, lo analiza e intenta descubrir errores
potenciales sin ejecutar el programa.
La parte del análisis es similar a la que se encuentra en los
compiladores de optimación. Así un verificador estático
puede detectar si hay partes de un programa que nunca se
podrán ejecutar o si cierta variable se usa antes de ser
definida.
o Intérpretes: En lugar de producir un programa objeto
como resultado de una traducción, un intérprete realiza
las operaciones que implica el programa fuente.
Para una proposición de asignación, por ejemplo, un
intérprete podría construir un árbol, y después efectuar las
operaciones de los nodos conforme así "recorre" el árbol.
7. Las fases de un compilador son:
• Análisis Léxico: Esta fase se encarga de verificar si
todas las cadenas pertenecen o no al lenguaje. Es decir
realiza un análisis símbolo por símbolo indicando el
tokens por cada uno de los elementos reconocidos o el
error en caso de no reconocer. Este análisis no logra
detectar muchos errores por su característica.
Ejemplo:
Total=valor*5
Luego del análisis léxico:
Id = id * núm.
8. • Análisis Sintáctico: En esta fase se analiza la estructura de las
expresiones en base a gramáticas. Aquí ya se puede determinar
una estructura por ejemplo una expresión matemática mal
formada. El análisis que se realiza es jerárquico es decir en
base a árboles de derivación que se obtienen de las mismas
gramáticas.
Ejemplo: position:=initial + rate*60
9. • Análisis Semántico: Este análisis es más difícil de
formalizar, determina el tipo de los resultados
intermedios, comprobar que los argumentos que tienen
un operador pertenecen al conjunto de operadores
posible, y si son compatibles entre sí.
10. • Generación de Código Intermedio: El código intermedio es
una representación en base a elementos de 3 y 4 direcciones.
Lo que nos permite llegar a la fase de optimización de código.
a=b+c
1: + b c T1
2: = a T1
• Optimización de Código: Consiste en realizar una mejora en
el código intermedio, para reducir el número de líneas y hacer
que la ejecución sea más rápida
a=b+c
1: + b c a
11. • Generación de Código: Llegamos a la generación de código
ensamblador o código máquina del procesador que nos
interese por ejemplo:
a:=b+c
LOAD B
ADD C
STORE A
12. Un compilador opera en fases, de las cuales transforma el
programa fuente de una representación en otra. Dentro de
las tres primeras fases, que forman la mayor parte de
análisis de un compilador se analiza la administración, el
manejo de errores y la fase de análisis.
13. · Administración de tabla de símbolos: es la función
esencial de un compilador registrando los identificadores
utilizados en el programa fuente y reunir información sobre
los distintos atributos de cada identificador. Estos atributos
pueden proporcionar información sobre la memoria asignada
a un identificador.
· Detección e información de errores: en cada una de las
fases se puede encontrar errores, sin embargo, después de
detectar el error, se debe tratar de alguna forma ese error,
para poder continuar con la compilación.
Las fases de análisis sintáctico y semántico por lo general
manejan una gran proporción de los errores detectables por
el compilador. La fase léxica detecta los errores donde los
caracteres restantes de la entrada no forman ningún
componente léxico del lenguaje.
14. Los errores donde la cadena de componentes léxicos viola
las reglas de estructura del lenguaje que son determinados
por la fase del análisis sintáctico. Durante el análisis
semántico el compilador intenta detectar construcciones
que tengan la estructura sintáctica correcta, pero que no
tenga significado para la operación implicada.
· La fase de análisis: conforme avanza la traducción, la
representación interna del programa fuente que tiene el
compilador se modifica.
15. Compiladores cruzados: generan código para un sistema
distinto del que están funcionando.
Compiladores optimizadores: realizan cambios en el código
para mejorar su eficiencia, pero manteniendo la
funcionalidad del programa original.
Compiladores de una sola pasada: generan el código
máquina a partir de una única lectura del código fuente.
Compiladores de varias pasadas: necesitan leer el código
fuente varias veces antes de poder producir el código
máquina.
Compiladores JIT (Just In Time): forman parte de un
intérprete y compilan partes del código según se necesitan.
16. Se muestran algunas herramientas disponibles que pueden
utilizarse para la realización del proyecto de compiladores.
Todas las herramientas aquí expuestas funcionan bajo Windows.
· BISON
· COCO/R
· FLEX
· LEX
· SDGLL1
· TS 2006
· TS
· TS-OO
· YACC
17. Se han creado algunas herramientas generales para el
diseño automático de componentes específicos de
compilador.
Estas herramientas utilizan lenguajes especializados para
especificar e implantar el componente, y pueden utilizar
algoritmos bastante complejos.
Las herramientas más efectivas son las que ocultan los
detalles del algoritmo de generación y producen
componentes que se pueden integrar con facilidad al resto
del compilador.
18. La siguiente es una lista de algunas herramientas
útiles para la construcción de compiladores:
• Generadores de analizadores sintácticos: Estos
generadores producen analizadores sintácticos,
normalmente a partir de una entrada fundamentada en
una gramática independiente del contexto.
En los primeros compiladores, el análisis sintáctico
consumía no solo gran parte del tiempo de ejecución del
compilador, sino gran parte del esfuerzo intelectual de
escribirlo. Esta fase se considera ahora una de las más
fáciles de aplicar.
Muchos de los generadores de analizadores sintácticos
utilizan poderosos algoritmos de análisis sintáctico, y son
demasiado complejos para realizarlos manualmente.
19. • Generadores de analizadores léxicos: Estas
herramientas generan automáticamente analizadores
léxicos, por lo general a partir de una especificación
basada en expresiones regulares. La organización básica
del analizador léxico resultante es en realidad un
autómata finito. Una herramienta muy utilizada en la
especificación de analizadores léxicos para varios
lenguajes es el compilador LEX.
• Dispositivos de traducción dirigida por la sintaxis:
Estos producen grupos de rutinas que recorren el árbol
de análisis sintáctico, generando código intermedio. La
idea básica es que se asocian una o más “traducciones”
con cada nodo del árbol de análisis sintáctico, y cada
traducción se define partiendo de traducciones en sus
nodos vecinos en el árbol.
20. • Generadores automáticos de código: Tales
herramientas toman un conjunto de reglas que definen
la traducción de cada operación del lenguaje intermedio
al lenguaje de máquina para la maquina objeto. Las
reglas deben incluir suficiente detalle para poder
manejar los distintos métodos de acceso posibles a los
datos; por ejemplo, las variables pueden estar en
registros, en una posición fija (estática) de memoria o
pueden tener asignada una posición en una pila. La
técnica fundamental es la de “concordancia de
plantillas”.
21. • Dispositivos para análisis de flujo de datos: Mucha de
la información necesaria para hacer una buena
optimación de código implica hacer un “análisis de
flujo de datos”, que consiste en la recolección de
información sobre la forma en que se transmiten los
valores de una parte de un programa a cada una de las
otras partes.
Las distintas tareas de esta naturaleza se pueden efectuar
esencialmente con la misma rutina, en la que el usuario
proporciona los detalles relativos a la relación que hay
entre las proposiciones en código intermedio y la
información que se está recolectando.
22. Este trabajo servirá en el momento de la creación de un
compilador, ya que en él se detallan todas y cada una de
las partes que involucran a este. Podemos decir que
existen distintos tipos de compiladores. En los años 50 se
tardaron hasta 18 años trabajando en un compilador, sin
embargo ahora podemos construir en un máximo de tiempo
de 6 meses un compilador ya que ahora tenemos todas las
herramientas para agilizar la construcción.