Académique Documents
Professionnel Documents
Culture Documents
Compiladores
Notas de clase basadas en 1 Compiladores
Construcción de compiladores de Kenneth C. Louden
2 Lenguajes regulares y análisis léxico
Dr. Francisco Javier Zaragoza Martı́nez
franz@correo.azc.uam.mx 3 Gramáticas y análisis sintáctico
UAM Azcapotzalco
Departamento de Sistemas 4 Análisis sintáctico descendente
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 1 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 2 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 3 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 4 / 240
Contenido Contenido
1 Compiladores
1 Compiladores
Introducción a los compiladores
Una breve historia de los compiladores
2 Lenguajes regulares y análisis léxico Programas relacionados con los compiladores
Proceso de traducción
3 Gramáticas y análisis sintáctico Estructura de un compilador
La estructura del compilador
4 Análisis sintáctico descendente Arranque automático y portabilidad
Lenguaje y compilador de muestra
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 5 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 6 / 240
Programa fuente Compilador Programa objetivo Los compiladores suelen ser programas muy complejos, difı́ciles de
escribir y de entender.
Pero los compiladores se usan en todos los aspectos prácticos de la
Un compilador es un programa que traduce de un lenguaje a otro. computación.
Su entrada es un programa escrito en un lenguaje fuente. Una tarea frecuente es la de escribir aplicaciones con interfaces e
Su salida es un programa escrito en un lenguaje objetivo. intérpretes de instrucciones, más pequeños que un compilador pero
Los programas fuente y objetivo son equivalentes. usando las mismas técnicas.
Normalmente el lenguaje fuente es de alto nivel como C o C++. En este curso estudiaremos las técnicas básicas que permiten la
Normalmente el lenguaje objetivo es de bajo nivel como C o ASM. escritura de compiladores y de estas otras aplicaciones.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 7 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 8 / 240
Contenido Lenguaje máquina y lenguaje ensamblador
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 9 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 10 / 240
El lenguaje ensamblador todavı́a se usa cuando se requiere una gran Al principio se creyó que esto era imposible o poco eficiente.
velocidad o un código muy pequeño: videojuegos, sistemas embebidos. Esto fue desmentido con el desarrollo de FORTRAN por Backus (50s).
Sin embargo tiene varios defectos: Al mismo tiempo Chomsky comenzó a estudiar la teorı́a de lenguajes.
Aún no es fácil de escribir.
Es difı́cil de leer y comprender. La jerarquı́a de Chomsky clasifica a los lenguajes según la complejidad
Es completamente dependiente de la máquina. de sus gramáticas y los algoritmos necesarios para reconocerlos.
Por lo que el código debe reescribirse todo el tiempo. Los lenguajes regulares nos resultarán útiles para llevar a cabo el
Por lo tanto, el siguiente paso natural era la posibilidad de escribir proceso de análisis léxico.
programas en una notación más natural, independientes de la Los lenguajes libres de contexto son la forma estándar de representar
máquina y que todavı́a se pudieran traducir a lenguaje de máquina. la estructura de los lenguajes de programación y son fundamentales
Por ejemplo X = 2. para el proceso de análisis sintáctico.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 11 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 12 / 240
1 Compiladores
El desarrollo de métodos para la generación de código objeto es Introducción a los compiladores
mucho más complejo y continúa hasta nuestros dı́as. Una breve historia de los compiladores
Estas técnicas de mejoramiento de código tienen como objetivo Programas relacionados con los compiladores
aumentar la velocidad del código ejecutable o disminuir su longitud. Proceso de traducción
Estructura de un compilador
También se logró automatizar parte del desarrollo de los compiladores
La estructura del compilador
con los generadores de analizadores sintácticos y los generadores de
Arranque automático y portabilidad
analizadores léxicos (70s).
Lenguaje y compilador de muestra
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 13 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 14 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 15 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 16 / 240
Editores, depuradores, perfiladores y administradores Contenido
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 17 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 18 / 240
Analizador semántico
Optimizador de objetivo
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 19 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 20 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 21 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 22 / 240
expresión
asignación
expresión de asignación
expresión = expresión
expresión de subı́ndice expresión aditiva
subı́ndice adición
identificador identificador número número
expresión ( expresión ) expresión + expresión
hola mundo 3 1
hola mundo 3 1
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 23 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 24 / 240
Analizador semántico Ejemplo de árbol sintáctico abstracto con anotaciones
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 25 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 26 / 240
Optimizador (mejorador) de código fuente Ejemplo de árbol sintáctico abstracto con incorporación de
constantes
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 27 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 28 / 240
El generador de código toma cualquier representación interna del Una posible secuencia de código generado para nuestro ejemplo serı́a:
código (código intermedio) y genera código para la máquina objetivo. Usamos la convención de C para los modos de direccionamiento.
Aquı́ usaremos código ensamblador, aunque la mayorı́a de los
compiladores genera código máquina de manera directa. MOV R0, mundo ;; valor de mundo a R0
Es en esta etapa cuando las propiedades de la máquina objetivo se MUL R0, 2 ;; doble valor en R0
convierten en el factor principal: se deben usar instrucciones que MOV R1, &hola ;; dirección de hola a R1
existan y se debe tener cuidado con la representación interna de los ADD R1, R0 ;; sumar R0 a R1
datos. MOV *R1, 4 ;; constante 4 a dirección en R1
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 29 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 30 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 31 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 32 / 240
Estructuras de datos principales en un compilador Tokens
Existe una gran interacción entre las fases del compilador y las Cuando el analizador léxico reúne los caracteres en un token,
estructuras de datos que soportan esas fases. generalmente lo representa de manera simbólica.
Por lo tanto es importante que cuando se implementen se haga de la Para esto se usa un valor de un tipo de datos enumerado que
forma más eficaz posible sin aumentar la complejidad. represente al conjunto de tokens del lenguaje.
Idealmente, un compilador debe compilar un programa en tiempo A veces se necesita también almacenar información adicional: el
proporcional al número de caracteres del mismo. nombre de un token identificador o el valor de un token literal.
A continuación describiremos algunas de las estructuras de datos En la mayorı́a de los lenguajes sólo se procesa un token a la vez, pero
principales que existen en un compilador. en otros se requiere un arreglo de tokens.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 33 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 34 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 35 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 36 / 240
Esta estructura mantiene la información asociada con las literales Dependiendo de la clase de código intermedio generado, se puede
(constantes y cadenas usadas en el programa). almacenar de diversas formas:
Arreglo de cadenas de texto.
La búsqueda e inserción rápida también son esenciales, pero la Archivo de texto temporal.
eliminación no ocurre en esta estructura. Lista ligada.
Esta tabla es importante porque permite la reutilización de constantes La representación empleada también influye en el tiempo de ejecución
y cadenas y, por lo tanto, la reducción de tamaño del programa. de las etapas de mejoramiento de código.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 37 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 38 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 39 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 40 / 240
Etapa inicial y etapa final Pasadas
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 41 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 42 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 43 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 44 / 240
S T
A B B C A C
H ⇒
H H H
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 45 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 46 / 240
A B A B A H A H
⇒ ⇒
H H K K B B H H
M H
Podemos usar un compilador de la máquina H a la máquina K para Podemos utilizar un compilador para el lenguaje B en la máquina H
traducir el lenguaje de implementación de otro compilador de H a K. para traducir un compilador de A a H escrito en el lenguaje B.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 47 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 48 / 240
Compilación cruzada Compilador escrito en el lenguaje que compila
A H A H S T
⇒
B B K K S
K
Es común escribir un compilador en el mismo lenguaje que compila.
Aunque parece que esto es un problema debido a que el compilador
Podemos utilizar un compilador para el lenguaje B en la máquina K no se puede compilar a sı́ mismo, esto resulta muy útil.
para obtener un compilador cruzado de A a H en la máquina K. Veamos dos casos.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 49 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 50 / 240
S T S T A K A K
⇒ ⇒
S S T T A A H H
T H
S T S T A K A K
⇒ ⇒
S S T T A A K K
T H
El compilador azul está escrito en su propio lenguaje. El compilador azul está redirigido a la máquina K.
El compilador rojo (limitado) está escrito en lenguaje máquina. El compilador rojo se ejecuta en la máquina H.
El compilador verde es ineficiente. El compilador verde es un compilador cruzado.
El compilador café es la versión final. El compilador café se ejecuta en la máquina K.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 51 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 52 / 240
1 Compiladores
Introducción a los compiladores Un programa en TINY tiene una estructura muy simple: es una
Una breve historia de los compiladores secuencia de sentencias separadas por puntos y coma.
Programas relacionados con los compiladores Todas las variables son enteras y se declaran automáticamente.
Proceso de traducción Existen solamente dos secuencias de control: if y repeat.
Estructura de un compilador
Existen sentencias de lectura y escritura.
La estructura del compilador
Arranque automático y portabilidad Se permiten comentarios no anidados.
Lenguaje y compilador de muestra Las expresiones son aritméticas y booleanas.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 53 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 54 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 57 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 58 / 240
El trabajo del analizador léxico es leer los caracteres del código fuente Note que los primeros dos tipos de token representan a una única
y agruparlos en unidades lógicas llamadas tokens. cadena de caracteres y que los últimos dos representan a varias
Formar tokens es parecido a deletrear palabras en español. cadenas de caracteres.
En un compilador los tokens se definen como un tipo enumerado: Para distinguir claramente entre un token y la cadena que representa
typedef enum { se le llama a esta última su lexema.
IF, THEN, ELSE, PLUS, MINUS, NUM, ID, ...} TokenType; Por ejemplo, el token IF tiene a la cadena if como lexema.
Los tokens caen en diversas categorı́as: Los tokens que corresponden con las palabras reservadas y los
Las palabras reservadas como IF y THEN que representan a las cadenas sı́mbolos especiales tienen un único lexema.
de caracteres if y then. Los tokens que corresponden con literales representan una cantidad
Los sı́mbolos especiales como PLUS y MINUS que representan a los
infinita de lexemas, como NUM y los números.
caracteres + y -.
Las literales como NUM que representa a los números. Los tokens que corresponden con identificadores también representan
Los identificadores como ID que representa a los nombres. una cantidad infinita de lexemas.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 59 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 60 / 240
Aunque la tarea del analizador léxico es la de convertir todo el Considere la lı́nea de código fuente:
programa fuente en una secuencia de tokens, normalmente no lo hace a[index] = 4 + 2
todo a la vez. Suponga que esta lı́nea de entrada se almacena en un buffer:
En lugar de eso lo hará bajo el control del analizador sintáctico, a [ i n d e x ] = 4 + 2
simplemente devolviendo el siguiente token de la entrada:
Entonces una llamada a getToken deberá saltarse el primer espacio,
TokenType getToken(void); reconocer a la cadena a como un token y devolver el valor de token
Esta función devolverá el siguiente token de la entrada y calculará sus ID, de modo que la siguiente llamada a getToken comenzará a leer el
atributos, guardando los resultados en un buffer. carácter [.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 63 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 64 / 240
Contenido Expresiones regulares
2 Lenguajes regulares y análisis léxico Las expresiones regulares representan patrones simples de caracteres.
Análisis léxico
Expresiones regulares Una expresión regular r define un lenguaje L(r ): el conjunto de las
Autómatas finitos cadenas con las que concuerda.
Autómatas no determinı́sticos A L(r ) se le llama el lenguaje generado por r .
Implementación de un analizador léxico Este lenguaje depende del conjunto de caracteres disponible.
A este conjunto se le llama alfabeto y se suele denotar por Σ.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 65 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 66 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 67 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 68 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 69 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 70 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 71 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 72 / 240
Números flotantes Palabras reservadas
E = F eZ .
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 73 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 74 / 240
Identificadores Comentarios
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 75 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 76 / 240
Ambigüedad Contenido
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 77 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 78 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 79 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 80 / 240
¿Qué significa el diagrama anterior? Autómatas finitos determinı́sticos
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 81 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 82 / 240
Diferencias entre la definición y nuestro uso Ejemplo de un autómata finito con todas las transiciones
L son la letras.
D son los dı́gitos.
O = ¬(L|D) son los otros caracteres.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 83 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 84 / 240
Un autómata para reconocer enteros con signo Un autómata para reconocer comentarios en C
A ∗
+
∗
D / ∗ /
inicio signo entero D
− A B C D E
D O
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 85 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 86 / 240
L
La definición matemática de un autómata no indica todos los
aspectos de su funcionamiento.
Por ejemplo, no indica qué hacer cuando se alcance un estado de L [O]
inicio ident ID
error o de aceptación.
Cuando se hace una transición generalmente se agrega el carácter de
entrada a una cadena que eventualmente será el lexema de un token.
D
Cuando se alcanza un estado de aceptación se devuelve el token
encontrado y sus atributos.
Cuando se alcanza un estado de error se devuelve un carácter a la El estado inicial tiene otras transiciones en ¬L no mostradas.
entrada o se genera un token de error. En el estado final se devuelve el token ID.
En la transición [O] se devuelve el carácter leı́do a la entrada.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 87 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 88 / 240
Dos o más autómatas con caracteres iniciales distintos Combinados en un solo autómata
: =
1 2 assign
=
2 assign
< = < =
1 2 LE 1 4 LE
EQ
=
1 EQ
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 89 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 90 / 240
Dos o más autómatas con caracteres iniciales iguales Combinados equivocadamente en un solo autómata
< =
1 2 LE
=
2 LE
<
LT
<
1 LT
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 91 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 92 / 240
LE
2 Lenguajes regulares y análisis léxico
= Análisis léxico
Expresiones regulares
< > Autómatas finitos
1 2 NE Autómatas no determinı́sticos
[O] Implementación de un analizador léxico
LT
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 93 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 94 / 240
< =
En principio se pueden combinar los autómatas correspondientes a 1 2 LE
todos los tipos de token en uno gigante.
ǫ
Sin embargo esto se vuelve una tarea muy complicada.
Una posibilidad es ampliar la definición de autómata para permitir ǫ < >
cero o más transiciones desde un estado con un mismo sı́mbolo. 0 3 4 NE
A estos autómatas los llamaremos no determinı́sticos. ǫ
También permitiremos transiciones con la cadena vacı́a ǫ.
Estos autómatas no representan algoritmos. <
5 LT
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 95 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 96 / 240
Autómatas finitos no determinı́sticos Ejemplo de un autómata finito no determinı́stico
2
Definición
Un autómata finito no determinı́stico M consta de un alfabeto Σ, un a ǫ
conjunto de estados S, una función de transición T : S × (Σ ∪ ǫ) → 2S , un b
estado inicial s0 ∈ S y un conjunto de estados de aceptación A ⊆ S.
a ǫ
Lenguaje aceptado 1 3 4
El lenguaje L(M) aceptado por M es el conjunto de cadenas de caracteres ǫ
c = c1 c2 · · · cn ∈ (Σ ∪ ǫ)∗ tales que s1 ∈ T (s0 , c1 ), s2 ∈ T (s1 , c2 ), ldots,
sn ∈ T (sn−1 , cn ) con sn ∈ A.
La cadena abb puede aceptarse por cualquiera de las transiciones:
→ 1 →a 2 →b 4 →ǫ 2 →b 4 o
→ 1 →a 3 →ǫ 4 →ǫ 2 →b 4 →ǫ 2 →b 4.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 97 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 98 / 240
L [O]
Existen diversas maneras de implementar un autómata finito en un 1 2 3
programa.
No todas son apropiadas en general, pero algunas son sencillas.
D
Por el momento analizaremos tres opciones básicas:
1 Condicionales anidados.
2 Casos anidados. if siguiente carácter es una letra then
3 Tabla de transición. avanzar en la entrada
while siguiente carácter es una letra o un dı́gito do
avanzar en la entrada
aceptar
else
error u otros casos
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 99 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 100 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 101 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 102 / 240
s←1
c se lee de la entrada 2 Lenguajes regulares y análisis léxico
while not A[s] and not E [s] do Análisis léxico
n ← T [s, c] Expresiones regulares
if L[s, c] then Autómatas finitos
c se lee de la entrada Autómatas no determinı́sticos
s←n Implementación de un analizador léxico
if A[s] then
aceptar
else
error
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 103 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 104 / 240
Tokens del lenguaje de muestra Convenciones léxicas adicionales
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 105 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 106 / 240
MAS
+
Ya tenemos autómatas para los números y los identificadores.
El autómata para los comentarios es particularmente simple.
− + − ∗/ =< ();
Los autómatas para los demás tokens son sencillos pues constan de inicio MEN inicio FIN
cadenas fijas.
PYC
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 107 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 108 / 240
Autómata para los sı́mbolos, números e identificadores Autómata para el analizador léxico
D
D
NUM
NUM O
L
D [O]
D [O]
+ − ∗/ =< (); COM ID
inicio FIN L [O]
}{
L L [O] O
inicio = FIN
: [O]
ID
B ASI
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 109 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 110 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 111 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 112 / 240
Contenido Análisis sintáctico
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 113 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 114 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 115 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 116 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 117 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 118 / 240
Una gramática libre de contexto es un tipo más sofisticado de En el ejemplo anterior se usó el sı́mbolo → para indicar que un
especificación sintáctica de un lenguaje. sı́mbolo genera cualquiera de las cadenas a su derecha separadas por
Son similares a las expresiones regulares pero permiten la recursión. el sı́mbolo |.
Un ejemplo de lenguaje que se puede expresar con una gramática libre Como con las expresiones regulares se usa la concatenación, pero a
de contexto es el que representa a las expresiones simples aritméticas diferencia de éstas no se usa la cerradura de Kleene para la repetición.
con operaciones de suma, resta y multiplicación. Esto se debe a que la repetición se puede expresar recursivamente.
Estas expresiones se pueden dar mediante la siguiente gramática: El alfabeto de una gramáticas libres de contexto suele constar de
1 E → EOE |(E )|N. tokens (definidos a su vez por expresiones regulares) y caracteres
2 O → +| − |∗. simples.
Donde N representa a un número entero. A esto se le llama la forma Backus-Naur (BNF).
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 119 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 120 / 240
Especificación de una gramática libre de contexto Especificación alternativa de una gramática
Una regla gramatical libre de contexto en BNF es una cadena de Serı́a perfectamente válido especificar nuestro ejemplo como:
sı́mbolos donde: 1 E → EOE .
El primer sı́mbolo es el nombre de una estructura. 2 E → (E ).
El segundo sı́mbolo es →. 3 E → N.
Los siguientes sı́mbolos son caracteres del alfabeto, nombres de 4 O → +.
estructuras o |. 5 O → −.
Informalmente, una regla gramatical define una estructura. En 6 O → ∗.
nuestro ejemplo anterior:
Sin embargo, normalmente agruparemos todas las opciones que
E → EOE |(E )|N define una expresión E .
definan a una estructura en una sola regla.
O → +| − |∗ define un operador O.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 121 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 122 / 240
(34 − 3 ∗ 42
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 125 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 126 / 240
Ejemplo de gramática para paréntesis anidados Ejemplo de una gramática para sumas
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 127 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 128 / 240
Ejemplo de una gramática para decisiones anidadas Recursión por la izquierda y por la derecha
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 129 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 130 / 240
Ejemplo de gramática para paréntesis balanceados Ejemplo de otra gramática para decisiones anidadas
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 131 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 132 / 240
E ⇒ EOE (9)
Necesitamos una representación que mantenga la estructura de una
⇒ (E )OE (10)
cadena de terminales, abstrayendo las caracterı́sticas esenciales de
⇒ (EOE )OE (11) una derivación al mismo tiempo que se eliminan las diferencias
⇒ (NOE )OE (12) superficiales.
⇒ (N − E )OE (13) Un árbol de análisis gramatical correspondiente a una derivación es
⇒ (N − N)OE (14) un árbol en el cual los nodos interiores están etiquetados por no
terminales, las hojas están etiquetadas por terminales y los hijos de
⇒ (N − N) ∗ E (15)
cada nodo interno representan el reemplazo del no terminal asociado
⇒ (N − N) ∗ N. (16) en un paso de la derivación.
La diferencia entre esta derivación y la que vimos antes es el orden de
los reemplazos
Esto es en realidad una diferencia superficial.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 135 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 136 / 240
Ejemplo de un árbol de análisis gramatical en preorden Ejemplo de un árbol de análisis gramatical en posorden
La derivación La derivación
E1 E1
E2 O3 E4 E4 O3 E2
+ N + N
N N
Observe que la numeración de los nodos internos fue en preorden. Observe que la numeración de los nodos internos fue en posorden
inverso.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 137 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 138 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 139 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 140 / 240
3 4
que contiene estrictamente la información necesaria.
En este último árbol se muestran los valores verdaderos de los tokens.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 141 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 142 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 143 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 144 / 240
Ejemplo de árbol sintáctico abstracto para decisiones Ejemplo de estructura para decisiones
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 145 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 146 / 240
Ejemplo de árbol sintáctico abstracto para secuencias de Ejemplo alternativo de árbol sintáctico abstracto para
sentencias secuencias de sentencias
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 147 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 148 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 149 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 150 / 240
N = 34 N=3
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 151 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 152 / 240
Segundo árbol de análisis gramatical Segunda derivación izquierda
N=3 N = 42
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 153 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 154 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 155 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 156 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 157 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 158 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 159 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 160 / 240
Árbol de análisis gramatical para N − N ∗ N Árbol de análisis gramatical para N − N − N
E
E
E S T
E S T
E S T − F
T − T M F
T − F N
F F ∗ N
F N
N N
N
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 161 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 162 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 163 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 164 / 240
S
La respuesta depende de si queremos asociar el else con el primero o
I con el segundo if.
El siguiente fragmento de código en C nos ayudará a decidir:
if ( D ) S if (x != 0.0)
if (y == 1.0/x) ok = 1;
0 I else z = 1.0/x;
Es decir: esperamos que el else se asocie con el último if no asociado.
if ( D ) S else S
A esto se le llama la regla de la anidación más cercana.
1 c c
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 165 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 166 / 240
S
Una solución para el problema es como sigue:
J
S → I |J
I → if (D)I else I |c if ( D ) S
J → if (D)S| if (D)I else J
D → 0|1. 0 I
Esto funciona al permitir que llegue solamente una sentencia igualada if ( D ) I else I
J antes que un else en una sentencia if.
1 c c
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 167 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 168 / 240
Ambigüedad no esencial Contenido
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 169 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 170 / 240
P → S; P|S
Las construcciones repetitivas y opcionales son muy comunes en las
estructuras de los lenguajes de programación. se escribirı́a en EBNF como
Es por eso que en ocasiones se extiende la notación BNF con
P → S{; S}
notaciones especiales para estos casos.
Una de estas notaciones es la BNF extendida o EBNF. lo que resulta en recursión por la izquierda.
La repetición se simboliza con llaves {}, como en A → {α}β en lugar En el caso de las expresiones aritméticas tenemos que la regla
de la regla recursiva por la izquierda A → Aα|β.
E → EST |T
La opción se simboliza con corchetes [], como en A → [α]β en lugar
de A → αβ|β. se escribirı́a en EBNF como
E → {TS}T
P → S; P|S
3 Gramáticas y análisis sintáctico
se escribirı́a en EBNF como
El proceso del análisis sintáctico
P → S[; P] Gramáticas libres de contexto
Árboles de sintaxis abstracta
lo que resulta en recursión por la derecha. Ambigüedad
En el caso de las expresiones aritméticas tenemos que la regla Notación EBNF
Sintaxis del lenguaje Tiny
E → EST |T
E → T [SE ]
Una gramática libre de contexto para Tiny Declaraciones en C para un nodo de árbol sintáctico
Programa P → P; S|S typedef enum {StmtK,ExpK} NodeKind;
Sentencia S → I |R|A|L|W typedef enum {IfK,RepeatK,AssignK,ReadK,WriteK} StmtKind;
If I → if E then P end|if E then P else P end typedef enum {OpK,ConstK,IdK} ExpKind;
Repeat R → repeat P until E typedef enum {Void, Integer, Boolean} ExpType;
Asignación A → D := E
#define MAXCHLIDREN 3
Lectura L → read D
Escritura W → write E typedef struct treeNode {
Expresión E → XCX |X struct treeNode *child[MAXCHILDREN];
Comparación C →< | = struct treeNode *sibling;
Exp. Simple X → XUT |T int lineno;
NodeKind nodekind;
Suma U → +|−
union {StmtKind stmt; ExpKind exp;} kind;
Término T → TMF |F union {TokenType op; int val; char *name;} attr;
Multiplicación M → ∗|/ ExpType type;
Factor F → (E )|N|D (Número e iDentificador). } TreeNode;
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 175 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 176 / 240
Ejemplo de un programa en Tiny Ejemplo de un árbol sintáctico para un programa
read(x) if
id(fact)id(x)
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 177 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 178 / 240
Contenido Contenido
1 Compiladores
4 Análisis sintáctico descendente
Análisis sintáctico descendente
2 Lenguajes regulares y análisis léxico
Análisis sintáctico descendente recursivo
Análisis sintáctico LL(1)
3 Gramáticas y análisis sintáctico Conjuntos primero y siguiente
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 179 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 180 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 181 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 182 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 183 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 184 / 240
Ejemplo con la gramática de expresión Aclaraciones
Considere la gramática de expresión vista anteriormente: En el algoritmo anterior suponemos que existe una variable que
E → EST |T mantiene el token actual de la entrada.
S → +|− También suponemos que existe un procedimiento que empata el token
T → TMF |F actual con su parámetro, avanza en la entrada si tiene éxito y señala
M→∗ un error en caso contrario:
F → (E )|N
if el token es el esperado then
Entonces un procedimiento que reconoce un factor F serı́a: lee un nuevo token
else
if token es un ( then señala un error.
empata un ( Por el momento suponemos que el señalar un error imprime un
reconoce una expresión E mensaje y termina el proceso de compilación.
empata un ) Observe también que reconocer un factor es un procedimiento
else if token es un número then recursivo. Esto se debe a que debe reconocer una expresión, el
empata un número procedimiento para reconocer una expresión debe reconocer un
else término y el procedimiento para reconocer un término debe reconocer
señala un error. un factor.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 185 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 186 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 189 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 190 / 240
Construcción del árbol sintáctico de una expresión Construcción del árbol sintáctico de una decisión
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 191 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 192 / 240
Contenido El método básico del análisis sintáctico LL(1)
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 193 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 194 / 240
R
El analizador sintáctico comenzará con el sı́mbolo especial y el
Paso sı́mbolo inicial en la pila.
RPila EntradaR Acción
1 () R S → (S)S Aceptará una cadena de entrada si después de una serie de acciones
RS
2 () R empata ( la pila y la entrada terminan únicamente con el sı́mbolo especial.
R S)S(
3 R S)S )R S → ǫ Paso Pila Entrada Acción
4 R S) ) R empata )
R R
5 RS R S →ǫ 1 S ABC acción
6 acepta .. R R
. R ··· ···R acción
N acepta
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 195 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 196 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 199 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 200 / 240
Ejemplo de tabla de análisis sintáctico Gramáticas LL(1)
Considere la gramática S → (S)S|ǫ.
Como sólo hay una producción no vacı́a de S
S → (S)S Observe que la tabla presentada contiene a lo más una opción para
cada combinación de no terminal en la pila y token en la entrada.
entonces cada cadena derivable de S es vacı́a o comienza con un ( y A las gramáticas que cumplen esto se les llama gramáticas LL(1).
por lo tanto esta producción se agrega a M[S, (].
Esto también significa que una gramática que cumple esta propiedad
Como S → (S)S entonces la segunda regla se aplica con
no puede ser ambigua (aunque en ocasiones permitiremos una
α = ǫ, β = (, A = S, a =) y γ = S ambigüedad si tenemos una regla de eliminación de ambigüedad).
A continuación mostraremos un algoritmo que es capaz de realizar el
de manera que S → ǫ se agrega a M[S, )].
R análisis sintáctico usando la tabla de análisis sintáctico para una
Como S ⇒∗ S entonces S → ǫ se agrega a M[S, ]. gramática LL(1).
Esto completa la tabla:
R
M[N, T ] ( )
S S → (S)S S → ǫ S → ǫ
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 201 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 202 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 205 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 206 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 207 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 208 / 240
Recursión inmediata por la izquierda simple Ejemplo de recursión inmediata por la izquierda simple
Recursión inmediata por la izquierda general Ejemplo de recursión inmediata por la izquierda general
Enseguida mostramos un algoritmo que sólo está garantizado para Considere la gramática A → Ba|Aa|c y B → Bb|Ab|d con el orden
funcionar con gramáticas sin producciones vacı́as (A → ǫ) ni ciclos de A, B.
al menos un paso (A ⇒+ A). Primero se elimina la recursión inmediata por la izquierda de A de
Se supone que los no terminales tienen un orden A1 , . . . , Am . modo que la primera regla se reemplaza por A → BaA′ |cA′ y
A′ → aA′ |ǫ.
for i = 1 to m do
for j = 1 to i − 1 do Segundo se elimina la regla B → Ab de modo que la segunda regla se
Reemplaza cada selección de regla gramatical de la forma reemplaza por B → Bb|BaA′ b|cA′ b|d.
Ai → Aj β por la regla Ai → α1 β| · · · |αk β donde Aj → α1 | · · · |αk Tercero se elimina la recursión inmediata por la izquierda de B de
es la regla actual para Aj . modo que la segunda regla se reemplaza por B → cA′ bB ′ |dB ′ y
Elimina la recursión inmediata por la izquierda de Ai . B ′ → bB ′ |aA′ bB ′ |ǫ.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 213 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 214 / 240
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 215 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 216 / 240
Tabla LL(1) para las expresiones simples Factorización por la izquierda
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 217 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 218 / 240
Algoritmo para factorización por la izquierda Primer ejemplo de factorización por la izquierda
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 219 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 220 / 240
Segundo ejemplo de factorización por la izquierda Construcción del árbol sintáctico en análisis LL(1)
Considere la producción La construcción del árbol sintáctico cuando se usa análisis sintáctico
LL(1) no es trivial.
I → if (E )S|if (E )S else S
Una razón es que la eliminación de la recursión izquierda y la
para decisiones simples. factorización por la izquierda oscurecen la gramática.
La producción tiene un prefijo compartido if (E )S que se puede Pero la razón principal es que la pila de análisis sintáctico no contiene
factorizar por la izquierda. tokens vistos, sino predicciones de tokens.
Esto nos genera las dos producciones Por lo tanto, se debe posponer la creación de nodos del árbol hasta
que se eliminen las estructuras de la pila.
′
I → if (E )SI En general, esto requiere que se use una pila extra para seguir la pista
de los nodos del árbol sintáctico y que se inserten marcadores de
y
acción en la pila de análisis sintáctico.
I ′ → else S|ǫ.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 221 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 222 / 240
Ejemplo de cálculo de valores Ejemplo de pila de análisis sintáctico con pila de valores
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 225 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 226 / 240
Algoritmo para calcular el conjunto primero Algoritmo simplificado para calcular el conjunto primero
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 227 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 228 / 240
Ejemplo de cálculo del conjunto primero para expresiones Ejemplo de cálculo del conjunto primero para decisiones
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 229 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 230 / 240
R
Si A es un no terminal de la gramática entonces el conjunto siguiente
R S(sı́mbolo inicial) ← { }
de X , llamado S(X ), compuesto de terminales y posiblemente se for todo no terminal A 6= sı́mbolo inicial do
define de la siguiente manera: S(A) ← ∅
R
1 Si A es el sı́mbolo inicial entonces está en S(A). while existan cambios a cualquier S(A) do
2 Si hay una producción B → αAγ entonces P(γ) \ {ǫ} está en S(A). for cada selección de producción A → X1 X2 . . . Xn do
3 Si hay una producción B → αAγ tal que ǫ está en P(γ) entonces S(A) for cada Xi que sea un no terminal do
contiene a S(B).
R agregar P(Xi+1 Xi+2 . . . Xn ) \ {ǫ} a S(Xi )
Observe que siempre está en S(A) para el sı́mbolo inicial A y que ǫ if ǫ ∈ P(Xi+1 Xi+2 . . . Xn ) then
nunca es un elemento de S(A). agregar S(A) a S(Xi )
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 231 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 232 / 240
Ejemplo de cálculo del conjunto siguiente para expresiones Ejemplo de cálculo del conjunto siguiente para decisiones
E → EST E →T S →+ S →I S →c
S →− T → TMF T →F I → if (D)SE E → else S
M→∗ F → (E ) F →N E →ǫ D→0
D→1
Para la que obtuvimos P(E ) = {(, N}, P(T ) = {(, N},
P(F ) = {(, N}, P(S) = {+, −} y P(M) = {∗}. Para la que obtuvimos P(S) = {c, if}, P(I ) = {if}, P(E ) = {else, ǫ}
R y P(D) = {0, 1}.
Comenzamos con S(E ) = { } y S(T ) = S(F ) = S(S) = S(M) = ∅. R
R Comenzamos con S(S) = { } y S(I ) = S(E ) = S(D) = ∅.
R paso se actualizaRS(E ) = { , +, −}, S(S) = {(, N},
En el primer R
S(T ) = {R , +, −}, S(T ) = { , +,
R −, ∗}, S(M) = {(, N}, R paso se actualizaR S(I ) = { }, S(D) = {)},
En el primer
S(F ) = { , +, −, ∗} y S(E ) = { , +, −, ∗}. S(S) = { , else} y S(E ) = { }.
R R R
En el segundo
R paso se actualiza S(T ) = { , +, −, ∗, )} y En el segundo paso se actualiza S(I ) = { , else} y S(E ) = { , else}.
S(F ) = { , +, −, ∗, )}. En el tercer paso ya no hay actualizaciones.
En el tercer paso ya no hay actualizaciones.
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 233 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 234 / 240
Construcción de tablas de análisis sintáctico LL(1) Ejemplo para el cálculo de la tabla LL(1) de expresiones
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 235 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 236 / 240
Tabla LL(1) para las expresiones simples Ejemplo para el cálculo de la tabla LL(1) de decisiones
Si calculamos los conjuntos primero y siguiente obtenemos: Considere la gramática simplificada para decisiones anidadas:
E SE′ T M T′
F S → I| c I → if (D)SE
E → ǫ|else S D → 0|1.
R N +,R −, ǫ +, − R (, N
P (, R ∗, ǫ ∗ R (, N
S ,) ,) (, N , ), +, − , ), +, − (, N , ), +, −, ∗ Si calculamos los conjuntos primero y siguiente obtenemos:
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 237 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 238 / 240
. .
Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 239 / 240 Francisco Zaragoza (UAM Azcapotzalco) Compiladores Trimestre 11I 240 / 240