Fase de 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 nuestro
caso las categorías gramaticales del análisis léxico son los terminales de la
gramática. Para el ejemplo que nos ocupa podemos partir 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.
Fase de 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 operan dos 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.
El componente más importante del análisis semántico
es la verificación de tipos. Aquí, el compilador verifica si los operan dos de
cada operador son compatibles según la especificación del lenguaje fuente. Si
suponemos que nuestro lenguaje solo trabaja con números reales, la salida de
esta fase sería su mismo árbol, excepto porque el atributo de <NUM>, que
era el entero 8 a la entrada, ahora pasaría a ser el real 8,0. Además se ha debido
controlar que las variables implicadas en la sentencia, a saber, comisión, fijo
y valor son compatibles con el tipo numérico de la constante 8,0.
Etapa de síntesis
En la etapa anterior se ha controlado que el
programa de entrada es correcto. Por tanto, el compilador ya se encuentra en
disposición de generar el código máquina equivalente semánticamente al programa
fuente. Para ello se parte de las estructuras generadas en dicha etapa
anterior: árbol sintáctico y tabla de símbolos.
Fase de generación de código intermedio
Después de la etapa de análisis, se suele generar
una representación intermedia explícita del programa fuente. Dicha
representación intermedia se puede considerar como un programa para una máquina
abstracta.
Fase de optimización de código
Esta fase trata de mejorar el código intermedio, de
modo que en la siguiente fase resulte un código de máquina más rápido de
ejecutar. Algunas optimizaciones son triviales. En nuestro ejemplo hay una
forma mejor de realizar el cálculo de la comisión, y pasa por realizar
sustituciones triviales en la segunda y cuarta instrucciones, obteniéndose: t2
= valor * 8.0 comisión= fijo + t2
Fase de generación de código máquina
La
fase final de un compilador es la generación de código objeto, que por lo
general consiste en código máquina reubicable o código ensamblador. Cada una de
las variables usadas por el programa se traduce a una dirección de memoria
(esto también se ha podido hacer en la fase de generación de código
intermedio). Después, cada una de las instrucciones intermedias se traduce a
una secuencia de instrucciones de máquina que ejecuta la misma tarea.
No hay comentarios:
Publicar un comentario