Sunteți pe pagina 1din 78

LENGUAJES Y COMPILADORES

Analisis Sintactico Descendente

Profesor: Carlos A. Ruiz De La Cruz Melo


Correo: zorroculto69@hotmail.com
INTRODUCCION
El parser, o analizador sintctico, obtiene
una cadena de tokens del analizador
lexicogrfico(scanner) y verifica que esta
secuencia pueda ser generada por la gramtica
del lenguaje fuente

PROGRAMA FUENTE

ANALIZADOR
LEXICO
Dame el siguiente
siguiente
token
token
ANALIZADOR
SINTACTICO
INTRODUCCION
La sintaxis suele especificarse a traves de una G.L.C.

Se genera lgicamente un rbol de anlisis (parse


tree). Fsicamente en la prctica nunca se construyen
porque ocuparan mucho espacio, en su lugar se usan
como alternativa, pilas.

El parser avisar de los errores de una forma


inteligible y capaz de recuperarse de aquellos errores
para continuar procesando el resto de la entrada
METODOS A UTILIZAR

Mtodos de anlisis universales

CocKe-Younger-Kasami
Earley
Mtodos ascendentes(botton-up) y descendentes
(top-down)
BOTTON-UP Y TOP-DOWN

Los analizadores top-down


construyen el rbol de anlisis
sintctico desde el smbolo inicial
hasta describir la frase a reconocer,
mientras que los botton-up
comienzan por la frase a reconocer
subiendo hasta el smbolo inicial

En ambos casos la cadena de


entrada se analiza de izquierda a
derecha.
BOTTON-UP Y TOP-DOWN

Para una G=( Vn, Vt, P, S )

S
Anlisis Anlisis
Descendente Ascendente
SVn , w Vt*
(Top-down) (Botton-up)

w
CONDICIONES PARA UN TOP-DOWN
Las producciones de la G.L.C deben cumplir los
siguientes requisitos:

1. No debe existir recursividad por la


izquierda

2. Conocer el conjunto PRIMERO (First) de


cada Vn
CONDICION PARA UN CONJUNTO
FIRST
Para producciones de la forma

A 1 /2 /. /n

A Vn , i ( Vn Vt )*

Escoger la produccin correcta


requiere que todos los smbolos
iniciales de los i sean diferentes, si
son diferentes es lo que se conoce
como conjunto PRIMERO o First.
ANALISIS TOP-DOWN
Ejemplo 1
G=( Vn , Vt, P, S)
Vn={ S, I, C} Vt = { while, if, else, do, {, }, ; }
P={ S do { I }while C;
S while C { I }
S if C { I} else { I }
:
}
Observacin

PRIMERO (S)= { do, while, if }


Al reconocer una frase

do{ a=0; }while(k>2);


TIPOS DE TOP-DOWN

Existen los mtodos siguientes:

Anlisis Descendente Recursivo (ADR)


Anlisis Descendente Predictivo, no
recursivo (ADP)
ADR
A cada Vn se le asocia un procedimiento

Los procedimientos procesan la entrada.

La llamada recursiva de los procedimientos


genera el rbol de anlisis sintctico.

Tambin se cuenta con procedimientos auxiliares


para tratamiento de error y representacin del
scanner.
ADR
Ejemplo 2

G=( Vn, Vt, P, S )


Vn = { S, A1, A2 }

Da lugar a los siguientes procedimientos:

Procedimiento S
Procedimiento A1
Procedimiento A2
Procedimiento ERROR Procedimientos
Procedimiento Lxico adicionales
ADR
Un procedimiento opera del siguiente modo

Usa la produccin A con AVn, (Vn Vt)* si el


smbolo de entrada que se esta examinando pertenece
a PRIMERO(A)
El procedimiento implementa el lado derecho de la
produccin:

Un Vn da lugar a que se invoque un procedimiento


Un Vt que se lee y esta de acuerdo con la
gramtica provoca la lectura del siguiente
smbolo.
ADR
Ejemplo 3
Se generar el ADR a partir de la
siguiente gramtica

