Fases de un compilador

División en las fases de análisis y síntesis

A veces la compilación se divide en 2 fases:

El análisis

En esta fase se estudia el programa fuente fraccionándolo en pedazos para establecer el significado del mismo y construyendo una representación inmediata.

La síntesis

En esta fase se hace la construcción del programa objeto a partir de la representación realizada en la fase de análisis.

Análisis del programa fuente

En esta fase, la cadena de caracteres que constituye el programa fuente se lee de izquierda a derecha y se agrupa en componentes léxicos, además el analizador léxico trabaja con la tabla de símbolos introduciendo en ésta los nombres de las variables

Sección de Análisis de un traductor

Análisis Léxico

La primera fase de un compilador, recibe como entrada el código fuente de otro programa (secuencia de caracteres) y produce u

La primera fase de un compilador, recibe como entrada el código fuente de otro programa (secuencia de caracteres) y produce una salida compuesta de tokens (componentes léxicos) o símbolos.

Ejemplo de Tokens

Ejemplo de Tokens

Aqui el programa fuente se lee
de izquierda a derecha y se agrupa en componentes léxicos, que son secuencias de caracteres que tienen un significado atómico.

Normalmente los espacios en blancos son eliminados.

Análisis Sintáctico

Trabaja con una gramática de contexto libre y genera el árbol sintáctico que reconoce su sentencia de entrada. En este caso las categorías gramaticales del
análisis léxico son los terminales de la gramática. Para el ejemplo que nos ocupa se parte de la gramática

S ÷ <ID> <ASIG> expr <TERM>
expr ÷ <ID>
| <ID> <+> expr
| <ID> <*> expr
| <NUM>

De manera que el análisis sintáctico intenta generar un árbol sintáctico que encaje con la sentencia de entrada.

Árbol sintáctico

Árbol sintáctico

El árbol puede representarse tal y como aparece en esta figura, o bien invertido.

Análisis Semántico

Esta fase revisa el árbol sintáctico junto con los atributos y la tabla de símbolos para tratar de encontrar errores semánticos. Para todo esto se analizan los operadores y operandos de expresiones y proposiciones. Finalmente reúne la información necesaria sobre los tipos de datos para la fase posterior de generación de código.

Topic principal

Sección de síntesis del traductor

Generador de código interrmedio

Transforma la salida del análisis semántico, en una representación cercana a un lenguaje intermedio cercano al código objeto.

Tiene dos propiedades importante

Debe ser fácil de producir

Debe ser fácil de traducir al lenguaje objeto

Existen varias formas de representar el código intermedio

Árboles sintácticos

Notación postfija

Código de tres direcciones

Consiste en una secuencia de instrucciones, cada una con máximo tres operandos y un operador binario.

Ejemplo

Ejemplo

Optimizador de código intermedio

Intenta mejorar el código intermedio para que se ejecute más rápido y ocupe menos espacio

Además de la optimización a nivel de código intermedio, se puede reducir el tiempo de ejecución de un programa actuando a otros niveles: a nivel de código fuente y a nivel de código objeto.

Generador de código

La fase final donde se genera el código de máquina.

Se traducen las instrucciones intermedias a instrucciones de máquina.

Asignan variables a registros

Ejemplo

Ejemplo

Manejo de tabla de símbolos

Una función esencial de un compilador es registrar los identificadores de usuario (nombres de variables, de funciones, de tipos, etc.) 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, la dirección de memoria en que se almacenará en tiempo de ejecución,
su tipo, su ámbito (la parte del programa donde es visible), etc.

Pues bien, la tabla de símbolos es una estructura de datos que posee información sobre los identificadores definidos por el usuario, ya sean constantes, variables, tipos u otros.

Interpretes vs compiladores

Compilador

Es un traductor que como entrada tiene una sentencia en lenguaje formal y la salida es un fichero ejecutable. En si traduce un código de alto nivel a código de máquina.

Intérprete

Es similar al compilador con la diferencia que la salida es una ejecución. El programa de entrada es reconocido y ejecutado a la vez. Tiene como principal ventaja que permite una fácil depuración.

Ejemplo

POSICION=INICIAL+VELOCIDADA*60

Ejemplo explicativo

Ilustración de fases de un compilador

Ilustración de fases de un compilador

Detección de errores y emisón de mensajes de error

e2JS

Cada fase es capaz de detectar sus propios errores pero, luego de esto deben saber como manejarlo para continuar con la compilación y detectar más errores del programa fuente.

El analizador léxico detecta errores si los caracteres de entrada no conforman ningún token conocido.

El analizador sintáctico detecta errores si los tokens violan la sintaxis (reglas gramaticales).

El analizador semántico detecta errores si las sentencias estan bien sintacticamente pero no tienen significado.

Bibliografía

Gálvez, R. Mora, M. (2005).Taductores Y Compiladores con LEX / YACC, JFLEX/CUP Y JAVACC

Jiménez Millán, J. A. (2014). Compiladores y procesadores de lenguajes. Servicio de Publicaciones de la Universidad de Cádiz.

Martínez López, F. (2015). Teoría, diseño e implementación de compiladores de Lenguajes. RA-MA Editorial.