Estructura
y fases de un compilador (2) Análisis lineal También conocido como: análisis
léxico o exploración. Ejemplo, en la proposición de asignación: posicion =
inicial + velocidad * 60 Se identifican los siguientes componentes léxicos
Identificador (posicion) Símbolo de asignación (=) Identificador (inicial)
Signo de suma (+) Identificador (velocidad) Signo de multiplicación (*) Número
(60)
12. Estructura
y fases de un compilador (3) Análisis jerárquico También llamado análisis
sintáctico. Implica agrupar los componentes léxicos en frases gramaticales que
el compilador utiliza para sintetizar la salida. Por lo general, las frases
gramaticales se representan mediante un árbol de análisis sintáctico. Ejemplo:
Proposición de asignación Identificador posición = expresión expresión
identificador + expresión inicial expresión identificador * expresión velocidad
Número 60
13. Estructura
y fases de un compilador (4) La estructura jerárquica de un programa
normalmente se expresa utilizando reglas recursivas. Para el ejemplo anterior
de la proposición de asignación se tiene: Cualquier identificador es una
expresión Cualquier número es una expresión Si expresión1 y expresión2 son
expresiones, entonces también lo son: expresión1 + expresión2 expresión1 *
expresión2 (expresión1) Proposición de asignación Identificador posicion =
expresión expresión identificador + expresión inicial expresión identificador *
expresión velocidad Número 60
14. Estructura
y fases de un compilador (5) Muchos lenguajes definen recursivamente las
proposiciones mediante reglas como: Si identificador1 es un identificador y
expresión2 es un identificador, entonces: Identificador1 = expresión2 Si
expresión1 es una expresión y proposición2 es una proposición, entonces: while
( expresión1 ) do proposición2 if ( expresión1 ) then proposición2 El análisis
lineal (léxico) no es suficientemente poderoso para analizar proposiciones o
expresiones recursivas. Cuándo una construcción del lenguaje fuente es recursiva,
entonces es factible emplear una gramática libre de contexto para formalizar la
recursión.
15. Estructura
y fases de un compilador (6) Análisis semántico Revisa el programa e intenta
encontrar errores semánticos. Reúne la información sobre los tipos para la fase
posterior de generación de código. Un componente importante es la verificación
de tipos. Se verifica si cada operador tiene los operandos permitidos. Un real
no debe utilizarse como índice de un arreglo. Convertir un número entero a real
para algunos operadores. = posicion + inicial * velocidad 60 = posicion +
inicial * velocidad ent a real 60 El análisis semántico inserta una conversión
de entero a real en el árbol de análisis sintáctico
16. Estructura
y fases de un compilador (7) Conceptualmente un compilador opera en fases, cada
una de las cuales transforma al programa fuente de una representación a otra.
Analizador léxico Programa fuente Analizador sintáctico Analizador semántico
Generador de código intermedio Optimizador de código Generador de código
Programa objeto Manejador de errores Administrador de la Tabla de símbolos
17. Estructura
y fases de un compilador (8) Administración de la tabla de símbolos Registra
los identificadores e información referente a ellos. Se tiene un registro por
cada identificador. Todas las fases hacen uso de esta tabla. Detección e
información de errores En cada fase se pueden encontrar errores. Se debe
definir como se deben tratar los errores en cada una de las fases. Las fases de
análisis Cambian la representación interna del programa fuente conforme avanza
cada una de ellas. Generación de código intermedio Se puede considerar como
código para una máquina abstracta. Dicha representación debe ser fácil de
producir y fácil de traducir al código objeto. Optimización de código Trata de
mejorar el código intermedio de modo que resulte un código máquina más rápido de
ejecutar. Generación de código Por lo general se trata de código máquina
relocalizable o código ensamblador. Se deben seleccionar posiciones de memoria
para cada una de las variables. posicion = inicial + velocidad * 60 Analizador
léxico id1 = id2 + id3 * 60 Analizador sintáctico = id1 + id2 * id3 60
Analizador semántico = id1 + id2 * id3 ent a real 60 Generador de código
intermedio temp1 = entreal(60) temp2 = id3 * temp1 temp3 = id2 +temp2 Id1 =
temp3 Optimizador de código temp1 = id3 * 60.0 temp2 = id2 +temp1 Id1 = temp2
Generador de código MOVF id3, R2 MULF #60.0, R2 MOVF id2, R1 ADDF R2, R1 MOV
R1, id1 TABLA DE SIMBOLOS posicion … inicial … velocidad … 1 2 3 4
18. Estructura
y fases de un compilador (9) Con frecuencia las fases de un compilador se
agrupan en una etapa inicial y una etapa final: Etapa inicial Comprende
aquellas fases que dependen principalmente del código fuente. Normalmente
incluye el análisis léxico, sintáctico y semántico, la creación de la tabla de
símbolos, la generación de código intermedio y cierta optimización de éste.
También incluye el manejo de errores correspondientes a cada etapa. Etapa final
Comprende aquellas partes del compilador que dependen de la máquina objeto. En
general estas partes dependen del lenguaje intermedio, más que del lenguaje
fuente. Comprende aspectos de optimización y generación de código, junto con el
manejo de errores necesario y las operaciones con la tabla de símbolos. CLR
Architecture.PNG
19. Estructura
y fases de un compilador (10) Pasadas Consiste en leer un archivo de entrada y
escribir uno de salida. Es común que se apliquen varias fases de la compilación
en una sola pasada Reducción de pasadas Es deseable tener pocas pasadas dado
que la lectura y la escritura de archivos intermedios lleva tiempo. Sin
embargo, en ocasiones resulta muy difícil generar código si no se tiene una
representación intermedia completa. Por ejemplo: Las instrucciones de tipo goto
que saltan hacia delante. En este caso es posible dejar un espacio en blanco y
rellenar cuando la información esté disponible
No hay comentarios:
Publicar un comentario