Escolar Documentos
Profissional Documentos
Cultura Documentos
Introduccin
Un compilador es un programa que traduce un lenguaje (cdigo fuente de otro programa) de
cdigo en otro texto en lenguaje objeto.
Compilador
Fase de anlisis
En la fase de anlisis se estudia el lenguaje del programa fuente, errores, elementos de
inters Esta fase tambin se denomina procesador del lenguaje y es lo que vamos a ver en
esta asignatura. La fase de anlisis se describe en tres subfases:
Anlisis lxico
Se encarga de analizar los elementos ms pequeos de un texto que tienen sentido por s
mismas.
Anlisis sintctico
Se encarga de analizar la estructura de un texto.
1
Anlisis semntico
Se encarga de estudiar el significado de todos los elementos dentro del texto.
Ejemplo
Texto Fuente
lmite := largo * alto 1
Analizador lxico
El analizador lxico estudia carcter a carcter conociendo las estructuras mnimas que tienen
sentido por s mismas. A estas se las denomina Tokens.
l no tiene
sentido en lar no tiene
s mismo. sentido en s
mismo. * S tiene alto S tiene
sentido sentido
Texto resultado
Identificador1/op.asignacin1/identificador2/op.
aritmtica1/identificador3/op.aritmtico2/constante_entera1/
A grandes rasgos este sera el resultado del analizador. Cada token necesitara ms
informacin pero eso lo veremos ms adelante.
Analizador sintctico
Estudia la estructura de la secuencia de tokens para conocer si es una estructura permitida o
no lo es.
En el ejemplo:
2
rbol resultado
Resulta entonces en un rbol sintctico donde se detalla la estructura de la sentencia:
Este rbol es la entrada del analizador semntico que estudia si la sentencia (estructuralmente
correcta) tiene sentido en el lenguaje.
Analizador Semntico
Este analizador hace anotaciones en el rbol sintctico comprobando tipos, variables
definidas,
Por ejemplo:
3
Control de errores
Cada fase de anlisis tiene sus propios errores:
Tabla de smbolos
La tabla de smbolos es una coleccin de smbolos que utiliza nuestro texto para almacenar
informacin de cada token. El procesador del lenguaje interacta con ella para almacenar y
consultar su contenido.
Fase de sntesis
Una vez resuelta sin errores la fase de anlisis comienza la fase de sntesis que ser la
encargada de construir el texto objeto del texto fuente que hemos utilizado. La fase de sntesis
se subdivide en tres mdulos:
Su otra misin es muy til para reutilizar mdulos ya que podemos traducir muchos lenguajes
al mismo lenguaje intermedio.
En el ejemplo:
temp2:= 1
temp3:=temp1-temp2
id1:=temp1
Optimizador
El lenguaje resultante del generador de cdigo intermedio (CI) suele ser demasiado
redundante y poco eficiente ya que traducen paso a paso el rbol semntico sin fijarse en
4
pasos anteriores. Por ello es necesario el optimizador, para convertir el CI en un lenguaje
eficiente:
id1 := temp1 1
Generador de cdigo
El ltimo paso del proceso de sntesis es muy similar al primero, el generador de cdigo se
encarga de traducir el CI optimizado resultado del proceso anterior, que es ms fcil que el
lenguaje inicial, en cdigo ensamblador de muy bajo nivel.
En el ejemplo:
mul id3, r1
sub #1, r1
Lenguajes y gramticas
5
A 0
Entonces:
A 0A 00 L(G1) = { C/ A *C} = {0,1}*0
A 1A 10A 100
Jerarqua de Chomsky
Tipo 0 (sin restricciones) = Las reglas de produccin pueden ser de cualquier tipo.
,{N U T}*
R. por la izquierda
B B Ejemplo: BB1
BB1B11
Existen analizadores sintcticos incompatibles con esta recursividad por eso debemos crear
una gramtica equivalente sin recursividad por la izq.
A A
A A A
A A A A
6
Factorizar por la izquierda
A A 1B Existen
A A 1C
A A
A
A
Gramtica ambigua
Una gramtica es ambigua si existen dos formas diferentes de generar una misma sentencia,
una misma cadena. Los procesadores del lenguaje no son compatibles con las G. ambiguas.
Ejemplo:
1. S if E then S
2. S if E then S else S
3. S P
y en el lenguaje aparece:
de forma:
pero:
Hemos llegado a la misma cadena mediante dos caminos generadores. Esta es una gramtica
ambigua. Ningn analizador sintctico permite una gramtica ambigua ya que esta generara
distintos rboles y, por tanto, distintos cdigos objeto.
Ejercicio
EE+T
ET
T T*F
Fa
F (E)
TF
Es una gramtica recursiva por la izquierda. Elimina dicha recursividad.
7
Anlisis lxico
Definiciones
Token (componente lxico)
Cada uno de los elementos del lenguaje que estamos identificando que tienen sentido o
significado por s mismos. Es un conjunto mnimo de caracteres. Ejemplo:
8
Todo token tiene algunos componentes importantes:
Lexema
Es el conjunto de caracteres que forman un token. Ejemplo:
Patrn
La regla que describe como un determinado lexema se asocia a un determinado token.
Ejemplo:
Secuencia alfanumrica (sin espacios ni signos de puntuacin) que empieza por una letra en
un identificador.
Tipos de token
Existen algunos tipos bsicos que aparecen de forma habitual:
Identificador
Nmero
o Nmero real
o Nmero complejo
o Nmero entero
Operadores
o Asig. :=
o Relac. <, >, =, <=,
o Aritm. +, -, /, *, **,
Puntuacin ; , {, }, (, ), (Aunque hay que saber que cada uno de estos smbolos
serian tokens distintos ya que se diferencian a nivel sintctico.)
Palabras clave If, Do, While, Como antes, aunque las hemos agrupado juntos, lo
normal es que cada palabra clave forme un token.
Un Ejemplo
Analizador
a + b * C Analizador id1/op.aritm1/id2/op.aritm2/id3 ji/d
lxico lxico
Como puede verse, ambas sentencias producen el mismo listado de tokens a pesar de ser muy
diferentes. Si se enviaran al Analizador sintctico se perdera la informacin de esa sentencia.
Por eso debemos enviar ms informacin.
Entonces, el token lleva informacin adicional. Un token ser una tupla con la siguiente
estructura:
9
Ejemplo de funcionamiento
i f _ l i m i t e _ > 1 0 0 _ j _ = l i m i t e * n u m ;
Tabla de smbolos
Pos Lexema Tipo
1 Lmite
2 J
3 Num
Diseo lxico
Todo analizador lxico depender del lenguaje sobre el que se va a disear. Cualquier diseo
sigue un nmero determinado de pasos:
10
5. Tratar errores (incluyendo mensajes de error).
6. Implementar el AFD.
Ejemplo
Lenguaje Secuencia de identificadores separada por blancos. El patrn de los
identificadores es el descrito anteriormente.
Por ejemplo:
lmite_j_ind13
hola_estoy____aqui
Paso 1
Tokens: <id, pos_TS>
Paso 2
<N, T, P, S> P: S lA (l es cualquier letra l = a-z, A-Z)
A lA / dA (d es cualquier dgito d=0-9)
A
Paso 3
Paso 4
Acciones semnticas
C: lexema es la l
11
Paso 5
Llegados a este punto definiremos que cualquier cosa que no contemple el autmata es un
error, sin necesidad de especificarlo de forma explcita. Sin embargo, habra que definir los
mensajes de error.
Ejercicio
Hacer un diseo igual que este para el lenguaje:
12
Paso 3: Autmata finito
Paso 5: Errores
Los mensajes de error se crean y envan desde el mdulo de control de errores. Un analizador
lxico solo tendra que enviar a dicho mdulo un cdigo de error para cada operacin que no
se contemple en el autmata finito.
El nico error que podra darse en este ejemplo sera M1 cuando despus de : no se lee un
=.
13
Hay dos formas bsicas de manejar un error, descubrirlo y terminar (que es la forma fcil) o
volver al principio para subsanar el error.
Ejercicio
Qu cambios habra que realizar en los puntos 3 y 4 para tratar palabras
reservadas?
Aadidos al ejemplo
Un cambio que podramos realizar es aadir un op. relacional nuevo: >=. En el autmata
modificamos la rama del op. relacional (estado 9), de la siguiente forma:
Comentarios
Para los comentarios debemos aadir
al lenguaje /
14
que estamos, aadir el operador divisin.
Cadena
La cadena es algo diferente porque s genera un token: token cadena <cadena, puntero a
memoria> Se almacena en memoria debido a su tamao, demasiado grande para la TS.
Debemos aadir al lenguaje || (comillas dobles)
P = Reserva memoria.
*Salvo y /
dig+[.dig+][e[signa]dig+]
<entero, valor>
<real, valor>
Paso 2
Gramtica:
N dN//.D/eE (bucle para crear entero/fin de la parte entera sin decimales y sin
exponente/decimales tras la parte entera/exponente tras la parte entera)
15
D dD//eE (bucle para crear ms decimales/fin de la parte decimal sin
exponente/exponente tras la parte decimal)
Paso 3
Paso 4
Acc. semnticas
S : Iniciamos variables.
num = 0
exp = 0
ndec = 0
sig = +1
Tipo = null
T = num = d
T = num = num*10+d
T = num = num*10+d
ndec = ndec+1 (aumenta el nmero de posiciones decimales)
por ejemplo:
16
12,57 num=1257
ndec=2
TK2 = valor =
Generar token (real, valor)
V = if - then sig = -1
W = exp = exp*10+d
Ejemplo de Paso 1
Tenemos la siguiente gramtica:
E id |N|-E / (E)
N cte / -cte
id id l / id d / l Reglas lxicas
cte cte d / d
Ejercicio
Dado el siguiente texto en xml:
<tfc>
<autor> Luis Gomez </autor>
<fecha_nac> 18/05/85 </fecha_nac>
<ttulo> Diseo de An. Lxico </titulo>
<tutor> Marian Heras </tutor>
<nota> Sobresaliente 9 </nota>
</tfc>
Se pide analizador lxico para pasar este cdigo a la base de datos. Paso a paso
17
Errores
Errores tpicos
Anlisis lxico
Caracteres que no pertenecen a los terminales. Ao
Identificadores mal formados. 3ab
Constantes mal escritas. 3.0.4
Constantes fuera de lmite. 12975432
Anlisis sintctico
Smbolos no permitidos en esa posicin. If then 3 Begin
Ausencia de delimitadores. i=3__ f=4;
Palabras reservadas mal formadas. ifDhen
Anlisis semntico
Incompatibilidades de tipo en expresiones/asignaciones. entero = entero*3,0
Inconsistencia de tipo entre parmetros formales y actuales.
Identificadores no declarados o definidos mltiplos de un identificador.
Mensajes de error
Los mensajes de error deben seguir una serie de caractersticas:
18
Localizar los errores adecuadamente.
Completos y legibles.
Amables y respetuosos.
Tabla de smbolos
La tabla de smbolos (TS) es el lugar en el que se guarda, de forma ordenada, todos los
identificadores que existen en el texto fuente. La TS es una estructura de datos que est
presente mientras se ejecuta el compilador, entonces, obviamente, no existe cuando se
ejecuta el programa. Esta es una cuestin crtica.
Tipos de informacin
Lexema. La secuencia de caracteres que representa al identificador en el texto fuente.
Tipo del identificador.
ndice, aunque es ms una caracterstica de la propia TS. Suele almacenarse en una
estructura dinmica.
Alcance.
Dimensiones.
Argumentos (procedimiento o funcin).
Tipo de valor devuelto (funcin).
Direccin de memoria esttica, donde se almacena el valor de la variable cuando se
ejecute el programa. Enlace. El propio valor nunca se guarda en la tabla ya que es
necesario en ejecucin, cuando la TS ya no existe.
La TS no es una tabla esttica ya que la cantidad de memoria que se necesita para guardar
cada identificador es variable, depende del nmero de identificadores y la cantidad de
informacin que tengan. La TS es, por tanto, una tabla dinmica.
Organizacin de la TS
Imaginemos los siguientes identificadores: A, Aux, I, Cont, X
TS Lineal
Se introducen de forma lineal en la tabla.
19
TS ordenada
Cont > I
TS hash
En este caso la tabla se ordena segn una funcin hash que le asigna un ndice.
A1
Ya est siendo usada (la funcin
Aux 3 hash no es perfecta)
I1
Con = 3
La evolucin natural de esta solucin es que la TS sea una lista de ndices que enlacen con el Solo se enlazan los
primer identificador de ese ndice en la tabla de desbordamiento. identificadores con
igual ndice.
20
Manejo de errores con la TS
1 Programa bsico
2 Var a:integer
3 Procedure suma (a:integer, b:integer)
4 Begin
5 a:=a+b Problema 1 En este caso existen dos variables a, una dentro
6 End del Procedure y otra global. El compilador considera que esta
7 End variable es la ms cercana, en este caso la que est dentro del
8 Begin
9 Read (a, b) proceso. Debe solucionarse tambin con la TS.
10 Print (suma(a,b))
11 End
Problema 2 Identificador no declarado. En este caso se debe
saber esto gracias a la TS y conociendo el alcance de dicho
identificador.
21
Ejercicio resuelto
Dado este programa
TA TS proc1
D/U D
22
zona de definicin (D/U D). Se aade el identificador b y se vuelve a la zona de uso (D/U
U). Entonces se lee la variable a, al estar en zona de uso se busca en la TS actual (TS proc1) al
no estar se busca en la TS Global, como est se enva el token <id, 1(TS Global)>. Cuando se
llega al smbolo cierre de llave la TS proc1 se borra, ya no hace falta ms y el flas TS pasa a ser
TS Global.
Se continuara de esta forma, creando a continuacin la tabla fun para la funcin fun. Lo nico
destacable es que al leer el carcter u en zona de uso en la TS fun y no estar en ninguna tabla
saltara un error.
Procesos anidados
Dado el ejemplo:
PROGRAM Ejemplo;
VAR a, b : INTEGER;
23
Paso 1
Tabla bloques TS Global
TS Proc2
Tratamiento de registros en TS
Esto ser necesario para la prctica. Tenemos, por ejemplo, la siguiente estructura:
24
Struct Fecha
{int da, mes, ao;
}
Fecha x; Registro de tipo fecha.
Al leer los diferentes campos que habr en un registro. La mejor forma de representarlo es
aadir una TS adicional con el identificador fecha que indexe los campos del registro.
Lo siguiente que sucede es la creacin de una fecha. Como siempre se aade a la TS de forma
normal.
Entonces, ahora se quiere acceder al registro X, como siempre se busca los tokens para enviar.
<id, TS(n+1)>
<punto, -> En este momento se cambia la TS actual a TS Fecha. Ya que se va a querer
acceder a ella.
<id, TSFecha(2)> Tras esto se vuelve a la TS General.
Con este tipo de organizacin de la TS se sabe siempre que tabla se est usando y se elimina la
confusin, permitiendo doble asignacin de variables, por ejemplo.
Anlisis sintctico
En el anlisis sintctico los elementos de trabajo son los tokens que le enva el A. lxico. Este
mdulo es el motor del procesador de lenguajes y es el que marca el ritmo de trabajo. Cuando
lo necesita pide tokens al A. lxico y cuando tiene estructuras correctas las enva al A.
Semntico.
25
El analizador sintctico necesita una gramtica ms avanzada que el lxico. El lxico utilizaba
una gramtica tipo 3, el A. Sintctico utilizar una gramtica de tipo 2 (independiente del
contexto), donde:
A AN
(N U T)*
Es decir, que la nica restriccin es que a la izquierda haya un no terminal.
LL o por tablas.
Veamos un ejemplo:
Mtodo descendente
Siempre se expande el no terminal
ms a la izquierda, por convenio.
{2 3 4 6 5 1 2 4 6 4 6
26
Mtodo descendente
64642641532
Gramtica ambigua
1. E E + E [id + id * id]
2. E E * E
3. E id
Anlisis ascendente
id + id * id 3 E + id * id 3 E + E * id E +E*E E + E1 E
pivote
Sera equivalente:
3 2 1 3 2
id + id * id E + id * id E + E * id E * id E*E E
Una gramtica ambigua es una gramtica para la cual existe ms de un rbol que la genere. No
nos interesan las gramticas ambiguas ya que queremos que el compilador siempre funcione
de la misma manera.
ET/E+T
TF/T*F
F (E) / id
27
Anlisis ascendente por reduccin/desplazamiento: LR
Existen varios tipos de LR (SLR, LR cannico, LALR), nosotros vamos a utilizar el SLR. Este
mtodo es suficientemente general como para reconocer cualquier construccin que existe
hoy en da en los lenguajes de programacin. Detecta los errores lo antes posible.
Buffer del analizador lxico. Con
tokens.
Si = estado
xi N U T
Tabla de decisin.
Tabla de decisin
Accin [ Estado x token ]
Accin ( Sj , ai ) = Reducir A
Desplazar y transitar al estado Sk
Error (Cdigo error).
Aceptar.
Reducir
( S0, x1, , xm,Sm; a1, , an$) (S0, x1, , xm-r, Sm-r, A, S; a1, , an$)
Xm-r+1,, Xm = A B
S GOTO (Sm-r, A)
Desplazar
Significa pedirle un token al lxico y meterlo en la pila.
( S0, x1, , xm,Sm, ai, Sk; ai, , an$) Sk se introduce puesto que nunca puede haber un
token en la cima de la pila.
28
Tabla de decisin
ACCIN GOTO
estado id + * ( ) $ E T F
S0 D5 D4 1 2 3
S1 D6 ACEPTAR
S2 R2 D7 R2 R2
S3 R4 R4 R4 R4
S4 D5 D4 8 2 3
S5 R6 R6 R6 R6
S6 D5 D4 9 3
S7 D5 D4 10
S8 D6 D11
S9 R1 D7 R1 R1
S10 R3 R3 R3 R3
S11 R5 R5 R5 R5
D = desplazar R = reducir
Prefijo viable
Son todos los prefijos de una forma sentencial que no van ms all del El pivote es la subcadena que vamos
pivote. a tomar para reducir y que forma
parte del camino correcto.
Dada la cadena:
a
aB
aBc
aBcd
29
La base de la construccin de las tablas de decisin LR es encontrar todos los prefijos viables
de cualquier subcadena del lenguaje. Para ello utilizaremos un autmata reconocedor de
prefijos viables.
tem
Tambin llamado elemento.
EE+T
ET
F id
Si yo quiero aplicar la regla que me indica el tem necesito encontrar todos los elementos a la
derecha del punto, es decir:
Funcin cierre
Dado una G, I = conjunto de tems vlido.
Ejemplo
Siguiendo la gramtica habitual:
I = {E E + T}
El cierre de un estado son todas las posibilidades del lenguaje que se pueden aplicar desde una
determinada regla.
Funcin Goto
Goto (I, x) xNUT
Goto (I, x) = Cierre del conjunto formado por todos los tems de la forma: A x tales que
A x I
Ejemplo
I = { E E + T, E T}
30
Gramtica aumentada
G(N, T, P, S) Gramtica aumentada G(N U {S}, T, P U {S S}, S)
Es un formulismo que utilizamos al crear un LR. Esta gramtica aumentada nos asegura que
hemos llegado al final cuando usamos la reduccin por la regla E E
Coleccin cannica
Conjunto de tem inicial I0=Cierre{S S}
Ejemplo
I0 = Cierre {E E} = {EE, E E + T, E T, T T * F, T F, F (E), F id}
CC={I0} j = 1
CC = { I0, I1, I2, I3, I4, I5,} y continuara, con esto solo terminamos el bucle en el estado I0
habra que hacer nuevos bucles para cada nuevo estado.
31
Ejercicio
Crear un autmata reconocedor de prefijos viables.
A BC
B dB / b
C dB / C / dC
First
First () = { T / * a} Si * , First()
32
Ejemplo
Dada la gramtica habitual:
First(C) = {+, }
Follow
Conjunto de smbolos terminales que pueden ir a continuacin del no terminal en alguna
frmula vlida del lenguaje:
33
Aplicando estas tres reglas podemos calcular el follow de cualquier no terminal. Solo funciona
con no terminales. En este caso siempre se buscan las reglas donde el smbolo N aparezca a la
derecha de la regla.
Ejemplo
Dada la gramtica de la pgina 33:
Follow (E) = {$, +, )} Si a la derecha del no terminal aparece un terminal este se aade
directamente. $ se aade por ser axioma siempre.
Follow (T) = {$, +, ), *} Se aade el Follow(E) ya que T puede no tener nada a su derecha y
entonces se aade al Follow(T) el Follow del padre.
Tabla de ACCIN
El estado Si se obtiene de Ii teniendo en cuenta que:
Si A Ii Accin(i, a) = reducir (A )
a Follow(A)
34
Tablas de GOTO
Goto(Ii, A) = Ij GOTO(i, A) = j
S S Estado inicial I0
Ejemplo
Usando el autmata de prefijos viables de la pgina 32.
ACCIN GOTO
estado id + * ( ) $ E T F
S0 D5 D4 1 2 3
S1 D6 ACEPTAR
S2 R2 D7 R2 R2
S3 R4 R4 R4 R4
S4 D5 D4 8 2 3
S5 R6 R6 R6 R6
S6 D5 D4 9 3
S7 D5 D4 10
S8 D6 D11
S9 R1 D7 R1 R1
S10 R3 R3 R3 R3
S11 R5 R5 R5 R5
Para cada estado uno por uno vamos utilizando las reglas anteriormente descritas sobre el
autmata. Cada transicin en el autmata de un estado a otro es un desplazamiento.
35
Cuando encontramos un tem con punto al final reducimos por la regla donde est ese tem en
los Follow del smbolo a la izquierda de la regla. El nmero junto a r indica el nmero de regla.
Ejercicio de examen
Dada la gramtica:
Ejercicio
S SA / b Construir autmata y tabla de decisin.
A Aa / Ab / B
B dBe / e
36
Conflictos LR
Reduccin/Desplazamiento
Accin[Ii, a] = desplazar e ir Ij
Accin[Ii, Follow(B)] = Reducir B
Reduccin/Reduccin
Si decimos que:
Puede parecer correcto, pero NO, con esta condicin solo vemos si
existen conflictos de tres posibilidades, pero no si hay de dos (que
es lo ms comn). Para ello habra que desgranar esa condicin en
tres:
{a} Follow(A)
{a} Follow(B) No hay conflictos
Follow(A) Follow(B)
Se recomienda encontrar los conflictos antes de hacer la tabla de decisin, para ahorrar
trabajo y coste, y verificar las condiciones tras el autmata de prefijos viables.
37
Ejercicio de examen
Dada la siguiente gramtica:
Susceptibles de problemas
I0 Red/desp I3 Red/Desp I6 Red/Desp En el anlisis LR no existen conflictos
de desplazamiento/desplazamiento.
I2 Red/desp I4 Red/Desp I7 Red/Desp
38
Anlisis sintctico descendente
Condicin necesaria
Para que una gramtica pueda analizarse por mtodo descendente es necesario que no
presente recursividad por la izquierda (explicado en la pgina 6) y que est factorizada por la
izquierda.
S AB
A aC / aD Dos producciones empiezan por a NO est factorizada.
Si factorizamos:
S AB
A aA Similar al concepto de sacar factor comn.
A C / D
Ejemplo
E E+T / T Primero eliminamos recursividad por la izquierda:
T T*F / F E TE
F (E)/id E +TE /
T FT
T *FT /
F (E) / id Sin problemas de factorizacin.
39
Programa Analizador sintctico descendente PR
leer siguiente token (a);
E;
End;
Proc E;
T;
E;
End;
Proc E;
If a = First(+TE) then
Begin
leer siguiente token(a);
T;
E;
End;
Else ; //Aplicacin de E
End;
//El procedimiento T sera similar con a=*
Proc F;
If a = ( then
leer siguiente token(a);
E;
leer siguiente token(a);
if a = ) leer siguiente token(a);
Else ERROR;
End;
Else if a=id then leer siguiente token(a);
Else ERROR;
End;
End;
pila trabajo
Acciones
Si CimaPila = siguiente token = $ Fin con xito.
40
Si CimaPila N Consultar M[CimaPila, siguiente token] =
CimaPila XYZ Sustituir CimaPila
por derecha de la regla.
Si t First() M(A, t) = A (t T)
Si First() M(A, t) = A t Follow(A)
Ejemplo
First (E) = {(, id} Follow (E) = {), $} E TE
First (E) = {+, } Follow (E) = {), $} First (TE) = {(,id}
First (T) = {(, id} Follow (T) = {+, ), $} Se hace el First de cada produccin de
First (T) = {*, } Follow (T) = {+, ), $} las reglas y esta regla se sita en la
First (F) = {(, id} Follow (F) = {*, +, ), $} table bajo el smbolo que sea su First.
+ * ( ) Id $
E E TE E TE
E E +TE E E
T T FT T FT
T T T *FT T T
F F (E) F id
Ejercicio
F (id A) Crear el analizador sintctico LL.
APOR
O P O / null
R rest O /
P (id O)
Condicin LL
Si A 1, A 2 G => First(1) First(2) = Es decir, que no tengan nada en
comn.
Si A 1, A 2 G y First(1) => Follow(A) First(2) =
Pertenece a una de las reglas.
Si existen n producciones de A debe examinarse la condicin con todas las parejas de
producciones posibles.
41
Si First(1)(o a una de ellas, solo una) debera examinarse:
Ejemplo
F (id A) First (F) = { ( } Follow(F) = { $ }
A POR First(A) = { ( } Follow(A) = { ) }
O PO / null First(P) = { ( } Follow(O) = { ), rest }
R rest O / First(O) = { ( , null } Follow(R) = { ) }
P (id O) First(R) = { rest, } Follow(P) = { (, null }
First(PO) First(null) = ?
{ ( } {null} = La O no da problemas.
First(rest O) First() = ?
{ rest } {} = La primera condicin es correcta pero First() = as que debemos
examinar la segunda condicin.
First(rest O) Follow(R) = ?
{ rest } { ) } = La R no da problemas
y al examinar la condicin:
First(PO) First(null) = ?
{ (, null} {null}
Ejemplo de examen
BLOQUE ( block SENT REST-BLOCK )
REST-BLOCK SENT REST-BLOCK / return /
SENT SENT-ASIG / EXPRESION / SENT-CONTROL
First(SENT-ASIG) = First(EXPRESION) = { id }
SENT-ASIG * id op-asig id
EXPRESION * id op-arit id
First(SENT-CONTROL) = { If, while, for }
42
( ) block return id if while for $
BLOQUE BLOQUE (
En (SENT, id) hay dos reglas en la misma casilla, por tanto, esta gramtica no cumple la
condicin LL y por ello no permitira el anlisis LL.
First(BLOQUE) = { ( }
First(REST-BLOCK) = { return, , id, if, while, for }
First(SENT) = { id, if, while, for }
Follow(BLOQUE) = { $ }
Follow(REST-BLOCK) = { ) }
Follow(SENT) = { return, id, if, while, for }
Ejercicio
S procedure division . [DECLARACIONES] {CUERPO}
DECLARACIONES declaratives . {STRUCT use PARRAFO} end declaratives
CUERPO id section . {PARRAFO}
STRUCT number . SENTENCE
SENTENCE goto id / evaluate id
Esta gramtica est en formato extendido, donde lo que est entre [](corchetes) significa que puede
aparecer 1 o ninguna vez y lo que est entre {}(llaves) 0 n veces. Las palabras en maysculas son No
Terminales y en minscula Terminales.
Se trata de hacer el algoritmo predictivo-recursivo para esta gramtica.
43
Anlisis sintctico descendente por tablas
Dada la gramtica de la pgina 42 y la palabra:
( id ( id null ) null )
La produccin de cada regla se coloca en orden inverso en la pila { (id A) )A id( } para que en
la cabeza de la pila (que crece hacia la derecha) est el primer smbolo de la produccin.
Si el smbolo de la pila coincide con el token dado, vamos por el buen camino, el anlisis est
siendo correcto. Si al contrario no coinciden, es un error de la cadena.
44
Else if (sgte_token == id) Then
BEGIN //Aqu habra un conflicto
porque pueden ser dos reglas.
Comprobar_token(id);
If(sgte_token == op-asig) Then
BEGIN
Comprobar_token(op_asig);
Comprobar_token(id);
END
Else
BEGIN
Comprobar_token(op_arit);
Comprobar_token(id);
END
END
END
Procedure REST-BLOCK;
BEGIN
If(sgte_token {id, if, while, for) Then
BEGIN
SENT;
REST-BLOCK;
END
Else if (sgte_token == result) Then
Comprobar_token(return);
Else //if sgte_token Follow(REST-BLOCK)
END
Una solucin para eliminar el conflicto sera cambiar la gramtica por una equivalente:
Anlisis semntico
En el anlisis semntico se utilizar una gramtica de contexto libre (tipo 2) pero con un
aadido denominado gramtica de atributos. Estos atributos que aadiremos a los no
terminales nos darn informacin sobre su contenido semntico.
45
Traduccin dirigida por la sintaxis
Se presenta con dos notaciones diferentes:
Definicin dirigida por la sintaxis (DDS) Notacin de alto nivel con menos detalles.
Esquema de traduccin (EDT) Notacin de bajo nivel con ms detalles.
Lo que estamos trabajando es el diseo del analizador semntico, lo que quiere decir que si
trabajamos con DDS nos tendremos que preocupar de menos cosas pero ser cosas que
tendremos que definir ms tarde.
Todo lo contrario es trabajar con EDT, durante el diseo da ms trabajo pues te obliga a
trabajar con ms detalles pero allana el camino para ms tarde.
Atributos
Se aplican sobre los no terminales:
Ejemplo
Dada la frase: rbol sintctico: Hasta ahora solo nos fijbamos en si la estructura es
correcta, ahora debemos definir que el tipo es
int edad;
entero(int).
con la gramtica:
Tenemos que unir de alguna manera el tipo ese id, la
D Tipo id; nica manera es con un atributo que recorra las
Tipo int/float reglas.
46
Vemoslo con un ejemplo:
Nos faltara saber muchas cosas an, la primera de ellas: Qu orden seguimos? En qu
momento se hace cada cosa difiere mucho segn se utilice DDS o EDT.
47
La idea que se persigue es que, cuando llegue el momento de expandir un nodo ya tenemos
toda la informacin relevante sobre l.
Como consecuencia, deben cumplirse las siguientes condiciones cuando hay atributos
sintetizados y heredados:
Un atributo
heredado para un
smbolo del lado
derecho de la
regla debe
calcularse antes
de que se trate
dicho smbolo.
Un atributo
sintetizado para el
no terminal de la
izquierda slo
puede calcularse
una vez tratados
todos sus hijos.
Formas de representacin
DTL; L.tipo = T.tipo
T int T.tipo = int
T float T.tipo = float
L L1, id L1.tipo = L.tipo; Aade tipo TS(id.PosTS, L.tipo)
L id Aade tipoTS (id.PosTS, L.tipo)
D T{ L.tipo = T.tipo} L ;
T int {T.tipo = int}
T float {T.tipo = float}
L { L1.tipo = L.tipo } L1, id {Aade tipo TS(id.PosTS, L.tipo)}
L id {Aade tipoTS (id.PosTS, L.tipo)}
48
Aunque en este caso nos hemos permitido hacer un anlisis descendente aunque no sera del
todo posible si la frase fuese ms larga.
Comprobaciones semnticas
Sistemas de tipos
Orientado a la comprobacin de tipos. No es ms que un conjunto de reglas cuyo propsito es
asignar una expresin de tipo a las distintas estructuras del texto fuente, en el caso que nos
ocupa a las estructuras del lenguaje de programacin.
El comprobador de tipos (subconjunto muy grande del analizador semntico, incluso podemos
generalizar que es el analizador por completo) es la implementacin de sistemas de tipos.
Expresin de tipos
Denota el tipo de una construccin del texto fuente. Existen dos tipos.
Tipos bsicos
Todos aquellos tipos definidos dentro del propio lenguaje. Aunque existen tres tipos bsicos
especiales:
Tipo_OK
Tipo_error
Tipo_vacio
Estos tipos bsicos especiales nos ayudan a conocer la semntica de ciertas sentencias, que no
son identificadores ni datos.
49
Tipos construidos
Se basan en la aplicacin de un constructor a uno o ms tipos bsicos o construidos.
Constructores de tipos
Veamos los casos ms comunes:
Vectores
Si T es expresin de tipo array(I, T) es expresin de tipo (donde I son los ndices).
Ejemplo
char V[10] array(1..10, char) se asigna a V.
Producto cartesiano
Si T1, T2 son expresiones de tipo T1X T2 es expresin de tipo.
Este constructor nace ms como una necesidad del compilador que como expresin del
lenguaje. Luego veremos por qu.
Registro
Si T1,,Tn son expresiones de tipo record (T1xT2xxTn) es expresin de tipo
Ejemplo
Struct R
{ int a; record(int x array(1..5, real)) R
float b[5] 0..4 esto dependen del lenguaje.
}
Punteros
Si T es expresin de tipo pointer(T) es expresin de tipo.
Funciones
int ejemplo (float, char) float x char --> int es expresin de tipo que se asigna a ejemplo.
Ejemplo
PD;S Declaracin ; sentencias
D D1 ; D2 / id:T construidos
bsicos puntero array
T char / integer / boolean / T1 / array[num] of T1
asig if-then
S S1 ; S2 / id:=E / if E then S1 Sentencias
E car / num / true / false / id / E1 mod E2 / E1[E2] / E1 / E1 and E2 / E1 op.rel E2 operaciones
modulo puntero lgica general
Recordemos que los subndices sirven para diferenciar los no terminales con mismo nombre
en una regla.
Comprobacin de tipos
D id:T {aade tipo (id.entrada, T.tipo)}
50
T boolean {T.tipo = boolean}
S S1 ; S2 {S.tipo := (If S1.tipo = tipo_OK and S2.tipo = tipo_OK then tipo_OK Else
tipo_error)}
S If E then S1 {S.tipo := (If E.tipo = Boolean and S1.tipo = tipo_OK Then tipo_OK Else
tipo_error)}
E id {E.tipo = buscaTipoTS(id.entrada)}
E E1 mod E2 {E.tipo := (If E1.tipo = integer and E2.tipo = integer Then integer Else
tipo_error)}
E E1[E2] {E.tipo := (If E2.tipo = integer and E1.tipo = array(i,t) Then t Else tipo_error)}
(Este es un caso muy sencillo, en un caso real habra que hacer ms
operaciones)
E E1 and E2 {E.tipo := (If E1.tipo = boolean and E2.tipo = boolean Then boolean Else
tipo_error)}
E E1 op.rel E2 {E.tipo := (If E1.tipo = integer and E2.tipo = integer Then boolean Else
tipo_error)}
E E1 + E2 {E.tipo := (If E1.tipo = integer and E2.tipo = integer Then integer Else
tipo_error)}
Si existe int/float
51
Este es un ejemplo con un lenguaje sin conversin automtico de tipos.
Ejercicio
C : char;
i : integer;
i : c mod i mod 3
Entonces:
52
P { PilaTS := nuevaPila()
PilaDesp := nuevaPila()
push (PilaTS, crearTS())
push (PilaDesp, 0) } P
P DP /SP / (No vamos a colocar ninguna accin en este punto, aunque podramos verificar
que no se comenten errores y cosas as).
53
Paso de parmetros por referencia. No existen funciones
Ejercicio resuelto anidadas. El analizador lxico no interacta con TS.
P P
P DP / FP / SP / Al no haber anidamiento no hacen falta una tabla de smbolos.
D T id; Nos servir tener:
F Function id (L) : T ; begin B end
L T : id / L, L Una TSG (General) que se crea al principio y siempre esta
T integer / real disponible.
B DB / SB /
Una TSL (Local) que se crea al comenzar una funcin y se
S id := E / return E;
E id(A) / id destruye al terminar.
A E / A, A
Para comprobar si las declaraciones son locales a generales comprobaremos si hay un TSL
activa.
D ~ TSG
.
. Variables generales.
.
Fun ~ CreaTSL
.
. Variables, locales, puesto que TSL est activa.
.
End ~ TSL
.
. Variables generales.
.
End ~ TSG
EDT
P { TSG := CrearTS ; DespG:= 0 } P { Destruir(TSG) }
P DP / FP / X
54
begin B end { If B.tipoDev T.tipo
Then Error(El tipo devuelto no es correcto)
destruye(TSL); TSL = null; TS := TSG}
Notas
L T : id { If buscaTS(TSL, id.lex) null
Then Error(Parmetro ya declarado) 1.- Utilizamos una funcin distinta
Else id.ent := insertaTS(TSL, id.lex) porque normalmente hay que
insertaTipoParametro(TSL, id.ent, T.tipo)1 hacer cosas distintas.
insertarDespl(TSL, id.ent, desplL)
desplL := desplL + 22 2.- Al ser paso de parmetros por
L.tipo := T.tipo } referencia el desplazamiento es
simplemente guardar los bytes
L L1 , L2 { L.tipo := L1.tipo x L2.tipo }
correspondientes a la direccin de
T integer / real (Igual que en el ejercicio anterior) memoria, 2 en este caso.
B { B.tipoDev := vacio }
55
Ejercicio
P DS
DT:L/D;D
T integer / real / boolean / array
L id / id [numEntero] of T / L ; L
S for id := E to E do S / Repeat S until C / id := E / S ; S
E E + E / E x E / id / numEntero / true / false / id[E]
Apuntes de procesadores del lenguaje by Pau Arlandis Martnez is licensed under a Creative Commons
Reconocimiento 3.0 Unported License.
56