Académique Documents
Professionnel Documents
Culture Documents
NATURALES NO RENOVABLES
COMPILADORES
TEMA:
“Teoría de Compiladores”
AUTOR:
COORDINADOR:
LOJA – ECUADOR
2009
U NIV E RS IDA D NA CIONA L D E LOJA 2
INTRODUCCIÓN
La construcción de un compilador es una de las tareas más gratas con las que un
informático puede encontrarse a lo largo de su carrera profesional.
Aunque no resulta sensato pensar que una labor tal pueda formar parte de la actividad
cotidiana de la mayoría de estos profesionales, sí es cierto que, con cierta frecuencia, suele
aparecer la necesidad de analizar un fichero de texto que contiene información distribuida
según algún patrón reconocible: ficheros XML, ficheros de inicialización .ini, ficheros con
comandos del sistema operativo, los propios programas fuente, etc.
Es más, el concepto de análisis de un texto puede ser útil para ahorrar trabajo en
situaciones que están fuera del ámbito profesional informático, como por ejemplo la
generación de índices analíticos en archivos de texto escritos con procesadores que no
admiten esta opción.
Pero a pesar de la indudable utilidad de los conceptos generales relacionados con la teoría y
práctica de los análisis de textos, el crear un compilador introduce al informático en un
nuevo mundo en el que el control sobre el ordenador es absoluto y le lleva al paroxismo de
la omnipotencia sobre la máquina. Y es que resulta imprescindible un pleno conocimiento de
todos los conceptos intrínsecos al ordenador: dispositivos de E/S, código máquina utilizado
por el microprocesador, comunicación a bajo nivel entre éste y el resto de sus periféricos,
distribución de la memoria, mecanismos de uso de memoria virtual, etc.
Aunque pocas personas tendrán la oportunidad de crear, mantener, diseñar o formar parte
de un equipo que se dedique a los compiladores, las técnicas utilizadas en el diseño de estos
pueden emplearse con éxito en otras áreas del desarrollo de programas.
1958, Strong y otros proponen una solución al problema de que un compilador fuera
portable, y esta era dividir al compilador en dos fases “front end” (analiza el programa
fuente) y “back end” (genera código objeto para la máquina objeto).
Aparece BNF (Backus-1960, Naur-1963, Knuth-1964) como una guía para el desarrollo
del análisis sintáctico
A mitad de los 70’s Johnson crea YACC para UNIX (generador de analizadores
sintácticos)
Algoritmos
Lenguajes de Programación
Lenguajes Formales
Arquitectura del Computador
Ingeniería de Software
Partes Fundamentales:
FASES DE UN COMPILADOR
Programa Programa
fuente COMPILADOR objeto
Mensaje de error
- Optimización de código
Estructura de un compilador
U NIV E RS IDA D NA CIONA L D E LOJA 6
1.1. EJERCICIOS
S → AA
A → AAA | a | bA |Ab
S →AA→ bAA → bbAA → bbaA → bbabA → bbabAAA → bbabaAA → bbabaAbA→ bbabaabA → babaaba
Arboles de derivación
S → AB
U NIV E RS IDA D NA CIONA L D E LOJA 7
A → aA | a
B → bB | b
A B
a A b B
a b B
S → SbS | ScS | a
1 y 2) S 3) S
S b S S c S
a S c S S b S a
a a a a
Derivación por la izquierda
S → | Aa | B | D S → Aa |B
B→b B→b
A → aA | bA | B A → aA | bA | B
C → abd
S → ABA S → ABA | λ
A → aA |λ A → aA | a
B → bB | λ B → bB | b
2.1. EJERCICIOS
3.1. EJERCICIO
B → aBC
E → aBEd
L → (a – z)
2
-----
N → (1 – 9)
1 L
L L N
---- N L
3 4 5 6
<inicio> → _ <guion>
<inicio> → l <letra>
<guion> → l <letra> | n <numero>
<letra> → n <numero> | l_<guion> | λ
<numero> → l <letra>
S → A | Aa
A→B
B→C|b
C → D | ab
D→b
1. Unitario(S) → {S, A, B, C, D} 2. S → Aa | b | ab 3. S → Aa | b | ab
Unitario (A) → {A, B, C, D} A → b | ab A→ b | ab
Unitario (B) → {B, C, D} C → ab | b
Unitario (C) → {C, D} D→d
S → bA | aB S → DbA | DaB
A → bAA | aS |a A → DbD1 | DaS |Da
B → aBB | bS | b B →DaD2 | bS | b
Da → a
Db → b
D1→ AA
D2 → BB
S → AB| Cb
A → f | Al
B → t | CF
D→a|t
S → aA| λ
A → aA | bB | λ
B → bB
A → aA | bB | a A → aA | a A → aA | a
B → bB B → bB
S → a| aA | B | E
A → aB | λ
B → Aa
E → bED
D → ccc
S → ABaC
A → AB
B → b |λ
C → D | λ
D → d
Estos componentes léxicos son los operadores, identificadores y palabras reservadas del
lenguaje. Por lo tanto, transforma en flujo de caracteres en un flujo de objetos tokens,
ignorando los comentarios y los espacios en blanco y tabulaciones. Esta primera fase es
capaz de detectar errores de tipo léxico.
Por ejemplo, si en lugar de poner if pusiéramos ifi, el analizador léxico no usaría el token
predefinido IF para esa secuencia de caracteres, sino que entendería que es un
identificador cualquiera (como pudiera ser el nombre de una variable).
Expresión: 1+1 = x;
(a+b) = y;
Expresión: 1 + 1 = x; (a + b) = y;
Por ejemplo, un árbol cuyo nodo raíz es PROGRAMA, que se compone de una lista de clases.
Cada una de estas serian arboles que describen los distintos atributos y métodos de la
misma, y así sucesivamente. Esta fase no puede detectar los errores.
TABLA DE SÍMBOLOS
Mensajes de Error
GRAMÁTICAS
INDEPENDIENTES DE
CONTEXTO
int a ;
(INT,int)(Id,a)(terInst,;)
Gramática
Derivacion
Árbol de construcción
<S>
cte id := <E>
cte
U NIV E RS IDA D NA CIONA L D E LOJA 16
Pasos
TABLAS
Reglas
1. Los conjuntos siguientes son vacíos al inicio excepto el axioma que excluye $
2. AαCβ
S(C)= P(B) – {λ}
3. AαC ó αCβ
P(B) tiene {λ} S(C)= S(A)
Teorema 1:
No ser recursivo por la izquierda
Factorizada
Teorema 2:
No es ambigua
Características:
Primeros y Siguientes
Procedimiento:
Calcular primeros símbolos no terminales
Calcular siguientes símbolos no terminales
Construir la tabla LL(1)
Ejemplo 1:
PRIMEROS SIGUIENTES
8. F id
TABLA DE ANÁLISIS
id + * ( ) $
E E TE` E TE`
E` E` +TE` E` λ E` λ
T T FT` T FT`
T` T` λ T` *FT` T` λ T` λ
F F id F (E)
Cadena: id + id
9 $ E`T`F id $ Aplicar F id
10 $ E`T` id id $ Continuar
11 $ E`T` $ Aplicar T` λ
12 $ E` $ Aplicar E` λ
13 $ $ Salir Cadena Aceptada
Ejemplo 2:
PRIMEROS SIGUIENTES
TABLA DE ANÁLISIS
( ) ; x $
S S (A)
A A CB A CB
B Bλ B ;A Bλ
C CS Cx
Cadena: ( x )
6 $)B )$ Aplicar B λ
7 $) )$ Continuar
8 $ $ Salir Cadena Aceptada
Ejercicio Propuesto:
PRIMEROS SIGUIENTES
Comprobación de validez semántica. Esta es una de las fases más complejas del proceso de
compilación. Tiene que realizar varias tareas: la resolución de nombres, el tipo de las
expresiones y la evaluación L/R. La resolución de nombres consiste en comprobar que cada
identificador que usemos (ya sea una variable local, parámetro, atributo o método) ha sido
previamente declarado y además, si es visible desde el ámbito actual.
En cuanto a los tipos, hay que comprobar que en las expresiones donde intervengan 2
identificadores (asignación, suma, producto, concatenación, etc.) comprobar que ambos
identificadores aceptan dicha operación, que son de tipos compatibles. La evaluación L/R
consiste en que para cada asignación, cada componente puede aparecer o no en esa posición.
Por ejemplo, el resultado de una serie de operaciones no puede aparecer a la izquierda, solo
a la derecha, ya que no se puede asignar un valor al resultado de una serie de operaciones.
Dado que puede contener información de diversa índole, debe hacerse de forma que su
estructura no sea uniforme, esto es, no se guarda la misma información sobre una variable
del programa que sobre un tipo definido por el usuario. Hace funciones de diccionario de
datos y su estructura puede ser una tabla hash, un árbol binario de búsqueda, etc., con tal
de que las operaciones de acceso sean lo bastante eficientes.
U NIV E RS IDA D NA CIONA L D E LOJA 22
Gramáticas semánticas
El número de reglas requeridas pueden llegar a ser demasiado grande ya que faltaría
muchas generalizaciones sintácticas.
Debido a lo anterior, el análisis gramatical puede ser muy lento y ocupar mucho espacio
en memoria.
Se puede observar que las gramáticas semánticas pueden ser útiles para producir
interfaces de subconjuntos de lenguaje natural.
Una gramática con atributos es una gramática de contexto libre cuyos símbolos pueden
tener asociados atributos y las producciones pueden tener asociadas reglas de evaluación
de los atributos.