Sei sulla pagina 1di 5

Compiladores - Generalidades 1

1 GENERALIDADES DE COMPILADORES

DEFINICIÓN DE UN COMPILADOR

Un compilador es un programa que permite traducir el código fuente de un programa en


lenguaje de alto nivel, a otro lenguaje de nivel inferior (típicamente lenguaje máquina). De
esta manera un programador puede diseñar un programa en un lenguaje mucho más
cercano a como piensa un ser humano, para luego compilarlo a un programa más manejable
por una computadora. Un compilador tiene como característica principal la propiedad de que
reporta y en algunos casos corrige los errores detectados en el código fuente.

Figura 1. Definición de un compilador

Partes de un compilador
Normalmente los compiladores están divididos en dos partes:

Front End: es la parte que analiza el código fuente para comprobar su validez. Esta parte
suele ser independiente de la plataforma o sistema para el cual se vaya a compilar. El Front
End realiza la fase de Análisis de la compilación.

Back End: es la parte que genera el código objeto, específico de una plataforma, a partir de
los resultados de la fase de análisis, realizada por el Front End. El Back End realiza la fase
de Síntesis de la compilación.

Esta división permite que el mismo Back End se utilice para generar el código máquina de
varios lenguajes de programación distintos y que el mismo Front End que sirve para analizar
el código fuente de un lenguaje de programación concreto sirva para generar código
máquina en varias plataformas distintas.

El código que genera el Back End normalmente no se puede ejecutar directamente, sino que
necesita ser enlazado por un programa enlazador (linker).

HISTORIA

Históricamente los compiladores han estado unidos a la evolución de los lenguajes de


programación, ya que en esta evolución se encuentra su verdadero sentido. Un compilador
es desarrollado porque existe un lenguaje de programación creado, brindando un nivel de
abstracción superior al usuario, que requiere ser traducido para poder ser interpretado por la
máquina.
“Es importante recordar que los sistemas de computo solo reconocen el sistema binario”

Evolución de los lenguajes de alto nivel


La evolución de los lenguajes de alto nivel llevó a que los desarrolladores necesitaran menos
conocimientos sobre la estructura interna en el computador para dar la solución lógica al
problema en cuestión.

Historia de los lenguajes

· Lenguajes de primera generación


En un comienzo la programación de los computadores se realizaba a través del uso del
código binario de maquina, lo que causaba que la programación fuera difícil y problemática.
Se evolucionó al uso de octales y hexadecimales.
Compiladores - Generalidades 2

· Lenguajes de segunda generación (ensambladores)


En estos lenguajes se usan abreviaturas nemónicas o nombres simbólicos.
Se cambió del nivel de flip-flop a registro.
Es un lenguaje dependiente de la máquina.
No es una programación estructurada.

· Lenguajes de tercera generación


Son lenguajes compuestos de estructuras de control basadas en objetos de datos lógicos.
Lenguajes de Alto nivel
Control independiente de la máquina en la que se ejecuta.

· Lenguajes de cuarta generación


Propiamente los lenguajes de cuarta generación no existen, pero es posible considerar las
herramientas CAD (Diseño Asistido por Computador) con soporte de FRAMEWORK como lo
más cercano. Algunas herramientas ya existentes reciben como entrada un código muy
parecido al lenguaje natural, por ejemplo diagramas de UML, y brindan como salida un
código ejecutable en una máquina.
Control independiente de la máquina en la que se ejecuta.

FORTRAN, fue el primer lenguaje compilado, en un intento por facilitar a los programadores
Franceses e Ingleses su trabajo. Fue un cambio difícil, pero un gran paso en los
compiladores.

En esa época el refrán “Los verdaderos programadores utilizan un lenguaje ensamblador” era
muy aceptado.
FORTRAN no poseía estructuras como registros, conjuntos, punteros, tipos enumerados, y no
estaba incluida la recursividad, debía simularse con una pila.

Hoy en día los compiladores son mucho más poderosos, y es posible especificar lenguajes
donde se usen más estructuras y tecnologías actuales, como la comunicación en red y
algoritmos complejos.

FIGURA 2. Evolución de los Lenguajes

TRADUCTORES

Generalidades

Traductor: Es una máquina teórica que tiene como entrada un texto escrito en un lenguaje
L1 y como salida un texto escrito en un lenguaje L2. Habitualmente se denomina a L1
Lenguaje fuente y a L2 el lenguaje objeto.

Las técnicas que se desarrollan en esta asignatura no sólo son válidas para la
implementación de compiladores, sino que son aplicables en general a todos los sistemas de
procesamiento de lenguajes y de traducción. Estos sistemas pueden ser de distintos tipos:
Compiladores - Generalidades 3

Traductores de Lenguaje Natural: Serían los que tradujeran un lenguaje natural en otro
(por ejemplo, español a inglés). Esto en la actualidad no se ha conseguido debido
fundamentalmente a la ambigüedad del lenguaje natural. Los mayores logros en la materia
siempre trabajan con un subconjunto del lenguaje natural, limitando las construcciones
sintácticas válidas y/o el vocabulario.
Este tema se aborda generalmente mediante técnicas de Inteligencia Artificial.

Compilador: Es un traductor que convierte un texto escrito en un lenguaje fuente de alto


nivel en un programa objeto en código de máquina.

