¿Qué es un compilador?

Es un Software que traduce un programa escrito en un lenguaje de programación de alto nivel (C / C ++, COBOL, etc.) en lenguaje de máquina. Un compilador generalmente genera lenguaje ensamblador primero y luego traduce el lenguaje ensamblador al lenguaje máquina. Una utilidad conocida como “enlazador” combina todos los módulos de lenguaje de máquina necesarios en un programa ejecutable que se puede ejecutar en la computadora.

Un poco de Historia

El término “compilador” fue acuñado a principios de 1950 por Grace Murray Hopper. La traducción fue vista entonces como la “compilación” de una secuencia de rutinas seleccionadas.

Grace Brewster Murray Hopper fue una científica informática estadounidense y contraalmirante de la Marina de los Estados Unidos. Una de las primeras programadoras de la computadora Harvard Mark I, fue una pionera en programación que inventó una de las primeras herramientas relacionadas con el compilador. Ella popularizó la idea de los lenguajes de programación independientes de la máquina, lo que condujo al desarrollo de COBOL, un lenguaje de programación de alto nivel que todavía se usa en la actualidad.

El primer compilador del lenguaje de alto nivel FORTRAN se desarrolló entre 1954 y 1957 en IBM por un grupo dirigido por John Backus.

Un compilador es uno de los pilares de la programación y de cómo entender la comunicación entre un lenguaje de alto nivel y una máquina. Al poder conocer el funcionamiento de este paso intermedio nos permitirá desarrollar y programar de una forma más precisa los lenguajes de alto nivel.

Tradicionalmente los compiladores generaban código máquina de inferior calidad que el que podían escribir programadores humanos, pero actualmente los compiladores proporcionan hoy en día un código máquina de alta calidad pequeño y rápido, haciendo poco atractiva la programación en ensamblador, programación que en asignaturas como está ya simplemente se menciona por conocerla pero no se realiza un estudio para aprender este tipo de programación.

Los programadores de ensamblador siguen teniendo ventaja en cuanto a que disponen de un mayor conocimiento global del programa que les permite realizar determinadas optimizaciones del código que resultan muy difíciles para los compiladores.

 

¿En qué se diferencia de un Intérprete?

Para responder a esta pregunta primero debemos conocer que es y para qué sirve un Intérprete.

Un intérprete lee un programa fuente ejecutable, escrito en un lenguaje de programación de alto nivel, así como datos para este programa, y ​​ejecuta el programa contra los datos para producir algunos resultados. Un ejemplo es el intérprete de shell de Unix, que ejecuta comandos del sistema operativo de forma interactiva.

Hay que tener en cuenta que tanto los intérpretes como los compiladores (como cualquier otro programa) están escritos en un lenguaje de programación de alto nivel (que puede ser diferente del idioma que aceptan) y se traducen en código máquina.

Por ejemplo, un intérprete de Java puede escribirse completamente en C o incluso en Java. El programa fuente del intérprete es independiente de la máquina ya que no genera código de máquina.

Un intérprete generalmente es más lento que un compilador porque procesa e interpreta cada enunciado de un programa tantas veces como el número de evaluaciones de esta afirmación. Por ejemplo, cuando se interpreta un bucle for, las afirmaciones dentro del cuerpo for-loop se analizarán y evaluarán en cada paso del bucle. Algunos lenguajes, como Java y Lisp, vienen con un intérprete y un compilador. Los programas fuente de Java (clases Java con extensión .java) son traducidos por el compilador javac en archivos de códigos de bytes (con extensión .class).

El intérprete de Java, llamado Java Virtual Machine (JVM), en realidad puede interpretar códigos de bytes directamente o puede compilarlos internamente en código máquina y luego ejecutar ese código.

Los compiladores son procesos complejos debido a que tienen varias fases por las que un programa fuente debe de pasar antes de convertirse en un programa ejecutable, los pasos son los siguiente

Analizador léxico:

El analizador léxico o lexicográfico (Scanner en inglés) es la primera etapa del proceso de compilación, el cual se encarga de dividir el programa en Tokens, los cuales, según una tabla de símbolos definida por el mismo lenguaje.

De esta forma cada token del programa es clasificado según su significado para ser procesados en la segunda etapa del proceso de compilación.

Analizador sintáctico:

El analizador sintáctico (Parse en inglés), es la segunda fase del proceso de compilación y tiene como finalidad la generación de un Árbol sintáctico, el cual no es más que una estructura de datos compleja que permite representar de una forma más simple al programa fuente.

Los compiladores modernos utilizan estructuras de objetos para representa a un programa, de esta forma existe una clase específica para representa cada posible token de nuestra tabla de símbolos.

Analizador semántico:

El analizador semántico es el último paso antes de empezar a compilar realmente el código, prepara el programa para ser compilado. El analizador semántico parte del árbol sintáctico abstracto y tiene la finalidad de validar los puntos más finos del programa, como por ejemplo, validar compatibilidad en tipos de datos, que la variable utilizada en una instrucción este previamente declara o que estén dentro del contexto, si implementamos una interface que todos los métodos estén definidos, etc.

El analizador semántico es el que analiza que todo el programa tenga un significado exacto y que este no pueda fallar en tiempo de ejecución,