compiladorA pesar de su importancia y omnipresencia, no es extraño que a veces surjan dudas acerca de su naturaleza: ¿En qué lenguaje está escrito un compilador? ¿Cómo se compila un compilador? ¿Puede un compilador de C estar escrito en C?Estas tres preguntas, que no se pueden responder por separado, pues están relacionadas entre sí, no forman (a pesar de las apariencias) una versión moderna del dilema del huevo y la gallina. Veamos por qué.

El compilador es una pieza fundamental en el desarrollo de software. Se encarga de transformar las instrucciones dadas en algún lenguaje de programación (más o menos cercano al lenguaje natural) a instrucciones comprensibles por un computador: el lenguaje máquina, formado por unos y ceros, que a su vez es otra abstracción para codificar diferentes tensiones de una señal eléctrica.

En qué lenguaje está escrito un compilador?

Para responder a esta pregunta podemos remontarnos a los albores de las ciencias de la computación. Fue en 1952 cuando Grace Hopper, una de las mujeres que más contribuyó a la informática, escribió el primer compilador: el sistema A-0. Hopper (a la que por cierto, se debe también el origen del término a partir de la ya conocida anécdota con el Mark I) reunió todas las subrutinas en lenguaje máquina que había utilizado a lo largo de los años y las puso en una cinta asociadas a un código numérico. El sistema A-0 podía traducir códigos simbólicos matemáticos a lenguaje máquina haciendo uso de estos códigos numéricos, buscando en la cinta las subrutinas correspondientes.

Si bien esto se corresponde más con la noción actual de enlazador, se considera al sistema A-0 como el primer compilador. Por tanto, en el principio de los tiempos de la computación, fue un humano quien tuvo que convertir aquellas instrucciones dadas en un lenguaje ajeno al computador, una especie de símbolos matemáticos, en instrucciones binarias.

Conforme la computación fue avanzando y se volvió más compleja, se hizo uso de las instrucciones en ensamblador, que realizaban un mapeo directo a unas instrucciones en lenguaje máquina que podían ejecutarse directamente por el procesador.

Cómo se compila un compilador? ¿Puede un compilador de C estar escrito en C?

Como hemos comprobado, se puede escribir una versión muy simple de compilador a partir de ensamblador y código máquina. Una vez que se tiene un software  capaz de traducir algo a instrucciones binarias, se puede utilizar para escribir un compilador un poco más sofisticado que el anterior y de nuevo, emplear el segundo para construir un tercero. A este proceso iterativo de construcción de una herramienta a partir de una versión anterior más simple lo llamamos bootstrapping. Ese “algo” puede ser instrucciones en el mismo lenguaje de programación con el que está construido el compilador, creando uno nuevo autocontenido (self-hosting). Así está construido, por ejemplo, gcc, uno de los compiladores más populares de C. 

Sin embargo, hay disponibles gran cantidad de lenguajes con sus respectivos compiladores que permiten omitir el primer paso de usar directamente ensamblador y código máquina.

En la imagen se muestra un ejemplo simplificado de bootstrapping. Supongamos que se crea un nuevo lenguaje llamado T. Para poder compilarlo, se escribe un compilador para T en otro lenguaje, por ejemplo en C (Tcompiler_c.c). Ahora, se usa algún compilador existente de C para compilar Tcompiler_c.c, generando un ejecutable Tcompiler_c. Una vez hecho esto, se puede volver a escribir un nuevo compilador de T, pero ahora usando el propio lenguaje (Tcompiler_t.t). Como ya existe un programa capaz de compilarlo, Tcompiler_c, se utiliza para obtener un nuevo compilador que fue compilado a partir de su propio código fuente. Se puede repetir este último paso generando cada vez una versión más potente que la anterior.

compiler

Los compiladores siguen siendo hoy en día herramientas  en constante evolución. De ellos depende, en parte, que el código objeto que se ejecuta en un procesador esté mejor optimizado y sea más eficiente. Por eso, los compiladores representan un recurso fundamental en Teldat, desde su uso hasta su comprensión teórica, para desarrollar software embebido de calidad.


Sobre el autor

Javier Marchan

Comparte este post

Tweet about this on TwitterShare on LinkedInShare on Google+Email this to someone