G=(Vn, Vt, P, E )
Vn={ E, T, F } Vt = { id, *, +, (, ) }
P= {
E E+T / T
T T*F / F
F ( E ) / id A A , ( Vn Vt ) * , A V
}
A A A , A Vn
A A | a , ( Vn Vt )
ADR
Se buscar primero eliminar la recursividad
G=(Vn, Vt, P, E )
Vn={ E, T, F } Vt = { id, *, +, (, ) }
P= {
E TR A A , ( Vn Vt ) * , A V
R +TR /
T FG A A A , A Vn
G *FG / A A | a , ( Vn Vt )
F ( E ) / id
}
ADR
Tenemos tres procedimientos adicionales

Uno para el lxico llamado lxico


Otro para avisar de errores llamado error
Y para verificar el patrn especificado por la
gramtica denominado igual
ADR
E TR
Procedimiento E( )
T()
R() R +TR /
finE

ProcedimientoR()
si( e = +) entonces T FG
igual(+)
Procedimiento F()
T()
R()
G *FG / case e
finsi ( :igual(()
finR E()
F ( E ) / id igual())
ProcedimientoT( ) id :igual(id)
F() otro
G()
error()
finT ProcedimientoG()
si( e = * ) entonces fin-case
igual(*) finF
F()
G()
finsi
finG
ANALISIS DE UNA
SECUENCIA CON ADR
El final de cadena se
indica por un carcter $

Secuencia a ser
id * id $ analizada

Programa principal
que llama al
Programa principal
analizador lxico y
eLexico() luego al analizador
E() sintctico (E)
finprincipal

id * id $

Primer smbolo a ser


procesado
ADR
Procedimiento E() ProcedimientoG() ProcedimientoIgual(t)
T() si( e = * ) si e = t
R() igual(*) e lexico()
finE F() sino
G() error()
Fin Igual
finsi
finG
ProcedimientoR()
si( e = +)
igual(+)
T() Procedimiento F()
R() case e
finsi ( :igual(()
finR E()
igual())
id :igual(id)

ProcedimientoT()
otro
error()
id * id $
F() fin-case
G() finF
finT
ADR
Procedimiento E() ProcedimientoG() ProcedimientoIgual(t)
T() si( e = * ) si e = t
R() igual(*) e lexico()
finE F() sino
G() error()
Fin Igual
finsi
finG
ProcedimientoR()
si( e = +)
igual(+)
T()
Procedimiento F()
R()
finsi case e
finR ( :igual(()
E()
igual())

ProcedimientoT()
id :igual(id)
otro
id * id $
F() error()
G() fin-case
finT finF
ADR
Procedimiento E() ProcedimientoG() ProcedimientoIgual(t)
T() si( e = * ) si e = t
R() igual(*) e lexico()
finE F() sino
G() error()
Fin Igual
finsi
finG
ProcedimientoR()
si( e = +)
igual(+)
T()
Procedimiento F()
R()
finsi case e
finR ( :igual(()
E()
igual())

ProcedimientoT()
id :igual(id)
otro
id * id $
F() error()
G() fin-case
finT finF
ADR
Procedimiento E() ProcedimientoG() ProcedimientoIgual(t)
T() si( e = * ) si e = t
R() igual(*) e lexico()
finE F() sino
G() error()
Fin Igual
finsi
finG
ProcedimientoR()
si( e = +)
igual(+)
T()
Procedimiento F()
R()
finsi case e
finR ( :igual(()
E()
igual())

ProcedimientoT()
id :igual(id)
otro
id * id $
F() error()
G() fin-case
finT finF
ADR
Procedimiento E() ProcedimientoG() ProcedimientoIgual(t)
T() si( e = * ) si e = t
R() igual(*) e lexico()
finE F() sino
G() error()
Fin Igual
finsi
finG
ProcedimientoR()
si( e = +)
igual(+)
T()
Procedimiento F()
R()
finsi case e
finR ( :igual(()
E()
igual())

ProcedimientoT()
id :igual(id)
otro
id * id $
F() error()
G() fin-case
finT finF
ADR
Procedimiento E() ProcedimientoG() ProcedimientoIgual(t)
T() si( e = * ) si e = t
R() igual(*) e lexico()
finE F() sino
G() error()
Fin Igual
finsi
finG
ProcedimientoR()
si( e = +)
igual(+)
T()
Procedimiento F()
R()
finsi case e
finR ( :igual(()
E()
igual())

ProcedimientoT()
id :igual(id)
otro
id * id $
F() error()
G() fin-case
finT finF
ADR
Procedimiento E() ProcedimientoG() ProcedimientoIgual(t)
T() si( e = * ) si e = t
R() igual(*) e lexico()
finE F() sino
G() error()
Fin Igual
finsi
finG
ProcedimientoR()
si( e = +)
igual(+)
T()
Procedimiento F()
R()
finsi case e
finR ( :igual(()
E()
igual())

ProcedimientoT()
id :igual(id)
otro
id * id $
F() error()
G() fin-case
finT finF
ADR
Procedimiento E() ProcedimientoG() ProcedimientoIgual(t)
T() si( e = * ) si e = t
R() igual(*) e lexico()
finE F() sino
G() error()
Fin Igual
finsi
finG
ProcedimientoR()
si( e = +)
igual(+)
T()
Procedimiento F()
R()
finsi case e
finR ( :igual(()
E()
igual())

ProcedimientoT()
id :igual(id)
otro
id * id $
F() error()
G() fin-case
finT finF
ADR
Procedimiento E() ProcedimientoG() ProcedimientoIgual(t)
T() si( e = * ) si e = t
R() igual(*) e lexico()
finE F() sino
G() error()
Fin Igual
finsi
finG
ProcedimientoR()
si( e = +)
igual(+)
T()
Procedimiento F()
R()
finsi case e
finR ( :igual(()
E()
igual())

ProcedimientoT()
id :igual(id)
otro
id * id $
F() error()
G() fin-case
finT finF
ADR
Procedimiento E() ProcedimientoG() ProcedimientoIgual(t)
T() si( e = * ) si e = t
R() igual(*) e lexico()
finE F() sino
G() error()
finsi Fin Igual
finG
ProcedimientoR()
si( e = +)
igual(+)
T()
Procedimiento F()
R()
finsi case e
finR ( :igual(()
E()
igual())

ProcedimientoT()
id :igual(id)
otro
id * id $
F() error()
G() fin-case
finT finF
ADR
Procedimiento E() ProcedimientoG() ProcedimientoIgual(t)
T() si( e = * ) si e = t
R() igual(*) e lexico()
finE F() sino
G() error()
finsi Fin Igual
finG
ProcedimientoR()
si( e = +)
igual(+)
T()
Procedimiento F()
R()
finsi case e
finR ( :igual(()
E()
igual())

ProcedimientoT()
id :igual(id)
otro
id * id $
F() error()
G() fin-case
finT finF
ADR
Procedimiento E() ProcedimientoG() ProcedimientoIgual(t)
T() si( e = * ) si e = t
R() igual(*) e lexico()
finE F() sino
G() error()
finsi Fin Igual
finG
ProcedimientoR()
si( e = +)
igual(+)
T()
Procedimiento F()
R()
finsi case e
finR ( :igual(()
E()
igual())

ProcedimientoT()
id :igual(id)
otro
id * id $
F() error()
G() fin-case
finT finF
ADR
Procedimiento E() ProcedimientoG() ProcedimientoIgual(t)
T() si( e = * ) si e = t
R() igual(*) e lexico()
finE F() sino
G() error()
finsi Fin Igual
finG
ProcedimientoR()
si( e = +)
igual(+)
T()
Procedimiento F()
R()
finsi case e
finR ( :igual(()
E()
igual())

ProcedimientoT()
id :igual(id)
otro
id * id $
F() error()
G() fin-case
finT finF
ADR
Procedimiento E() ProcedimientoG() ProcedimientoIgual(t)
T() si( e = * ) si e = t
R() igual(*) e lexico()
finE F() sino
G() error()
Fin Igual
finsi
finG
ProcedimientoR()
si( e = +)
igual(+)
T()
Procedimiento F()
R()
finsi case e
finR ( :igual(()
E()
igual())

ProcedimientoT()
id :igual(id)
otro
id * id $
F() error()
G() fin-case
finT finF
ADR
Procedimiento E() ProcedimientoG() ProcedimientoIgual(t)
T() si( e = * ) si e = t
R() igual(*) e lexico()
finE F() sino
G() error()
Fin Igual
finsi
finG
ProcedimientoR()
si( e = +)
igual(+)
T()
Procedimiento F()
R()
finsi case e
finR ( :igual(()
E()
igual())

ProcedimientoT()
id :igual(id)
otro
id * id $
F() error()
G() fin-case
finT finF
ADR
Procedimiento E() ProcedimientoG() ProcedimientoIgual(t)
T() si( e = * ) si e = t
R() igual(*) e lexico()
finE F() sino
G() error()
Fin Igual
finsi
finG
ProcedimientoR()
si( e = +)
igual(+)
T()
Procedimiento F()
R()
finsi case e
finR ( :igual(()
E()
igual())

ProcedimientoT()
id :igual(id)
otro
id * id $
F() error()
G() fin-case
finT finF
ADR
Procedimiento E() ProcedimientoG() ProcedimientoIgual(t)
T() si( e = * ) si e = t
R() igual(*) e lexico()
finE F() sino
G() error()
Fin Igual
finsi
finG
ProcedimientoR()
si( e = +)
igual(+)
T()
Procedimiento F()
R()
finsi case e
finR ( :igual(()
E()
igual())

ProcedimientoT()
id :igual(id)
otro
id * id $
F() error()
G() fin-case
finT finF
ADR ProcedimientoG()
si( e = * )
ProcedimientoIgual(t)
si e = t
igual(*) e lexico()
Procedimiento E() F() sino
T() G() error()
R() finsi Fin Igual
finE finG

ProcedimientoR()
si( e = +) Programa principal
igual(+)
eLexico()
T()
R() E()
finsi Procedimiento F() finprincipal
finR case e
( :igual(()
E()

ProcedimientoT()
igual())
id :igual(id)
id * id $
F()
otro
G()
error()
finT
fin-case
finF
TERMINO EL
RECONOCIMIENTO
IMPLEMENTACION DEL ADR
#define cmp strcmp // reemplaza la funcin COMPARA
#define esn isdigit // reemplaza la funcin ES DGITO
#define esl isalpha // reemplaza la funcin ES LETRA
class AS{
char cad[100];
int p;
char *lex;
public:
// mtodos que implican los Vn de la gramtica G
void E(); void T(); void R(); void G(); void F();
void I(char *); // verifica el patrn de la gramtica G
char *L(); // implementa el analizador lxico
void leer(); // captura una frase del lenguaje
void W(); // avisa de algun error
AS(){ p=0;} // puntero a cada smbolo de la frase
};
SCANNER DEL ADR
char *AS::L(){ // analizador lxico
char *t; int k=0,s=0;
t = new char[20];
for(int i=p; i<strlen(cad); i++)
if(cad[i]!=' '){ // caracter blanco formar un nuevo lexema
if( p==i && esl(cad[i])) s=1; // si es identificador
if(s){
if(esl(cad[i]) || esn(cad[i])); // si es letra o dgito
else return "sos"; // si no es lexema conocido
}
t[k]=cad[i];
k++;
}
else { p=i+1; break; } // apunta al prximo componente lxico
t[k]='\0';
if(s) return "id"; // retorna un identificador
else return t; // retorna otro tipo de lexema
}
METODOS DEL ADR
void AS::leer(){
cout<<"\n leer cadena: ";gets(cad);
lex=L(); Es el programa
E(); leido en una
}
cadena

void AS::I(char *m){ //igual


if(!cmp(m,lex)) lex=L(); Verifica el
else W(); patrn
}
especificado por
la gramtica

void AS::W(){
cout<<"\n error";
getch(); exit(0); }
Avisa de algun
error
METODOS DEL ADR
void AS::E(){ T(); R(); }

E TR

void AS::R(){
if (!cmp(lex,"+")){
I("+");
T(); R+TR /
R();
}
}

void AS::T(){ F(); G(); }


T FG
METODOS DEL ADR
void AS::G(){
if( !cmp(lex,"*")){

G *FG /
I("*");
F();
G();
}
}

void AS::F(){
if(!cmp("(",lex)){ I("("); E(); I(")");
}
else if (!cmp(lex,"id")) I("id"); F ( E ) / id
else W();
}
main() {
AS p;
p.leer();
cout<<"\n perfecto";
getch();
}
DETALLE DE UN ADR
1. Para producciones de la forma A 1 / 2 / / n

Si entrada PRIMERO(1) entonces


Procedimiento 1
sino Si entrada PRIMERO(2)

sino Si entrada PRIMERO(n) entonces
Procedimiento n
sino
error
finsi
..
finsi
finsi

A 1 / 2 / / n
DETALLE DE UN ADR
2. Para producciones A 1 2 n

Procedimiento 1
Procedimiento 2
..
Procedimiento n
A 1 2 n
3. Para producciones A A /

si entrada PRIMERO()
Procedimiento
Procedimiento A
finsi

AA/
DETALLE DE UN ADR
4. Para producciones A

Procedimiento
A
5. Para producciones A /

A/
si entrada PRIMERO()
Procedimiento
Finsi

6. Para producciones A a, a Vt
si entrada = a
entrada lexico()
sino
error
A a, a Vt
finsi
ANALIZADOR DESCENDENTE
PREDICTIVO (ADP)
Es un analizador sintctico que no es recursivo

Condicin exigible es que a partir del siguiente


token de entrada, sea posible determinar que
regla aplicar lo cual se logra mediante una
tabla.

La recursividad se evita mediante una pila

Un analizador descendente predictivo dirigido


por tabla y que usa pila es el mtodo que se
basa en gramticas LL(k)
ADP
Frase de entrada
i+i* i $
pila
E ANALIZADOR
SALIDA
$ SINTACTICO

TABLA DE ANALISIS
SINTACTICO (TAS)
CONSTRUCCION DE UN ADP

I. Hallar los conjuntos PRIMERO y SIGUIENTE

II. La construccin de la tabla de anlisis


sintctico (TAS) usando la informacin de los
conjuntos PRIMERO y SIGUIENTE
I.HALLAR LOS CONJUNTOS
PRIMERO
PRIMERO() donde (VtVn)*, son los terminales que
pueden comenzar una forma de frase derivable de . Dada
G=(Vn, Vt, P, S), se calcula PRIMERO(X) aplicando las
siguientes reglas:

1. Si XVt PRIMERO(X) es { X}
2. Si X P se adiciona a PRIMERO(X)
3. Si X Vn y XY1 Y2 Yk P colocar aVt en
PRIMERO(X) si, para alguna i , a esta en PRIMERO(Yi ) y
esta en todos los PRIMERO(Y1),, PRIMERO(Yi -1) osea Y1
Yi -1 *
I.HALLAR LOS CONJUNTOS
Ejemplo 4
Encontrar los conjuntos PRIMEROS de los Vn
Dada G=(Vn, Vt, P, S)
TABLA I
Vn ={S, A, B} Vt ={ a,b,c}
P={ SIMBOLO PRIMERO

S ABc S a, b, c

A a / A a,
B b,
B b /
}
I.HALLAR LOS CONJUNTOS
SIGUIENTE

SIGUIENTE(A) para AVn es el conjunto de terminales que pueden


aparecer inmediatamente a la derecha de A.
Dada G=(Vn, Vt, P, S), se calcula SIGUIENTE(A) aplicando las
siguientes reglas:

Colocar $ en SIGUIENTE(S) si S es smbolo inicial y $ es el


delimitador.
De AB, colocar todo PRIMERO() en SIGUIENTE(B)
excepto
De AB o AB donde PRIMERO() colocar todo
de SIGUIENTE(A) en SIGUIENTE(B).
I.HALLAR LOS CONJUNTOS
Ejemplo 5
Encontrar los conjuntos SIGUIENTES de los Vn
Dada G=(Vn, Vt, P, S)
Vn ={S, A, B} Vt ={ a,b,c}
TABLA II
P={ SIMBOLO SIGUIENTE

S ABc S $

A a / A b, c
B c
B b /
}
II. TAS
ALGORITMO

ENTRADA: una gramtica G


SALIDA : tabla de anlisis sintctico M

1. A donde (Vt Vn)* se dan los pasos 2 y 3


2. a PRIMERO(), se adiciona A a M[ A, a]
3. Si PRIMERO(), adicionese A a M[ A, b ], b Vt de
SIGUIENTE(A), si PRIMERO() y $SIGUIENTE(A),
adicionese A a M[ A, $]
TABLA DE ANALISIS SINTACTICO
DEL ADP
SIMBOLO PRIMERO SIGUIENTE
Dada G=(Vn, Vt, P, S) S a, b, c $
Vn ={S, A, B} Vt ={ a,b,c} A a, b, c
P={ B b, c
S ABc
A a /
B b /
} TAS
Vn TABLA DE SIMBOLOS
a b c
S S ABc S ABc S ABc

A A a A A

B B b B
ALGORITMO DE ANALISIS
Sim apunta al primer componente lxico de w$
Repetir
Sea X smbolo de la cima de la pila y a el smbolo apuntado por sim
si X Vt o $
si X = a
sacar X de la pila y avanzar sim
sino error
finsi
sino si M[ X, a] = X Y1 Y2 Yk
sacar X de pila y meter Yk Yk-1 Y1 con Yi en la cima
sino
error
entrada
finsi
A
finsi
X
a. . . . . .$
Hasta X = $

pila : Sim
$
Vn TABLA DE SIMBOLOS
a b c
S S ABc S ABc S ABc RECONOCIMIENTO

A A a A A

B B b B

No PILA ENTRADA SALIDA


1 $S abc$ S ABc
2 $ cBA abc$ A a

TAS 3
4
$ cBa
$ cB
abc$
bc$ B b
5 $ cb bc$
6 $c c$

ANALISIS DEL ADP


7 $ $ SE ACEPTA
ADP
Ejemplo 6
Se generar el ADP a partir de la siguiente gramtica

G=(Vn, Vt, P, E )
Vn={ E, T, F } Vt = { id, *, +, (, ) }
P= {
E E+T / T
T T*F / F
F ( E ) / id
}
ADP
G=(Vn, Vt, P, E )
Vn={ E, T, F } Vt = { id, *, +, (, ) }
P= {
E E+T / T
T T*F / F
F ( E ) / id
}

Se buscar primero eliminar la recursividad


G=(Vn, Vt, P, E )
Vn={ E, T, F } Vt = { id, *, +, (, ) }
P= {
E TR
R +TR /
T FG
G *FG /
F ( E ) / id
}
CONJUNTOS PRIMERO Y SIGUIENTE
DEL ADP
G=(Vn, Vt, P, E )
Vn={ E, T, F } Vt = { id, *, +, (, ) }
P= {
E TR
R +TR /
T FG
G *FG /
F ( E ) / id
} TABLA III
SIMBOLO PRIMERO SIGUIENTE
E ( , id ),$
R +, ),$
T ( , id +, ) , $
G *, +, ) , $
F ( , id *, +, ) , $
TABLA DE ANALISIS SINTACTICO
DEL ADP
SIMBOLO PRIMERO SIGUIENTE
G=(Vn, Vt, P, E )
E ( , id ),$
Vn={ E, T, F } Vt = { id, *, +, (, ) } R +, ),$
P= {
T ( , id +, ) , $
E TR
G *, +, ) , $
R +TR /
T FG F ( , id *, +, ) , $
G *FG /
F ( E ) / id
} TAS
Vn SIMBOLOS DE ENTRADA
id + * ( ) $
E ETR ETR
R R+TR R R
T TFG TFG
G G G*FG G G
F Fid F(E)
Vn SIMBOLOS DE ENTRADA

id + * ( ) $
E ETR ETR

R R+TR R R RECONOCIMIENTO
T TFG TFG
G G G*FG G G
F Fid F(E)

No PILA ENTRADA SALIDA


1 $E id * id $ E TR
2 $ RT id * id $ T FG

TAS 3
4
$ RGF
$ RG id
id * id $
id * id $
F id

5 $ RG * id $ G * FG
6 $ RGF* * id $

ANALISIS DEL ADP


7 $ RGF id $ F id
8 $ RG id id $
9 $ RG $ G
10 $R $ R
11 $ $ SE ACEPTA
GRAMATICAS LL(K)
Una gramtica es LL(k) si la tabla
construida tiene una nica produccin
en la intersecin de una columna(Vt) y
una fila (Vn)

LL(K)
Lectura de los Nmero de smbolos
smbolos de entrada tomados en cada
de izquierda a lectura
derecha

Las derivaciones son por la


izquierda

Los casos en el ejemplo5 y ejemplo6, son


ejemplos de una gramtica LL
CONDICION DE ERROR DE UN ADP
Ejemplos usando la tabla IV
M[R,+] = R+TR es correcto
M[R,*] , si se diera indicara error, as que la
gramtica no sera LL

pila A ...b....
:
: entrada
$ M[A, b] = error
PROPIEDADES DESEABLES EN UN
PARSER

Determinar la accin reconociendo unos pocos


tokens de entrada
Como mximo un k preestablecido
En la prctica suele ser k=1

No necesitar marcha atras (backtracking)

No ocupar mucha memoria


IMPLEMENTACION TAS M
Vn SIMBOLOS DE ENTRADA
import java.io.*;
class TABLA{ id + * ( ) $
String M[][]= new String[6][7]; E ETR ETR
String produccion="";
R R+TR R R
T TFG TFG
G G G*FG G G
F Fid F(E)
TABLA(){ // se inicializa la tabla
for(int i=0; i<6; i++)
for(int j=0; j<7; j++)
M[i][j]=" ";// primero se llena de blancos
M[0][1]="i";M[0][2]="+"; M[0][3]="*";
M[0][4]="("; M[0][5]=")";M[0][6]="$";

M[1][0]="E";M[1][1]="RT";M[1][4]="RT";
M[2][0]="R";M[2][2]="RT+";M[2][5]="&";M[2][6]="&";
M[3][0]="T";M[3][1]="GF"; M[3][4]="GF";
M[4][0]="G";M[4][2]="&";M[4][3]="GF*";M[4][5]="&";M[4][6]="&";
M[5][0]="F";M[5][1]="i";M[5][4]=")E(";
}
IMPLEMENTACION id
PILA
G
boolean Terminal(String car){ R
for(int i=1; i< 7; i++)
if(M[0][i].equals(car)) return true;
return false;
$ fondo
}

String RetProduccion(){ return produccion; } Vn SIMBOLO DE


id
E ETR
boolean ExisteInterseccion(String XX,String ae){
int i,x=0,y=0; R R+TR
for(i=1; i< 7; i++)
if(M[0][i].equals(ae)) x=i;

for(i=1; i< 6; i++)


if(M[i][0].equals(XX)) y=i;
if(x ==0 || y == 0 ) return false;
else if( M[y][x].equals(" ")) return false;
else{ produccion=M[y][x]; return true;}

}
} // FIN DE CLASE TABLA
IMPLEMENTACION
class PARSER{
TABLA t=new TABLA();
String pila[]=new String[100];
String ae; //guarda un simbolo de la cadena de entrada
int i; // indice de la pila
String cad; // guarda la cadena de entrada
int p; // posicion de un simbolo de la cadena de entrada a leer
int pos;
static String leer(String m){
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String cadena="";
System.out.println(m);
try{ cadena=br.readLine(); }
catch(IOException ioe) { }
return cadena;
}

b*(a+ b)
IMPLEMENTACION pos

int RetPos(){ return pos; }

b *( a + b ) $
String Lexico(){ // regresa un lexema
char caracter;
String tira=""; //int k=0;
boolean sw=false;
for(int i=p; i<cad.length(); i++)
if(cad.charAt(i)!=' '){
tira=tira+cad.charAt(i); // se rellena otra cadena
pos=i+1;
break;
}
caracter=tira.charAt(0);
if(Character.isLetter(caracter)) i * ( i + i )
tira="i";
return tira.trim();
}

void lectura(){ // lee la cadena de entrada


cad=leer("LEER CADENA: ");
cad=cad+" $";
sintactico(); // se llama al analizador
}
IMPLEMENTACION pos

void mover(int pos){ p=pos; }


b *( a + b ) $
PARSER(){ pila[0]="$"; pila[1]="E"; i=2; p=0; } E
i=2
$
void Empilar(String produccion){// mete en la pila
String t;
for(int j=0; j<produccion.length(); j++){ T GF
t="";
t=t+produccion.charAt(j);
pila[i]=t; i++; PILA
} T
}
R
void error(){
System.out.println(" error de sintaxis");
$ fondo
System.exit(0);
}
IMPLEMENTACION pos

String RetCad(){
String temp=""; int j,k=0;
b *( a + b ) $
for(j=p; j<cad.length(); j++){
temp=temp+cad.charAt(j); }
return temp;
}

String RetPila(){ a+b)$


String CadPila="";
for(int j=0; j<i; j++) CadPila=CadPila+pila[j];
return CadPila;
}

PILA
T
R $RT
$ fondo
IMPLEMENTACION
void sintactico(){ // analizador sintactico
String XX; String produccion=""; int pos=0;
do{
// se copian las cadenas retornadas en "ae" y "XX"
ae=Lexico(); XX=pila[i-1];
pos=RetPos();
if( t.Terminal(XX)) // retorna 1 si XX es terminal, sino 0
if(XX.equals(ae)) {
i=i-1; // se descuenta un simbolo de la pila
mover(pos); // se lee la cadena de entrada desde
// la posicion "pos"
}
else { System.out.println("1"); error();}
else
if (t.ExisteInterseccion(XX,ae)){
produccion=t.RetProduccion();
System.out.println("| "+RetPila()+" | "+RetCad()+" | "+XX+"-->"+produccion);
i = i -1; // se descuenta un simbolo de la pila
// si la produccion es & no se mete en la pila
if(!produccion.equals("&")) Empilar(produccion);
}
else {System.out.println("2");error();}
}while(!XX.equals("$"));
}
IMPLEMENTACION
public static void main(String arg[]){
PARSER p=new PARSER();
p.lectura();
System.out.println("\n analisis correcto");
}
} // FIN DE PARSER

LEER CADENA:
a*b
| $E | a * b $ | E-->RT
| $RT | a * b $ | T-->GF
| $RGF | a * b $ | F-->i
| $RG | * b $ | G-->GF*
| $RGF | b $ | F-->i
| $RG | $ | G-->&
| $R | $ | R-->&

analisis correcto

Process completed.
ADP
Ejemplo 7

A partir del siguiente ejemplo de cdigo del lenguaje


WHILE, generar un ADP y prubelo para alguna secuencia
del lenguaje. El lenguaje no debe aceptar el programa vaco
y el argumento de cada while debe ser solo un identificador

Un programa ejemplo del lenguaje WHILE

while a {
while b { }
while c { }
}
while d { }
ADP G=(Vn, Vt, S, P)
Vn={ S, W, A}
Se elimina la Vt={while, {, }, id }
Gramtica P={
ambigedad SWK
G=(Vn, Vt, S, P) KS /
Vn={ S, W, A} AS/
Vt={while, {, }, id } Wwhile id { A}
P={
SWS / W }
AS/
Wwhile id { A}

} G=(Vn, Vt, S, P)
Vn={ S, W, A}
Vt={while, {, }, id }
P={ Se eliminan
SWA producciones
AS/ redundantes
Wwhile id { A} la

}
CONJUNTOS
G=(Vn, Vt, S, P)
Vn={ S, W, A}
Vt={while, {, }, id }
P={
SWA
AS/
Wwhile id { A}

Vn PRIMERO SIGUIENTE
S while $ R1
W while $, while R3, R2
A while, $, } R3, R2
TABLA DE ANALISIS
SINTACTICO
CONJUNTOS
G=(Vn, Vt, S, P)
Vn={ S, W, A} Vn PRIMERO SIGUIENTE
Vt={while, {, }, id } S while $
P={
SWA W while $, while
AS/ A while, $, }
Wwhile id { A}

TAS
Vn while $ }
S SWA
W Wwhile id { A}
A AS A A
PRUEBA DEL ANALIZADOR
G=(Vn, Vt, S, P)
Vn={ S, W, A}
Vt={while, {, }, id } S
P={
SWA
AS/ WA
Wwhile id { A}

}
while id { A}
while b { while c{ } }
S

WA

while id { A}
PRUEBA DEL ANALIZADOR

G=(Vn, Vt, S, P)
Vn={ S, W, A} PILA SECUENCIA PRODUCCION
Vt={while, {, }, id } $S while b{while c{}} $ SWA

P={ $AW while b{while c{}} $ Wwhile id {A}

SWA $A}A{id while while b{while c{}} $

AS/ $A}A{id b{while c{}} $

Wwhile id { A} $A}A{ {while c{}} $


$A}A while c{}} $ AS

} $A}S while c{}} $ SWA

G es LL $A}AW
$A}A}A{id while
while c{}} $
while c{}} $
Wwhile id {A}

TAS
$A}A}A{id c{}} $
Vn while $ } $A}A}A{ {}} $
$A}A}A }} $ A
S SWA
$A}A} }} $
W Wwhile id { A}
$A}A }$ A
A AS A A $A} }$
$A $ A

$ $ SE ACEPTA
LABORATORIO

Escriba un ADP para reconocer una zona de declaracin


de variables. Por ejemplo

dato, a, b: integer;
cant, x: real;
Total: real;

Luego implemntelo en C++ o en java

Observacin:

Puede utilizar el programa para el ejemplo 6


Se recomienda utilizar lexemas de un solo carcter si
va a utilizar la implementacin para el ejemplo 6, por
ejemplo el cdigo anterior podra tratarse as:

d, a, b: i;
c, x: r;
T: r;

Enviar a zorroculto69@Hotmail.com

S-ar putea să vă placă și