Intérprete: Es un traductor que realiza la operación de compilación paso a paso. Para cada
sentencia que compone el texto de entrada, se realiza una traducción, ejecuta dicha
sentencia y vuelve a iniciar el proceso con la sentencia siguiente. La principal ventaja del
proceso de compilación frente al de interpretación es que los programas se ejecutan mucho
más rápidamente una vez compilados; por el contrario, es más cómodo desarrollar un
programa mediante un intérprete que mediante un compilador puesto que en el intérprete
las fases de edición y ejecución están más integradas. La depuración de los programas suele
ser más fácil en los intérpretes que en los compiladores puesto que el código fuente está
presente durante la ejecución. Estas ventajas pueden incorporarse al compilador mediante la
utilización de entornos de desarrollo y depuradores simbólicos en tiempo de ejecución.
Un Intérprete no arroja código objeto, ya que ejecuta directamente las instrucciones sobre la
máquina.

Preprocesadores u Optimizadores: Procesan un texto fuente modificándolo en cierta


forma previamente a la compilación. Por ejemplo, muchos compiladores admiten un conjunto
de macroinstrucciones ajenas al lenguaje en sí que indican al compilador si tiene que incluir
algún fichero externo, si ha de hacer o no un listado completo de la compilación, entre otras.

Conversores Fuente-Fuente: Traducen un lenguaje fuente de alto nivel a otro (por


ejemplo, PASCAL -> C, ó Java -> C++). Una aplicación interesante de la traducción fuente-
fuente es el desarrollo e implementación de prototipos de nuevos lenguajes de
programación. Así, por ejemplo, si se desea definir un lenguaje especializado puede
implementarse rápidamente mediante su traducción a un lenguaje convencional de alto
nivel.

Rutinas de Análisis de Instrucciones: El conjunto de instrucciones del entorno de un


sistema operativo constituye un lenguaje que debe ser analizado previamente para realizar
las acciones oportunas. Igualmente, ciertos programas como editores de texto, sistemas de
diseño asistido, etc., utilizan instrucciones complejas que deben interpretarse
adecuadamente.

Ensambladores: Son compiladores cuyo lenguaje de entrada, llamado ensamblador,


permite la traducción de cada sentencia fuente a una instrucción en código máquina.

Compilador cruzado: Un compilador cruzado es un compilador capaz de crear código


ejecutable en otra plataforma distinta a aquélla en la que él se ejecuta. Esta herramienta es
útil cuando quiere compilarse código para una plataforma a la que no se tiene acceso, o
cuando es incómodo o imposible compilar en dicha plataforma (como en el caso de los
sistemas empotrados).

Compilación-Montaje-Ejecución: En las aplicaciones grandes es conveniente fragmentar


el programa a realizar en módulos que se compilan por separado, y una vez que estos estén
compilados unirlos mediante un programa denominado montador para formar el módulo
ejecutable. El montador se encarga, a su vez, de incluir las librerías donde están guardadas
las funciones predefinidas de uso común.

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.
Compiladores - Generalidades 4

Compilación incremental: Este compilador actúa de la siguiente manera. Compila un


programa fuente. Caso de detectar errores al volver a compilar el programa corregido sólo
compila las modificaciones que se han hecho respecto al primero.

Autocompilador: Es aquél que está escrito en el mismo lenguaje que se pretende compilar.
Supongamos, por ejemplo, que queremos desarrollar la versión 2.0 de un compilador Pascal.
Dicho compilador generará un código mucho más rápido y eficiente que el que generaba la
versión anterior 1.0. Sin embargo, son ya muchas las máquinas (IBM 370, Serie 1, PDP 11,
...) que disponen del antiguo compilador, o que al menos tienen otro compilador Pascal. La
mejor opción consiste en escribir el nuevo compilador en Pascal, ya que así podrá (el
compilador) ser compilado en las distintas máquinas por los compiladores Pascal ya
existentes.

Metacompilador: Es un traductor que tiene como entrada la definición de un lenguaje y


como salida el compilador para dicho lenguaje.

Decompilador: Es el que traduce código máquina a lenguaje de alto nivel. Los


decompiladores más usuales son los desensambladores, que traducen un programa en
lenguaje máquina a otro en ensamblador.

El Preprocesador

En una fase compilación se puede apreciar que son varios los componentes que se involucran
en la interpretación del código fuente. El más visible para el usuario es el Preprocesador. Es
común encontrase en un código fuente la necesidad de agregar líneas como:

#include<stdio.h>
#include<conio.h>
void main()
{
int a;
if( a ){
printf(“Hola mundo”);
}
}

La idea de agregar las líneas include es la de reutilizar código previamente desarrollado y así
facilitar nuestras construcciones. Por esta razón, el trato a este tipo de código es diferente al
trato hecho al código fuente propio, pero en ambos casos es importante reconocer cual es la
función del compilador, ya que esta depende del tipo de lenguaje que interpreta.

Figura 3. Compilador con preprocesador

En general, el proceso de Compilación puede verse como la ejecución de una secuencia de


fases que tienen como objetivo final la entrega de código.

El preprocesador acepta como entrada código fuente y se encarga de:


1. Eliminar los comentarios.
Compiladores - Generalidades 5

2. Interpretar y procesar las directivas de preprocesamiento, precedidas siempre por el


símbolo # (en lenguaje C).

Dos de las directivas más comúnmente empleadas en C son #include y #define:

Figura 4. Lo que hay después del compilador.

El enlazador - Parte de algunos compiladores

El enlazador (del inglés, linker) resuelve las referencias a objetos externos que se
encuentran en un fichero fuente. Estas referencias son a objetos que se encuentran en otros
módulos compilados, ya sea en forma de ficheros objeto o incorporados en alguna biblioteca
(del inglés, library).

Para terminar:

¿Qué es un compilador?
¿Cuál es la función de un compilador?
¿Por qué es importante un compilador en el desarrollo de software?
¿Qué tipo de proyectos requieren la existencia de un compilador?

Consulte

1. ¿Que es la máquina virtual de Java?, ¿Cuál es su función?


2. ¿Qué podríamos decir de las instrucciones import de java según lo mencionado aquí?

Potrebbero piacerti anche