Diseño del compilador: fases del compilador

El proceso de compilación es una secuencia de varias fases. Cada fase toma la entrada de su etapa anterior, tiene su propia representación del programa fuente y alimenta su salida a la siguiente fase del compilador. Entendamos las fases de un compilador.

Análisis léxico

La primera fase del escáner funciona como un escáner de texto. Esta fase escanea el código fuente como un flujo de caracteres y lo convierte en lexemas significativos. El analizador léxico representa estos lexemas en forma de tokens como:

<token-name, attribute-value>

Análisis de sintaxis

La siguiente fase se llama análisis de sintaxis o parsing. Toma el token producido por el análisis léxico como entrada y genera un árbol de análisis sintáctico (o árbol de sintaxis). En esta fase, las disposiciones de los tokens se verifican con la gramática del código fuente, es decir, el analizador verifica si la expresión hecha por los tokens es sintácticamente correcta.

Análisis semántico

El análisis semántico comprueba si el árbol de análisis sintáctico construido sigue las reglas del lenguaje. Por ejemplo, la asignación de valores se realiza entre tipos de datos compatibles y la adición de una cadena a un número entero. Además, el analizador semántico realiza un seguimiento de los identificadores, sus tipos y expresiones; si los identificadores se declaran antes de su uso o no, etc. El analizador semántico produce un árbol de sintaxis anotado como salida.

Generación de código intermedio

Después del análisis semántico, el compilador genera un código intermedio del código fuente para la máquina de destino. Representa un programa para alguna máquina abstracta. Está entre el lenguaje de alto nivel y el lenguaje de máquina. Este código intermedio debe generarse de tal manera que sea más fácil de traducir al código de la máquina de destino.

Optimización de código

La siguiente fase hace la optimización del código del código intermedio. Se puede asumir que la optimización es algo que elimina líneas de código innecesarias y organiza la secuencia de declaraciones para acelerar la ejecución del programa sin desperdiciar recursos (CPU, memoria).

Codigo de GENERACION

En esta fase, el generador de código toma la representación optimizada del código intermedio y lo asigna al lenguaje de máquina de destino. El generador de código traduce el código intermedio en una secuencia de código de máquina (generalmente) reubicable. La secuencia de instrucciones del código de máquina realiza la tarea como lo haría el código intermedio.

Tabla de símbolos

Es una estructura de datos que se mantiene a lo largo de todas las fases de un compilador. Todos los nombres de los identificadores junto con sus tipos se almacenan aquí. La tabla de símbolos facilita al compilador buscar rápidamente el registro del identificador y recuperarlo. La tabla de símbolos también se utiliza para la gestión del alcance.