Gramaticas PDF

También podría gustarte

Está en la página 1de 54

33

Ing. Fco. Ros Acosta

Gramticas

friosam@prodigy.net.mx

II
GRAMTICAS.

2.1 INTRODUCCIN A LAS GRAMTICAS

.......................

34

2.2 ESTRUCTURAS DE LAS GRAMTICAS

.......................

37

2.3 CLASIFICACIN DE LAS GRAMTICAS

.......................

41

2.4 REPRESENTACIN DE GRAMTICAS

.......................

44

2.5 EJERCICIOS PROPUESTOS

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

33

34

Ing. Fco. Ros Acosta

Gramticas

friosam@prodigy.net.mx

Palabras clave : gramticas, clasificacin de gramticas. Gramticas de contexto libre.Lenguajes y


autmatas. Derivaciones, lenguaje generado.

2.1 INTRODUCCIN A LAS GRAMTICAS.


En la seccin 1.3 se mostr como las primeras fases de anlisis en un proceso de
compilacin interactan para efectuar ciertas tareas sobre el programa fuente. El
analizador lxico que tiene de entrada al programa fuente, identifica a los tokens y los
enva al analizador sintctico, fig 2.1.

Programa
Fuente

ANALIZADOR

ANALIZADOR

LXICO

SINTCTICO

rbol de
reconocimiento
(rbol de parse)

tokens

Fig 2.1 Anlisis lxico y anlisis sintctico de un programa.


Cuntos tokens enva el analizador lxico al analizador sintctico ?; los que requiera el
propio analizador sintctico para el reconocimiento de la sintxis de una instruccin. La
tarea fundamental del anlisis sintctico es recibir los tokens que juntos (concatenados)
constituyen en escencia, a una instruccin. De acuerdo a ciertas reglas de sintxis para
cada instruccin , decide si stas -las instrucciones-, estn bien construidas; es decir,
respetan y cumplen dichas reglas de sintxis.
Las gramticas consisten de un conjunto de reglas, que nos permiten especificar
formalmente la sintxis de las instrucciones de un lenguaje de programacin.

Expresiones regulares
Gramticas

LyA

34

= especificacin de tokens.

= especificacin de sintxis de instrucciones.

35

Ing. Fco. Ros Acosta

friosam@prodigy.net.mx

Gramticas

Los programas analizadores sintcticos que se basan en gramticas para reconocer las
instrucciones residentes en el programa fuente se denominan Parsers (reconocedores).
Las dos clases de parser ms comunes son :
Parser Descendente ( Top Down )
Parser Ascendente ( Bottom Up )
INSTRUCCIONES
Especificacin
Reconocimiento
Gramticas

1. Parser Descendente
( Top Down )
2. Parser Ascendente
( Bottom Up )

Fig. 2.2 Especificacin y reconocimiento de instrucciones.


Veamos con ms detalle el fin de una gramtica. Hemos dicho que una gramtica se
utiliza para especificar de manera formal, la sintxis de una instruccin ( o de varias ) .
El uso de una gramtica le permite a un reconocedor ( Parser ), saber si una instruccin
est bien construida. Si no est adecuadamente construida, el reconocedor lo har saber
mediante el envo de un mensaje error de sintxis .
Supongamos la instruccin scanf que en lenguaje C es usada para leer datos desde el
teclado. En la figura 2.3 se muestran algunas posibles formas en las que puede ser
encontrada en un programa fuente, la instruccin scanf.
1)
2)
3)
4)
5)

scanf (%d,&iNum);
scanf (%f,pfNum);
scanf (%s %d,sNom,&iTen);
scanf (%c,&asCar[i]);
scanf (%d %f %d,piEnt1,pfReal,piEnt2);
.....

Fig 2.3 Algunas instancias de la instruccin scanf.

35

36

Ing. Fco. Ros Acosta

friosam@prodigy.net.mx

Gramticas

Podemos llegar a ciertas conclusiones hechndole un vistazo a la fig. 2.3. Entre las
cuestiones que mas nos interesan, estn :
1. Las n instancias son un conjunto de tokens concatenados. La instancia 1 tiene 8
tokens debidamente concatenados :

scanf

Palabra reservada

Separador

%d

CteLit

Separador

&

Operador de Direccin

iNum

Identificador

Separador

Terminador de Instruccin

2. Las n instancias de la instruccin constituyen un lenguaje, donde las cadenas que lo


constituyen, precisamente, son tokens concatenados.
3. Si el analizador sintctico ( Parser descendente o ascendente ) se basa en gramticas
para efectuar el reconocimiento de una instruccin bien construida, entonces la
gramtica debe especificar al lenguaje compuesto por todas las cadenas que son una
instancia para dicha instruccin.

Una gramtica G denota a


un lenguaje L (G).

LyA

36

37

Ing. Fco. Ros Acosta

friosam@prodigy.net.mx

Gramticas

2.2 ESTRUCTURA DE LAS GRAMTICAS.


Una gramtica consiste de 4 componentes, y es denotada por G = (VT, VN, S, )
donde :

VT Es el conjunto de smbolos terminales a partir de los cuales las cadenas son

formadas. Si la gramtica es usada para denotar un lenguaje de programacin , entonces


los tokens son los smbolos terminales.
VN Es el conjunto de smbolos no terminales , tambin llamados variables sintcticas.
Las variables sintcticas denotan un conjunto de cadenas. Los smbolos no terminales
definen conjuntos de cadenas que ayudan a definir el lenguaje generado por la
gramtica.
S Es un smbolo no terminal de la gramtica que es distinguido como smbolo de
inicio. El conjunto de cadenas que este smbolo de inicio denota, es el lenguaje definido
por la gramtica G.
Es el conjunto de producciones o reglas gramaticales. Las producciones de una
gramtica especifican la manera en que los tokens ( terminales ) y las variables
sintcticas ( no terminales ) pueden ser combinados para formar cadenas.

Ejemplo 2.1 Dada la siguiente gramtica :


R
R
R
R
P
P

read
readln
read (P)
readln (P)
P, id
id

Encuentra sus componentes VT, VN,, S y .


Usemos la siguiente convencin de notacin :
Las letras maysculas servirn para denotar variables sintcticas (Smbolos no
terminales).
El lado izquierdo de la primera produccin es el smbolo de inicio.
Si A
1 , A
2, . . . A
K son producciones teniendo a la no
terminal A en el lado izquierdo, podemos escribir A
1 2 . . . K donde
1, 2, . . . ,K se les llama las alternativas para A.

37

Ing. Fco. Ros Acosta

38

friosam@prodigy.net.mx

Gramticas

Encontremos el conjunto de smbolos terminales VT.


VT = { read, readln, ( , ) , , , id }
ya que read y readln son palabras reservadas, ( , ) y la coma son separadores, e id es un
identificador.

Todos son tokens !!!

LyA

VN = { R, P } nicamente dos smbolos no terminales.


El smbolo de inicio es R, aplicando la 2da. convencin de notacin, y el conjunto de
producciones es condensado, aplicando la 3a. convencin :
={ R
P

read readln read (P) readln (P)


P, id id }

La gramtica es :

G = ( { read, readln, ( , ) , , , id }, {R,P},R, )


Ejemplo 2.2 Supongamos la gramtica que especifica a la instruccin de asignacin
en Pascal, con expresiones aritmticas +, -, * y / nicamente.
1)
2)
3)
4)
5)
6)
7)
8)

A
E
E
E
T
T
T
F

id := E;
E+T
E -T
T
T*F
T/F
F
id

38

Ing. Fco. Ros Acosta

39

9)
10)
11)

F
F
F

friosam@prodigy.net.mx

Gramticas

num
(E)
-E

La gramtica G = (VT, VN, S, ) tiene los siguientes componentes :


VT = { id, :=, ; , +, - , * , / , num, ( , ) }
VN = { A,E,T,F }
S = A
Usando la convencin de notacin (3), la gramtica puede representarse como :
A
E
T
F

id := E;
E+TE-TT
T*FT/F F
id num (E) -E

Ejemplo 2.3 Veamos una gramtica que nos genera el lenguaje de todos los
nmeros enteros pares :
N
N
K
K
L
L
L
L
P
P
P
P
P
Z
Z
...
...
Z
D

KP
L
KD
Z
2
4
6
8
0
2
4
6
8
1
2

9
0

39

Ing. Fco. Ros Acosta

40

D
D
...
...
D

friosam@prodigy.net.mx

Gramticas

1
2

VT = { 0, 1, 2..., 9 }

// Los dgitos del 0-9.

VN = { N, K, L, Z, D, P }
S=N
La gramtica con la agrupacin de las alternativas para cada variable sintctica es :
N
K
P
L
D
Z

KP L
KD Z
0 2 4 6 8
2468
0 1 ... 9
1 2 ...9

tiene 32 producciones
LyA

Bueno, ya s de que se conforma una gramtica,


pero ....

Cmo interpreto a las producciones ?


Cmo la gramtica genera a un lenguaje ?

LyA

Seccin 2.4 resuelve tus preguntas ! !

40

Ing. Fco. Ros Acosta

41

Gramticas

friosam@prodigy.net.mx

2.3 CLASIFICACIN DE LAS GRAMTICAS.


Chomsky clasific las gramticas en 4 clases, imponiendo un conjunto de restricciones
sobre las producciones. La clasificacin es la siguiente :

Gramticas no restringidas.
Gramticas sensibles al contexto.
Gramticas de contexto libre.
Gramticas regulares.

Gramticas no restringidas.- Son aquellas en las cuales las producciones no


estn sujetas a ninguna clase de restriccin en su composicin.
Gramticas sensibles al contexto.- Son aquellas que contienen nicamente
producciones de la forma :

, donde , y denota la longitud de la cadena .

Ejemplo :
(1)
(2)
(3)
(4)
(5)
(6)

S
S
bB
bC
CB
cC

Sea la gramtica con producciones :


aSBC
abC
bb
bc
BC
cc

En la figura 2.4 mostramos la produccin y los diferentes parmetros ,,,.


No de
Produccin
1

aSBC

abC

bB

bb

bC

bc

CB

BC

cC

cc

Fig. 2.4 Longitudes de y .

41

Ing. Fco. Ros Acosta

42

friosam@prodigy.net.mx

Gramticas

Para la gramtica G = ( {a,b,c}, {S,B,C}, S, ), siempre se cumple .

Pero,...Porqu eso de
sensibles al contexto ?

LyA

Una produccin puede leerse de la siguiente forma :


A

A produce a alfa bien, A es definido por alfa.

Si analizamos ms detenidamente la gramtica del ejemplo, encontramos producciones


como las no. 3, 4, 5 y 6 que tienen la siguiente interpretacin :
bB

bb

B produce es definido por bb slo cuando a su izquierda


tiene el token b

bC

bc

C produce es definido por bc slo cuando a su izquierda


tiene el token b

CB

BC

C produce es definido por BC slo cuando a su derecha


tiene la no terminal B

B produce es definido por BC slo cuando a su izquierda


tiene la no terminal C.

Lo mismo sucede para la produccin 6. La interpretacin se deja de ejercicio al alumno.


Los ejemplos anteriores se refieren a que una no terminal genera o produce una cadena,
slo cuando su contexto ( a su izquierda a su derecha ) est restringido a la aparicin
de cierto token o de un no terminal. Este contexto est contenido en el lado izquierdo de
la propia produccin.

42

Ing. Fco. Ros Acosta

43

friosam@prodigy.net.mx

Gramticas

Entonces : la primera produccin


S
aSBC
Nada a la izquierda, nada a la derecha
CONTEXTO LIBRE ?

LyA

Gramtica de contexto libre.- Son aquellas que contienen solamente producciones de


la forma :

, donde y VN.

Ejemplo :
S
C
C

Sea la gramtica con producciones :

aCa
aCa
b

Sus componentes son : VT = { a,b }, VN = { S,C }, S = S.


Analizando el lado izquierdo de cada produccin, se encuentra un smbolo no terminal,
libre en su contexto, es decir, a su izquierda y derecha aparece la cadena .
Gramticas de contexto libre : su caracterstica principal, el lado
izquierdo de las producciones slo un smbolo no terminal :

NO MS
Gramticas Regulares.- Son aquellas que contienen slo producciones de la forma

, donde y VN y tiene la forma aB a, donde


a VT y VN.

43

Ing. Fco. Ros Acosta

44

Ejemplo :
S
S
B
C
C

friosam@prodigy.net.mx

Gramticas

Sea la gramtica con producciones :

aS
aB
bC
aC
a

Sus componentes son : VT = { a, b }, VN = { S,B,C }, S = S.


Observando cada una de la reglas o producciones, todas tienen en su lado izquierdo slo
una no terminal. Las gramticas regulares son tambin gramticas de contexto libre, o
sea :
gramticas regulares

gramticas de contexto libre.


Adems, el lado izquierdo de cada produccin cumple con la forma aB a, por
ejemplo :
S
S
B
C
C

aS
aB
bC
aC
a

a=a
a=a
a=b
a=a
a=a

,
,
,
,

B=S
B=B
B=C
B=C

Los lenguajes de programacin tienen la caracterstica agradable que consiste en que la


mayora de sus instrucciones pueden ser especificadas, por gramticas de contexto libre.

2.4 REPRESENTACIN DE GRAMTICAS.


Dedicaremos esta seccin al estudio de varios temas que se relacionan con una gramtica
y su representacin. A continuacin listamos los temas.
Lenguaje generado por una gramtica.
Derivaciones
Arboles de reconocimiento (Arboles de Parse)
Ambigedad
Escritura de gramtica
Precedencia y Asociatividad de operadores.
Recursividad a la izquierda. Recursividad a la derecha.
Notacin de Backus Naur (BNF).

44

Ing. Fco. Ros Acosta

45

friosam@prodigy.net.mx

Gramticas

Lenguaje generado por una gramtica.


En la seccin 2.1 concluimos que una gramtica genera un lenguaje L(G) , donde G
es la gramtica. En lenguajes de programacin cada cadena del lenguaje, es un conjunto
de tokens concatenados. Las gramticas tambin pueden usarse para representar
tokens, pero esta tarea es mejor delegarla a las expresiones regulares. En algunos
ejemplos utilizaremos una gramtica para representar a un token, como en el ejemplo
2.3. Utilizaremos a las gramticas para especificar las reglas de sintxis de
instrucciones o sentencias, pertenecientes a un lenguaje determinado.
Bueno !! ,

pero ...

Cmo genera a las cadenas de


un lenguaje, una gramtica ?
LyA

Existen varias formas de visualizar el proceso mediante el cual una gramtica genera o
define a un lenguaje. A continuacin veremos dos de ellas :
Derivaciones
Arboles de Reconocimiento (Arboles de Parse).
Herramientas para generar un lenguaje
utilizando una gramtica :

LyA

Derivaciones
Arboles de parse

45

46

Ing. Fco. Ros Acosta

friosam@prodigy.net.mx

Gramticas

Derivaciones.
Supongamos la gramtica del ejemplo 2.1, que define al lenguaje de la instruccin de
lectura en Pascal.
R
P

read readln read(P) readln(P)


P,id id

A menudo, nos hacemos la siguiente pregunta :


R *
readln (iNum)

El smbolo de inicio R deriva en cero ms etapas a la


sentencia readln (iNum) ?

El smbolo es el utilizado para denotar una derivacin , es decir, la generacin de


una cadena (sentencia) del lenguaje. El smbolo se puede combinar con otro para
indicar :

deriva en 0 o ms etapas a ...


deriva en una o ms etapas a ...
deriva en una etapa a ...
Derivacin ? ...
En qu consiste ?

LyA

La derivacin consiste en utilizar una produccin, con el fin de ir efectuando


sustituciones; una sustitucin indica que la no terminal -variable sintctica- situada al
lado izquierdo de una produccin, es reemplazada por la cadena que constituye la parte
derecha de dicha produccin. As, para la anterior cuestin :
R *
readln (iNum)
el proceso de derivacin es :
R readln (P) readln (id)

46

Ing. Fco. Ros Acosta

47
(1)

friosam@prodigy.net.mx

Gramticas

(2)

La generacin es exitosa, ya que el analizador lxico no enva el lexema iNum, sino el


token id (identificador). Asimismo, la derivacin (1) utiliza la produccin R readln(P)
y la derivacin (2), utiliza la produccin P
id .

Porqu iniciamos la derivacin


con R y no con P ? .
Es lo mismo ?

LyA

La generacin (derivacin) de una sentencia o cadena de un lenguaje, slo se puede


lograr si dicha derivacin comienza, a partir del smbolo de inicio o distinguido de la
gramtica.
Analicemos ahora, las producciones de la gramtica de este ejemplo. El smbolo es
interpretado como Es definido por . En las producciones :
R

read readln read(P) readln(P)

decimos que R es definido por las cadenas read o readln o read(P) o bien readln(P). La
definicin del smbolo no terminal R est en funcin de los tokens read, readln, ( , ) y la
variable sintctica -smbolo no terminal- P. Para la definicin de P, se utilizan dos
producciones :
P

P,id id

O sea , P es definido por P, id o bien por el token id solamente. Aqu P el smbolo no


terminal, est definido en funcin de los tokens id, la coma y por el mismo !!. Esta regla
es claramente recursiva. El uso de la recursividad al escribir reglas o producciones, es la
caracterstica principal que distingue a una gramtica con respecto a una expresin
regular. Una expresin regular no tiene definiciones recursivas.
Escritura de :

Expresiones regulares ... definiciones no recursivas.

LyA

Gramticas

... definiciones recursivas.


47

Ing. Fco. Ros Acosta

48

friosam@prodigy.net.mx

Gramticas

La recursividad en una regla es para una gramtica, lo que la operacin de cerradura es


para una expresin regular ( r* r+ ). Para mostrar lo anterior, obtengamos la
derivacin para la cadena readln (x,y,z).
R *
readln (x,y,z)
R
R
R
R

readln (P)
readln (P,id)
readln (P,id,id)
readln (id,id,id)

//
//
//
//

R
P
P
P

readl (P)
P,id
P,id
id

La aplicacin de la regla recursiva P


P,id nos permite obtener la cadena ,id
cuantas veces se encuentre en la sentencia un id. Obviamente el smbolo no terminal P,
genera el lenguaje :
L(P) = { id (,id)n n 0 } , que es una concatenacin de id con las cadenas (,id)n
fig. 2.5.

...

Cadena de L(P)

id (,id) 0 = id = id

id (,id) 1 = id,id

id (,id) 2 = id(,id,id) = id,id,id


...

Fig 2.5 Lenguaje generado por la variable sintctica P.


Podemos tambin concluir con este ejemplo, que P nunca podr derivar por si misma,
una sentencia del lenguaje especificado por la gramtica :
R
P

read readln read(P) readln(P)


P,id id

cuyo smbolo de inicio es R .

P * readln (x) ?

NUNCA
LyA
48

Ing. Fco. Ros Acosta

49

Gramticas

friosam@prodigy.net.mx

Ejemplo 2.4 Suponga la gramtica :


A
E
T
F

id = E
E+T E-T T
T*F T/F F
id num -E (E)

con elementos : VT = { id, =, +, -,*, /, num, ( , ) }, VN = { A, E, T, F }, S = A .


Obtengamos la derivacin de x = y + 5 * z, es decir,
Derivacin
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)

id = E
id = E+T
id = T+T
id = F+T
id = id+T
id = id+T*F
id = id+F*F
id = id+num*F
id = id+num*id

A *
x = y+5*z .

Produccin Aplicada
A
E
E
T
F
T
T
F
F

id = E
E+T
T
F
id
T*F
F
num
id

Derivacin con xito.


En la anterior derivacin de 9 etapas, observamos que siempre sustitumos el no terminal
situado ms a la izquierda de la forma sentencial. Una forma sentencial es una cadena
que contiene al menos un smbolo no terminal -variable sintctica-. Una sentencia es una
cadena que contiene solamente smbolos terminales -tokens-. En la anterior tabla las
derivaciones numeradas del (1) al (8) derivan formas sentenciales. La derivacin (9)
produce una sentencia. Veamos la derivacin (1) : A id = E . La nica no
terminal que podemos sustituir es la E, empleando la alternativa E
E+T ,
obtenemos la derivacin (2) :
A id = E id = E+T
Podemos sustituir
la E o bien la T

LyA
49

!!

Ing. Fco. Ros Acosta

50

Gramticas

friosam@prodigy.net.mx

A id = E id = E+T id = T+T

E
T
En una derivacin ms a la izquierda
siempre sustitumos a la no terminal que se
encuentra ms a la izquierda.

LyA

Llamemos a esta manera de derivar una sentencia como Derivacin a la Izquierda. Un


reconocedor descendente (Parser Top Down) es un programa que reconoce
instrucciones utilizando una gramtica y derivaciones a la izquierda.
A continuacin mostraremos el proceso de derivacin a la izquierda de la cadena :
x = -y*z+1
Derivacin a la izquierda
A

id
id
id
id
id
id
id
id
id
id
id
id

Produccin Aplicada

= E
= E+T
= T+T
= T*F+T
= F*F+T
= -E*F+T
= -T*F+T
= -F*F+T
= -id*F+T
= -id*id+T
= -id*id+F
= -id*id+num

LyA

A
E
E
T
T
F
E
T
F
F
T

id = E
E+T
T
T*F
F
-E
T
F
id
id
F

num

Caray !! El proceso de derivacin de una sentencia o


instruccin, requiere de una significativa cantidad de
etapas, an para una cadena tan simple como :
x = -y*z+1
Pobre Parser !! ....
Ser que todo lo anterior lo hace a mano ?!!
50

Ing. Fco. Ros Acosta

51

Gramticas

friosam@prodigy.net.mx

Afortunadamente, existen tcnicas que permiten que el algoritmo utilizado por un


reconocedor ( Parser ) sea eficiente.

Ejemplo 2.5 Tomemos la misma gramtica y tambin la misma sentencia a


reconocer. Obtengamos la derivacin :
A *
x = y+ 5*z
Derivacin a la derecha
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)

Produccin Aplicada

id = E

id = E

id = E+T

E+T

id = E+T*F

T*F

id = E+T*id

id

id = E+F*id

id = E+num*id

num

id = T+num*id

id = F+num*id

id = id+num*id

id

Comparando con la derivacin en el ejemplo 2.4, observamos que tenemos el mismo


nmero de etapas de derivacin, pero siempre se ha sustitudo el no terminal situado
ms a la derecha. La derivacin (2) tiene dos no terminales que pueden sustituirse:
A id = E

id = E + T

En una derivacin a la derecha, la no terminal seleccionada debe ser la T. Esto sucede,


precisamente al obtener la 3a. derivacin, en que T es sustituda por la produccin o
alternativa T
T*F .
A id = E

id = E+T id = E+T*F

51

Ing. Fco. Ros Acosta

52

Gramticas

friosam@prodigy.net.mx

Un reconocedor ascendente ( Parser Bottom Up) es un programa que reconoce


instrucciones utilizando una gramtica y derivaciones a la derecha. Al proceso de
derivacin a la derecha, tambin se le conoce como Derivacin Cannica. La siguiente
tabla nos muestra la derivacin a la derecha de la cadena : x = - y * z + 1 .

Derivacin a la derecha

Produccin Aplicada

id = E

id = E

id = E+T

E+T

id = E+F

id = E+num

num

id = T+num

id = T*F+num

T*F

id = T*id+num

id

id = F*id+num

id = -E*id+num

-E

id = -T*id+num

id =

-F*id+num

id =

-id*id+num

id

Las derivaciones nos permiten visualizar el proceso de


generacin de cadenas, al usar una gramtica.
Derivaciones a la izquierda ... utilizadas por :

Reconocedores descendentes.
Derivaciones a la derecha ... utilizadas por :

LyA

Reconocedores ascendentes.

A continuacin se muestran algunos ejemplos tpicos, donde se obtiene el lenguaje


generado por una gramtica dada.

52

Ing. Fco. Ros Acosta

53

Gramticas

friosam@prodigy.net.mx

Ejemplo 2.6 Encontrar el lenguaje generado L(G) por la gramtica cuyo conjunto
de producciones es :
S
C
C

aCa
aCa
b

Los componentes de la gramtica son : VT = { a,b }, VN = { S,C }, S = S.


Agrupemos en alternativas, las producciones cuyo lado izquierdo sea la misma no
terminal :
S
C

aCa
aCa b

Paso 1.
Agrupar las producciones.

Luego, apliquemos una derivacin utilizando slo reglas no recursivas :


S

aCa

aCa

aba

Paso 2.
Obtener las sentencias simples,
empleando slo combinaciones de
producciones no recursivas.

Derivacin

Produccin utilizada

S aCa
aba

S
C

aCa
b

Sentencia derivada aba

LyA

Ohh !! ...
Existe un smbolo b y en su
contexto, observo que a la
izquierda y a la derecha se tiene un
smbolo a .

53

LyA

Ing. Fco. Ros Acosta

54

Gramticas

friosam@prodigy.net.mx

Ahora, usemos la regla recursiva C


esta regla recursiva.

aCa para observar qu cadenas produce el uso de

S aCa aaCaa aaaCaaa aaaaCaaaa


S

aCa

aCa

aCa

aabaa
C

aCa

aaabaaa
C

aaaabaaaa

La regla C
aCa produce el mismo nmero de as a la izquierda y a la derecha de la
b.
Podemos concluir, que el lenguaje generado por G= ( {a,b}, {S,C}, S, ) es :
L (G) =

{ an b an n > 0 }

Y para n = 0 ?

LyA

Ejemplo 2.7 Supongamos la gramtica del read y readln en Pascal.


read readln read(P) readln(P)
P,id id

R
P

Obtener el lenguaje generado por la gramtica.


La gramtica tiene las alternativas agrupadas. nicamente existe una produccin
recursiva :
P P,id
Obtengamos las cadenas ms simples que genera el smbolo de inicio R . sto se logra,
derivando slo con reglas no recursivas :
R read
R

//

1a. cadena

read

R readln

//

2a. cadena

54

Ing. Fco. Ros Acosta

55
R

readln

R read (P)
R

read(P)

read (id)

//

readln(P)

3a. cadena

id

R readln (P) readln (id)


R

Gramticas

friosam@prodigy.net.mx

//

4a. cadena

id

Ahora, apliquemos la regla recursiva para observar el conjunto de cadenas que produce :
R
R

read(P)

read(P)

read(P,id)
P,id

read(P,id,id)

read(id,id)
P

P,id

read(P,id,id,id)

P,id

read(id,id,id)

id

id

read(id,id,id,id)
P

id

Juntemos las sentencias anteriormente derivadas en una tabla, y observemos las partes
que las componen :
Sentencia
read
readln
read(id)
readln(id)
read(id,id)
readln(id,id)
read(id,id,id)
readln(id,id,id)

Parte 1

Parte 2

read
readln
read
readln
read
readln
read
readln

(id )
(id)
(id,id)
(id,id)
(id,id,id)
(id,id,id)

El lenguaje generado es la concatenacin de parte1 con parte 2 :


L(G) = { (read r readln s ) ( ( id ( ,id ) n ) ) m | n >= 0, 0 m 1,
0 r 1, 0 s 1, r s }

Ejemplo 2.8
S
S
B
C
C

Supongamos la gramtica con producciones :

aS
aB
bC
aC
a
55

Ing. Fco. Ros Acosta

56

Gramticas

friosam@prodigy.net.mx

Obtener el lenguaje generado L(G).


Volviendo a los ejemplos 2.6 y 2.7, el lenguaje generado siempre ha sido expresado en
funcin de los smbolos terminales. Una sentencia o instruccin de un lenguaje, es una
concatenacin de tokens.

Instruccin = concatenacin de
tokens !!

LyA

El aplicar inicialmente las reglas o producciones recursivas, tiene como objetivo


encontrar las cadenas o sentencias ms simples. Agrupemos la gramtica :
aS aB
bC
aC a

S
B
C

Las reglas no recursivas son :


S
B
C

aB
bC
a

Obtengamos una derivacin con estas producciones :


S

aB

aB abC
B

bC

aba

Sentencia ms simple !!!

Ahora, utilicemos la recursividad de ms abajo, es decir C


S

aB
S

aB

abC
bC

abaC
C

aC

abaaC

abaaaC

aC

abaa

aC

abaaa

56

aC .

abaaaa
C

57

Ing. Fco. Ros Acosta

friosam@prodigy.net.mx

Gramticas

Esta regla produce as a la derecha de la b solamente !!!


La regla recursiva ms abajo vista
desde el smbolo de inicio de la
gramtica es precisamente C
aC.
La regla recursiva siguiente ms abajo,
se busca ahora en las alternativas para la
no terminal B. En este caso B no
produce recursividad, por lo que la regla
recursiva siguiente ms abajo es : S
aS .

Reglas recursivas
de ms abajo ? !!

LyA

Observemos que es lo que produce la aplicacin recursiva


de esta regla.
S aS aaB aabC

S aaS aaaB aaabC


S aaaS aaaaB aaaabC
S aaaaS aaaaaB aaaaabC

aaba
aaaba
aaaaba
aaaaaba

La regla S
aS produce as a la izquierda de la b !! . As, el lenguaje generado es
identificado como :

L (G) = { am b an m,n > 0 }

Ejemplo 2.9 Sea la gramtica con producciones :

N
N
P
P
P
P
P
D
D
D
D
.
D

DN
P
0
2
4
6
8
0
1
2
3
9

Obtener el lenguaje generado L(G), donde G = ( {0,1,2..,9}, {N,P,D}, S, ) .


Agrupamos las alternativas para cada una de las no terminales -variables sintcticas- en

57

Ing. Fco. Ros Acosta

58

G:
N
P
D

friosam@prodigy.net.mx

Gramticas

DN P
0 2 4 6 8
0 1 2 3 4 5 6 7 8 9

El nmero de producciones de es 17, no obstante que despus de la agrupacin


pudieran parecer slo 3. nicamente existe una regla recursiva N
DN. Las
sentencias ms simples, se obtienen con una derivacin utilizando slo reglas no
recursivas.
N P
N

Nmeros pares de una


cifra, incluyendo el cero.

Ahora, aplicamos la regla recursiva ms abajo, que resulta ser : N


N
N

DN

DN
N

DP
P

DN.

D0 00
P

10
D

D2
P

N DN
N

DN

Pares de 2 cifras

DDN
DN

02

20

DDDN

DN

La recursividad en N
DN , produce
dgitos a la izquierda de un dgito par.
La gramtica genera nmeros pares,
incluyendo al cero.

Ahora, podemos decir que el lenguaje generado es :

58

LyA

Ing. Fco. Ros Acosta

59

Gramticas

friosam@prodigy.net.mx

L (G) = { dign Par dig {0,1,2,....9} , par {0,2,4,6,8} , n >= 0 }

Ejemplo 2.10 Sea el conjunto de producciones :


S
S
A
A
B

aS
bA
aA
aB
b

Obtener el lenguaje generado por la gramtica G = ( {a,b} , {S,A,B}, S, ).


aS bA
aA aB
b

S
A
B

Recuerda !!
El primer paso es
agrupar las producciones

LyA
Recursivas
S
A

No recursivas

aS
aA

S
A
B

bA
aB
b

Luego, identifica las


reglas recursivas y las no
recursivas.

Ahora, encuentra las cadenas ms


simples, derivando slo con
producciones no recursivas.
LyA

S bA baB

bab

Cadena ms simple

bA

bA
A

baA
aA

baab

baaB
aB

baaab

baaA baaaB

59

Busca la regla recursiva


ms abajo, y aplicala
para observar las
cadenas que produce :
A
aA

Ing. Fco. Ros Acosta

60
A

aA

friosam@prodigy.net.mx

aB

baaaab

baaaA baaaaB
A

aA

aB

baaaaA baaaaaB

baaaaab

aA

aB

Gramticas

La regla A
aA
produce as entre las dos
bs .

LyA

Slo falta aplicar la otra regla recursiva. Observemos las cadenas que produce :
S aS abA abaB
aaS aabA aabaB
aaaS aaabA aaabaB
aaaaS aaaabA aaaabaB

abab
aabab
aaabab
aaaabab

S
aS agrega as a
la izquierda de la
primera b

De acuerdo a las anteriores sentencias derivadas, el lenguaje generado puede escribirse


como :

L(G) = { a m b a n b | m > = 0 , n > 0 }

Arboles de Reconocimiento (Arboles de Parse).


Un rbol de parse puede ser visto como una representacin grfica de una derivacin,
donde el orden en que son aplicadas las producciones es mostrado, debido a la naturaleza
jerrquica del rbol.
Un rbol de parse tiene las siguientes caractersticas :
La raz del rbol es el smbolo de inicio de la gramtica.
Las hojas (nodos sin hijos) son smbolos terminales, es decir, tokens.
Los nodos intermedios son etiquetados siempre por un smbolo no terminal.
Un nodo y sus hijos constituyen una produccin.

60

Ing. Fco. Ros Acosta

61

Gramticas

friosam@prodigy.net.mx

El rbol de parse que representa la derivacin R read(x,y) es mostrado enseguida. La


gramtica es la del ejemplo 2.7.
R
R

read(P)

P,id

read

(
P

id

id

id
En el rbol se aprecian 6 nodos sin hijos, es decir, hojas. Todos ellos etiquetados por un
token. La raz es el smbolo de inicio R de la gramtica. Los nodos intermedios son 2 y
ambos son etiquetados por la variable sintctica P.
Tomemos la gramtica del ejemplo 2.3 cuyo lenguaje generado son los nmeros pares
excluyendo al cero. El nmero par nunca empieza con cero. La derivacin para la
sentencia N * 768 y el rbol de parse son los siguientes :
N
K
K

KP

KD

8
D

7
N KP
N

KP

KDP
K

KD

ZDP

7DP
7

76P
D

768
P

La raz del rbol es etiquetado con el smbolo de inicio N. Existen 3 hojas etiquetadas
por los tokens 7,6 y 8. Los nodos intermedios son 5, etiquetados por los smbolos no
terminales K, Z, D y P.

Ambigedad.
Se dice que una gramtica es ambigua, si sta produce ms de un rbol de
reconocimiento (parse) para una misma sentencia. O de otra manera, cuando la

61

Ing. Fco. Ros Acosta

62

Gramticas

friosam@prodigy.net.mx

gramtica produce ms de una derivacin -ya sea izquierda derecha- para una misma
sentencia.
Supongamos la gramtica :
E

E+E | E-E | E*E | E/E | id | num

G = ( { +, -, *, /, id, num }, { E }, E, )
Obtengamos la derivacin para la sentencia : 5 + id * 9
(1) E E+E num+E num+E*E num+id*E num+id*num
E

E+E

num

E*E

id

num

Pero, existe otra derivacin para la misma sentencia :


(2) E E*E E+E*E num+E*E num+id*E num+id*num
E

E*E

E+E

num

id

num

Los arboles de parse para las dos derivaciones anteriores son :


E
E

num

E
E
id

E
E

num

num

(1)

num

id

(2)

Ser adecuado ... escribir gramticas ambiguas ?


Y las gramticas utilizadas anteriormente en los diferentes
ejemplos son ambiguas ?

LyA

62

Ing. Fco. Ros Acosta

63

Gramticas

friosam@prodigy.net.mx

Hemos pretendido que las gramticas anteriormente utilizadas no sean ambiguas.


Adems, para cierto tipo de reconocedores es deseable que las gramticas no sean
ambiguas, y para algunas aplicaciones podemos considerar mtodos que pueden usar
gramticas ambiguas, pero conllevan la utilizacin de reglas para eliminar las
derivaciones o arboles de parse no deseados, dejando slo una opcin de derivacin de
rbol, para cada una de las sentencias instrucciones. Como podemos ver, lo anterior
traera consigo, una tarea de programacin que puede llevar a una mayor complejidad o
bien, a una mayor cantidad de cdigo, cuando construimos un reconocedor.
Generalmente, un reconocedor con gramticas ambiguas, es menos eficiente que un
reconocedor con gramticas no ambiguas, cuando se trata de reconocer un mismo
lenguaje (conjunto de sentencias).
Existe un ejemplo tpico para indicar como una gramtica ambigua puede traer
problemas al derivar una sentencia en ms de una forma no deseada. Nos referimos a
la instruccin if . Propongamos la siguiente gramtica para dicha instruccin en el
lenguaje C :
I

if (E) I | if (E) I else I | S

donde :
S

es el smbolo de inicio que genera sentencias diferentes al if ,

es el smbolo de inicio que genera sentencias de la clase expresiones.

De acuerdo a esta gramtica, la instruccin : if ( E1 ) if ( E2 ) S1 else S2 tiene dos


arboles de parse, y por lo tanto la gramtica es ambigua fig 2.6.
I
if

E
E1

if

if ( E )
E2

I else I
S1

( E
E1

S2

if ( E ) I
E2

(a)

(b)

63

else I

S1

S2

Ing. Fco. Ros Acosta

64

friosam@prodigy.net.mx

Gramticas

Fig 2.6 Arboles de parse para la sentencia if (E1) if(E2) S1 else S2.
Es claro, que el rbol que se prefiere es el de la fig 2.6(a), ya que la regla general es que
el else pertenece al if ms cercano. Modifiquemos la gramtica para que no exista
entre el entonces y el sino del if, una instruccin if que no tenga la rama else (sino).
I

M | N

if ( E ) M else M | S

if ( E ) I | if ( E ) M else N

(1)

(2)
(3)
(5)

(4)
(6)

Tratemos de obtener ms de una derivacin para la sentencia : if ( E1 ) if ( E2 ) S1


else S2 :
I M if ( E ) M else M
(1)

(3)

Falla !!
Obliga a utilizar de nuevo if (E) M else M
o terminar con S .

Ahora, vayamos por otro camino es decir, utilicemos la alternativa (6) :


I if ( E ) M else N if ( E1 )
(2)

(6)

Tambin falla !!
Obliga a terminar con M
S ... (4), o
bien a utilizar M
if ( E ) M else M ...
(3), que sera fatal, ya que slo existe un
else en la sentencia .

As, encontramos que la sentencia slo es derivable siguiendo las etapas de sustitucin
que se muestran a continuacin :
I N
(2)

if ( E ) I

(5)

if ( E1 ) M

(1)

if ( E1 ) if ( E ) M else M

(3)

if ( E1 ) if ( E2 ) S1 else M

(4)

Sentencia reconocida !!
64

Ing. Fco. Ros Acosta

65

Gramticas

friosam@prodigy.net.mx

if ( E1 ) if ( E2 ) S1 else S2

(5)

Escritura de Gramticas.
La escritura de gramticas es una tarea muy parecida a la de escribir definiciones
regulares. No existe una metodologa definida para efectuar dicho trabajo, pero un buen
empiezo es examinar las sentencias ms representativas del lenguaje que deseamos
generar con la gramtica.

Ejemplo 2.11 Deseamos escribir una gramtica para especificar la sintxis de la


instruccin uses en Pascal. Esta instruccin se utiliza para declarar las bibliotecas ya
sea predefinidas o bien definidas por el usuario, al inicio de un programa en Turbo
Pascal. Restringiremos las bibliotecas predefinidas a : crt, printer, dos y graph.
(1)
(2)
(3)

uses
crt ;
uses
crt, pilas, dos;
uses
colas, listas;
...
...

Sentencias representativas
para la instruccin ...
uses .

LyA

Analizando las sentencias anteriores, observamos que la instruccin siempre inicia con
la palabra reservada uses, la cual es un token, seguida de uno ms identificadores de
bibliotecas separados por la coma.
uses
crt;

La instruccin tiene dos componentes :


parte 1 .....

token uses

uses
crt, pilas, dos;

parte 2 .....

bibliotecas separadas
por coma y la
terminacin punto y
coma.

LyA

Observando lo anterior, proponemos la primera produccin de la gramtica :


U

uses B ;
Parte 2
Parte 1

Que de dnde sali la U ? ..


T la abstraes !!!. Es el smbolo
de inicio de la gramtica.

LyA
65

Ing. Fco. Ros Acosta

66

Gramticas

friosam@prodigy.net.mx

Smbolo de inicio.

La variable sintctica B, es necesaria


para generar las cadenas de bibliotecas
separadas por una coma.

La gramtica se complementa aadiendo las siguientes producciones :


U
B
C

uses B ;
B,C | C
id | crt | printer | dos | graph

( G1 )

Veamos el lenguaje producido por B :


B C
// genera una biblioteca, regla no recursiva.
B

B B,C C,C
B

B,C

// genera dos bibliotecas.

B B,C B,B,C B,C,C C,C,C


B

B,C

B,C

// tres bibliotecas.

...
...
De acuerdo a lo anterior, B genera las cadenas C ( , C ) n n >= 0, donde el nmero de
bibliotecas generadas es n+1.
n
0
1
2
3
...
n

bibliotecas generadas
1
2
3
4
...
n+1

La variable sintctica C se utiliza para generar los tokens id (bibliotecas definidas por el
usuario) y las bibliotecas predefinidas crt, dos, graph y printer.
As, la gramtica G1 tiene :

66

Ing. Fco. Ros Acosta

67

Gramticas

friosam@prodigy.net.mx

8 producciones,
VT = { uses, , , ; , id, crt, printer, dos, graph },
VN = { U, B, C }

el smbolo de inicio S = U .
Las derivaciones y arboles de parse para las sentencias representativas se muestran en la
tabla de la figura 2.7.
sentencia
uses crt;

derivacin

rbol de parse

U uses B;
uses C ;
uses crt;

U
uses

C
crt
uses crt, pilas, dos;

U uses B;
uses B,C;
uses B,C,C;
uses C,C,C;
uses crt,C,C;
uses crt,id,C;
uses crt,id,dos;

U
uses

dos

id

crt
uses colas, listas;

U uses B;
uses B,C ;
uses C,C;
uses id,C ;
uses id,id;

U
uses

B
B
C
id

67

;
C
id

Ing. Fco. Ros Acosta

68

Gramticas

friosam@prodigy.net.mx

Fig2.7 Derivaciones y arboles de parse para las sentencias representativas de la


instruccin uses en Turbo Pascal.
Ejemplo 2.12 Supongamos la declaracin de variables en Turbo Pascal, con slo
variables simples ( no arreglos , no registros ) de tipo integer, real y char. Entre las
sentencias representativas que podemos tomar en cuenta, se encuentran las siguientes :
(1)

var
i,j : integer;

(2)

var
x : real;
c,d : char;
k : integer;

En las sentencias observamos que :


(a)
Todas empiezan con el token var (palabra reservada),
(b)
El token de var es seguido de renglones.
De acuerdo a lo anterior tenemos :
D

D es el smbolo de inicio, y R es la variable


sintctica que genera las cadenas que hemos
denominado renglones.

var R

Dado que pueden existir ms de un renglones, las alternativas para el no terminal R


deben incluir al menos una regla recursiva.
D
R

var R
RI:T; | I:T;

El lenguaje generado por R es encontrado empleando derivaciones de la siguiente forma


:
R I : T;
R

// 1 rengln de declaraciones

I:T;

R I : T; I : T; I : T;
R

RI:T;

// 2 renglones

I:T;

R I : T; R I : T; I : T; I : T; I : T; I : T;
R

RI:T;

RI:T;

// 3 renglones

I:T;

...
R genera el lenguaje : ( I : T; ) n , n > 0. En todos los casos I representa a las
cadenas de identificadores separados por una coma y T es el no terminal que denota a
los tipos de datos.
I

I , id

I genera el lenguaje :

| id

id ( ,id ) n ,

LyA
68

n >= 0

Demustralo con
derivaciones !!!

Ing. Fco. Ros Acosta

69

friosam@prodigy.net.mx

Gramticas

y T genera :
T
char | integer | real
Juntando las producciones, tenemos la gramtica que especifica la declaracin de
variables pedida :
D
var R
(1)

RI:T; | I:T;

I , id

char | integer | real

(2)
(4)
(6)

(3)

| id
(5)
(7)

(8)

VT = { var , : , ; , , , id , char , integer , real }


VN = { D , R , I , T }
S = D
En la tabla de la fig. 2.8 tenemos las derivaciones a la izquierda para dos de las cadenas
representativas.
sentencia

derivacin

var
i,j : integer;

var
x : real;
c,d : char;
k : integer;

69

var R
var I : T;
4
var I,id : T;
5
var id,id : T;
7
var id,id : integer;
3

var R
var RI : T ;
var RI : T; I : T;
var I : T; I : T; I : T;
var id : T; I : T; I : T;
var id : real; I : T; I : T;
var id : real; I,id : T; I : T;
var id : real; id,id : T; I : T;
var id : real; id,id : char; I : T;
var id : real; id,id : char; id : T;
var id : real; id,id : char; id : integer;

Ing. Fco. Ros Acosta

70

friosam@prodigy.net.mx

Gramticas

Fig 2.8 Derivaciones para sentencias representativas : declaracin de variables en


Pascal.

Ejemplo 2.13

Encontrar la gramtica para la instruccin scanf( ) en lenguaje C.


Reconocer la lectura de arreglos n-dimensionales y que slo acepten en sus ndices
nmeros y variables; no expresiones. La especificacin de formatos debe reconocerse
slo como el token CteLit -constante literal cadena-.
Creo, que empezar
obteniendo las sentencias
representativas

LyA

sentencias representativas
(1)
(2)
(3)
(4)

scanf (%d,&iNum);
scanf (%f%d,pfReal, piEnt);
scanf (%s ,sCad);
scanf (%d %d %d,&x[i],piy[i],&z[4] [1][i]);

Todas las sentencias representativas tienen el prefijo comn : scanf (CteLit, seguido
de los identificadores que pueden presentarse en las formas :
& id
id
&id[ ]
id[ ]

direccin de una variable


apuntador a una variable
direccin del elemento de un arreglo
apuntador al elemento de un arreglo

La primera produccin es :

scanf ( CteLit , V ) ;

LyA

S es el smbolo de incio, y la no terminal V genera las cadenas para uno, dos o ms


identificadores.

70

Ing. Fco. Ros Acosta

71

Gramticas

friosam@prodigy.net.mx

V
V,I | I
El lenguaje generado por V es :
L (V) = { I ( ,I )n | n >= 0 }
Puede comprobarse con las derivaciones siguientes :
V I
// 1 identificador
V

V,I
V

I,I

V,I

// 2 identificadores

V,I,I
V

V,I

I,I,I
V

// 3 identificadores

El smbolo no terminal I produce directamente con reglas no recursivas, las diferentes


formas en que se presenta en la instruccin, un identificador de variable.
I
K
L

id | & id | id K | & id K
K[L] | [L]
id | num

La variable sintctica K produce las n dimensiones en el caso de lectura de arreglos.


K [L]
K

// 1 dimensin

[L]

K[L] [L][L]
K

K[L]

// 2 dimensiones

[L]

K[L][L]
K

K[L]

[L][L][L]
K

// 3 dimensiones

[L]

L (K) = { ( [ L ] ) n | n > 0 }

El lenguaje generado por K es :

Agrupando las producciones, obtenemos la gramtica G3 :


S

scanf ( CteLit , V ) ;
(1)

V,I | I

id | & id | id K | & id K

(2)
(4)

(3)
(5)

(6)

K[L] | [L]

id | num

(8)
(10)

...... ( G3 )

(7)

(9)
(11)

G(3) = ( { scanf , ( , ) , CteLit , , , ; , id , & , [ , ] , num } , { S , V , I , K , L } , S , }

71

Ing. Fco. Ros Acosta

72

friosam@prodigy.net.mx

Gramticas

La sentencia scanf (%d %c, &x[ i ][ 0 ], pcCar); es reconocida aplicando la siguiente


derivacin a la izquierda :
S 1
2

10

11

10

scanf (CteLit,V);
scanf (CteLit,V,I);
scanf (CteLit,I,I);
scanf (CteLit,&idK,I);
scanf (CteLit,&idK[L],I);
scanf (CteLit,&id[L][L],I);
scanf (CteLit,&id[id][L],I);
scanf (CteLit,&id[id][num],I);
scanf (CteLit,&id[id][num],id);

Precedencia y asociatividad de operadores. Recursividad a la


izquierda. Recursividad a la derecha.
En una instruccin de asignacin tal como x = 4 + 5 * 8, esperamos como resultado 44,
es decir, que primero se efecte el producto de 5*8 y luego la suma con 4. Lo anterior
debido, a que la prioridad de ejecucin de la multiplicacin y la divisin es ms alta, con
respecto a la resta y la suma. Adems, para la instruccin x = 3+6*4*2-10, la ejecucin
de la suma es primero que la ejecucin de la resta. Al efectuar la evaluacin de la
expresin, la computadora realiza las operaciones de izquierda a derecha.

Evaluacin de x = 3 + 6 * 4 * 2 - 10

LyA

Paso 1 : x = 3 + 48 - 10
Paso 2 : x = 51 - 10
Paso 3 : x = 41

// multiplicacin
// suma
// resta

Una gramtica que especifique una expresin, debe tomar en cuenta y representar en sus
producciones , la precedencia de ejecucin de los operadores que intervienen ya sean
aritmticos, relacionales, lgicos de otra naturaleza.
Por ejemplo, la gramtica para la instruccin de asignacin y expresiones aritmticas que
incluyen los operadores +, -, *, / es tpicamente escrita como :

72

Ing. Fco. Ros Acosta

73

Gramticas

friosam@prodigy.net.mx

(1) A
id = E
(2) E
E+T | E-T | T
.... ( G4 )
(3) T
T*F | T/F | F
(4) F
id | num
La sentencia x = 10 + y * z - 20 tiene el siguiente rbol de reconocimiento :
0

id

Un rbol de parse muestra de


manera clara, el orden en que las
operaciones se ejecutan !!

E
E

T * F

num

id

num

id

LyA

Observaciones :
(1) La asignacin de E a id en el nivel 1 del rbol, no se
puede realizar hasta que no se obtenga el valor de E .
(2) El valor de E en el nivel 1, se sabe hasta que se
efecta la resta E - T en el nivel 2.

LyA

(3) La resta en el nivel 2 E - T est sujeta a que se


obtenga el valor de E y ste, es sabido hasta que se
efecte la suma E + T en el nivel 3.
(4) La suma E + T asimismo, depende de que se realice
la multiplicacin T * F en el nivel 4.

Concluyendo :
id = E sujeta a E - T
E-T
sujeta a E + T
E + T sujeta a T * F

prioridad de ejecucin.

73

Ing. Fco. Ros Acosta

74

Gramticas

friosam@prodigy.net.mx

Pues como esperabamos, primero es realizada la multiplicacin, enseguida la suma y por


ltimo la resta, para luego ceder el paso a la asignacin !!.
Obviamente, antes de efectuarse una operacin, deben de producirse los operandos ya
sean id o bien num. De acuerdo a las observaciones anteriores, terminaremos
estipulando, que las operaciones con menos prioridad ocupan las producciones ms
cercanas (en derivacin) a la primera produccin -regla que contiene al smbolo de
inicio-. Por ejemplo, la suma y resta ocupan el 2o. nivel despus de la primera
produccin y sus reglas estn etiquetadas con el (2) en la gramtica G4. Le siguen las
operaciones de multiplicacin y divisin cuya prioridad es mayor, terminando con las
producciones
F
id y F num , etiquetadas con el (3) y (4) en G4, respectivamente. Lo
anteriormente dicho no es una regla, pero es til su conocimiento.
La ejecucin de las operaciones se realiza de izquierda a derecha. Esto es logrado,
gracias a que las reglas recursivas han sido escritas con la recursividad a la izquierda.

Recursividad
a la izquierda ?!!
LyA

Observemos las producciones para los smbolos no terminales E y T de la gramatica G4.


E
T

E+T | E-T | T
T*F | T/F | F

Las reglas o alternativas recursivas son :


E

E+T

E-T

74

T*F

T/F

Ing. Fco. Ros Acosta

75

Gramticas

friosam@prodigy.net.mx

Recursividad a la izquierda
La recursividad aparece a la izquierda de

Podemos escribir
estas reglas recursivas, conservando la recursividad a la derecha, tal y
la alternativa.
como lo mostramos enseguida :
(1)
(2)
(3)
(4)

A
E
T
F

id = E
T+E | T-E | T
F*T | F/T | F
id | num

.... ( G5 )

Recursividad
a la derecha ?!!

La misma gramtica G4
pero con .....

recursividad a la derecha !!

LyA

Veamos que sucede al obtener el rbol de parse para la sentencia x = 10 + y * z - 20,


utilizando las producciones de G5.
0

id

num

T -

F * T

id

F F
id

num

Se conserva la precedencia de la multiplicacin


sobre la suma y la resta, pero ... se efecta
primero la resta que la suma !!!

LyA

Es decir, la ejecucin se realiza de derecha a izquierda.


x = 10 + y * z - 20
75

ejecucin

Ing. Fco. Ros Acosta

76

Gramticas

friosam@prodigy.net.mx

Exite un ejemplo tpico de la aplicacin de la recursividad a la derecha. Supongamos


que deseamos obtener la gramtica para especificar la instruccin de asignacin
transitiva en el lenguaje de programacin C. En la sentencia a = b = c = 0; el cero es
asignado a la variable c, luego el valor de c es asignado a b y por ltimo el valor de b es
asignado a a. Es decir, la operacin de asignacin es realizada de derecha a izquierda. El
operador = es asociativo a la derecha. Un operador asociativo a la derecha se asocia u
opera, sobre el operando situado a su izquierda. Un operador asociativo a la izquierda se
asocia u opera, sobre el operando situado a su derecha. Son ejemplos de operadores
asociativos a la izquierda : +, -, *, /.
En la sentencia - x + y ,
el - opera sobre la x
y el + opera sobre la y.
LyA

En nuestro ejemplo a = b = c = 0; el operador = (3) se asocia a la c, el operador = (2)


opera sobre la b y el operador = (1) se asocia a la a.
La escritura de una regla que incluye operadores asociativos a la derecha, utiliza la
recursividad a la derecha. As, el conjunto de producciones para la gramtica de la
asignacin transitiva es :
A
L

id = L
id = L | num

..... (G6)

G6 = ( { id , = , num } , { A , L } , A , )
El rbol de parse para la sentencia a = b = c = 0 es el siguiente :
A

0
1

id

L
2
id

L
3

76

Ing. Fco. Ros Acosta

77

id

Gramticas

friosam@prodigy.net.mx

L
4
num

La asignacin del nivel 3 es la primera en efectuarse. Enseguida se realizan las


asignaciones del nivel 2 y 1 en ese orden. Se respeta la ejecucin de derecha a
izquierda.
Operadores asociativos a la izquierda ....

Reglas con recursividad


a la izquierda.

LyA

Operadores asociativos a la derecha ....

Reglas con recursividad


a la derecha.
Ejemplo 2.14
(a)
(b)

La gramtica G4 no puede derivar las sentencias :

x=-5* y
x = x * ( y+ 2 )

La sentencia (a) involucra al operador menos en su modalidad de monario (generalmente


es binario). La multiplicacin se realiza slo hasta que se haya asociado el menos al
nmero 5. Lo anterior quiere decir que el operador monario menos tiene mayor
precedencia que la multiplicacin (operador *). La modificacin a la gramatica G4 debe
efectuarse en el nivel siguiente a donde se encuentran las producciones para el producto
(*) y la division (/), es decir, en las producciones del no terminal F. A continuacin se
muestra la modificacin a G4 que permite reconocer las sentencias tipo (a).
A
id = E
E
E+T | E-T | T
T
T*F | T/F | F
F
id | num | - E
El rbol de parse para la sentencia x = - 5 * y, indica que primero se efecta la
asociacin del signo menos al numero 5 para enseguida dar paso a la multiplicacin por
y.
0
1

A
id

F
id

Para efectuar el producto en el nivel 3, es


necesario saber el valor de F en el nivel 4,
y F se sabe slo hasta que se haya realizado
77 la asociacin del signo - a la expresin E
del nivel 5. La expresin E del nivel 5 es el
token num.

Ing. Fco. Ros Acosta

78

friosam@prodigy.net.mx

Gramticas

num

Para la sentencia (b) x = x* ( y+2) se aplica el mismo razonamiento. Las expresiones


encerradas entre parntesis deben evaluarse antes que las dems, es decir, tienen ms alta
precedencia que las operaciones suma, resta, multiplicacin y divisin. Por lo anterior,
agregamos la modificacin en las producciones para F.
A
E
T
F

id = E
E+T | E-T | T
T*F | T/F | F
id | num | - E | ( E )

......

( G7 )

El rbol de parse para las sentencias del ejemplo (b) es :


0

id

id

num

id

Orden de ejecucin :
78

1o. Suma en el nivel 5


2o. Producto en el nivel 3

Ing. Fco. Ros Acosta

79

friosam@prodigy.net.mx

Gramticas

Notacin de Backus Naur ( BNF ).


Esta notacin establece las siguientes reglas para representar gramticas :
1. El smbolo ::= significa es definido por y se utiliza en lugar del smbolo

2. Los smbolos no terminales -variables sintcticas- se denotan delimitndolos con los


smbolos < y > . Por ejemplo el smbolo no teminal E se denota como < E >. Los
smbolos terminales no son delimitados por ningn smbolo.
3. Las reglas recursivas que nos permiten expresar la repeticin de cierto patrn en las
cadenas de un lenguaje se escriben en forma muy diferente. La repeticin en la notacin
BNF es expresada utilizando los smbolos { y }. Por ejemplo {x} significa la repeticin
de cero o ms ocurrencias de x. {x}0n indica la repeticin de cero hasta n ocurrencias
de x . Cuando se omite el lmite inferior en las repeticiones, el valor por default es 0. Por
ejemplo { x } n denota las cero hasta n ocurrencias de x.
4. El uso de los smbolos [ y ] indican cero o una ocurrencia. [ x ] denota cero o una
ocurrencia de x. [ x ] es equivalente a { x }1 .
5. El uso de los parntesis ( y ) denota la agrupacin de alternativas .
<A> ::= <B> <C> <B> <D>
se agrupan en :
<A> ::= <B> (<C> <D>)
6. Una cadena que represente a un smbolo terminal -token- puede escribirse entre
apstrofes.
Por ejemplo :

79

80

Ing. Fco. Ros Acosta

friosam@prodigy.net.mx

Gramticas

<R> ::= read | readln | read ( <P> ) | readln ( <P> )


<P> ::= <P> , id | id
Los tokens ( y ) se encerraron entre apstrofes, ya que puede existir confusin debido a
que tambin son usados para indicar agrupacin de alternativas. La coma y el id son
tokens asi como el read y readln.

Ejemplo 2.15 Convierte a la notacin BNF la gramtica del ejemplo 2.12.


D
R
I
T

var R
RI:T; | I:T;
I , id | id
char | integer | real

Aplicamos los estatutos 1 y 2 :


(1) <Declaracin>
(2) <Rengln>

::= var <Rengln>


::= <Rengln> <ListaIdentificador> : <Tipo> ; |
<ListaIdentificador> : <Tipo> ;
(3) <ListaIdentificador> ::= <ListaIdentificador> , id | id
(4) <Tipo>
::= char | integer | real
Notemos que los tokens no los hemos denotado entre apstrofes, ya que no es necesario
debido a que no puede haber ningn tipo de confusin.
La gramtica puede quedar escrita de la anterior manera en la notacin BNF. Sin
embargo podemos aplicar a las reglas recursivas, la notacin BNF para la repeticin
(estatuto 3) .
La recursividad se presenta en la definicin de < Rengln > y < Lista Identificador >.
La gramtica en notacin BNF despus de aplicar el estatuto 3 es :
(1) <Declaracin>
(2) <Rengln>

::= var <Rengln>


::= <ListaIdentificador> : <Tipo> ;
{ <ListaIdentificador> : <Tipo> ; }
(3) <ListaIdentificador> ::= id { , id }
(4) <Tipo>
::= char | integer | real

80

Ing. Fco. Ros Acosta

81

Dnde qued la recursividad de las producciones


Gramticas
(2) y (3) ? ...

friosam@prodigy.net.mx

En la notacin { x } de repeticin !!!

LyA

Ejemplo 2.16 Tomemos la gramtica G7 para la asignacin, citada en el ejemplo


2.14.
A
E
T
F

id = E
E+T | E-T | T
T*F | T/F | F
id | num | - E | ( E )

......

( G7 )

Hagamos la conversin a notacin BNF, aplicando primeramente los estatutos 1 y 2 :


(1) <Asignacin> ::= id = <Expresin>
(2) <Expresin> ::= <Expresin> + <Trmino> |
<Expresin> - <Trmino> |
<Trmino>
(3) <Trmino> ::= <Trmino> * <Factor> |
<Trmino> / <Factor> |
<Factor>
(4) <Factor>
::= id | num | - <Expresin> | ( <Expresin> )
El estatuto 6 es necesario aplicarlo a la produccin para <Factor> (Produccin 4), ya
que el uso de parntesis sin apstrofes en la notacin BNF tiene un significado especial
-agrupacin de alternativas-.
Bueno, y que no vamos
a denotar la recursividad
en (2) y (3) por medio de
la repeticin en BNF ?

LyA

Claro que s, el estatuto 3 es legalmente funcional en (2) y (3). La notacin BNF de la


gramtica se transforma a :
(1) <Asignacin> ::= id = <Expresin>
(2) <Expresin
::= <Trmino> { + <Trmino> } | <Trmino> { - <Trmino> }
(3) <Trmino>
::= <Factor> { * <Factor> } | <Factor> { / <Factor> }
81

Ing. Fco. Ros Acosta

82

(4) <Factor>

Gramticas

friosam@prodigy.net.mx

::= id | num | - <Expresin> | ( <Expresin> )

Vaya !!, es interesante cmo la


recursividad ya no es tan obvia
usando la notacin BNF.

LyA

La gramtica an acepta otra forma en su notacin BNF. Las producciones (2) y (3) son
susceptibles al estatuto 5, es decir, a la agrupacin de alternativas.
(1)
(2)
(3)
(4)

<Asignacin>
<Expresin>
<Trmino>
<Factor>

::=
::=
::=
::=

id = <Expresin>
<Trmino> ( { + <Trmino> } | { - <Trmino>} )
<Factor> ( { * <Factor> } | { / <Factor> } )
id | num | - <Expresin> | ( <Expresin> )

Las producciones (2) y (3) siguen aceptando la agrupacin


de alternativas. La agrupacin se muestra enseguida.
(1)
(2)
(3)
(4)

<Asignacin>
<Expresin>
<Trmino>
<Factor>

::=
::=
::=
::=

id = <Expresin>
<Trmino> { ( + | - ) <Trmino> }
<Factor> { ( * | / ) <Factor> }
id | num | - <Expresin> | ( <Expresin> )

Ejemplo 2.17 Obtener la notacin BNF para la gramtica escrita en el ejemplo

2.13 (instruccin de lectura scanf), cuyo conjunto de producciones se lista enseguida.


(1)
(2)
(3)
(4)
(5)

S
V
I
K
L

scanf ( CteLit , V)
V,I | I
id | &id | idK | &idK
K[L] | [L]
id | num

La gramtica se modifica en su notacin de la siguiente forma :


(1)
(2)
(3)
(4)

Aplicamos los
estatutos 1 y 2.

<InstrLectura> ::= scanf ( CteLit , <ListaDatos> )


<ListaDatos> ::= <ListaDatos> , <Dato> | <Dato>
<Dato>
::= id | &id | id <Dimensin> | &id <Dimensin>
<Dimensin>
::= <Dimensin> [ <Indice> ] | [ <Indice> ]

82

Ing. Fco. Ros Acosta

83

(5) <Indice>

Gramticas

friosam@prodigy.net.mx

::= id | num

Los smbolos ( , ) , [ , ] se han delimitado


con apstrofes. El estatuto 6 ha sido
empleado pues podran confundirse estos
smbolos con la agrupacin de alternativas
LyA
la notacin
estatuto
4.
Ahora, sustitumos las alternativas y
recursivas
por ladel
notacin
de repeticin
en BNF.
(1)
(2)
(3)
(4)
(5)

<InstrLectura>
<ListaDatos>
<Dato>
<Dimensin>
<Indice>

::=
::=
::=
::=
::=

scanf ( CteLit , <ListaDatos> )


<Dato> { , <Dato> }
id | &id | id <Dimensin> | &id <Dimensin>
{ [ <Indice> ] } 1
id | num

El estatuto 3 ha sido utilizado en las


producciones (2) y (4). La notacin
en <Dimensin> indica una o ms
repeticiones !!!

LyA

Veamos ahora las producciones que cumplen las condiciones para el empleo del estatuto
5.
(3) <Dato> ::= id | &id | id <Dimensin> | &id <Dimensin>
*

Se observa que las alternativas marcadas con asterisco (*) coinciden en el prefijo id, y
las alternativas marcadas con el smbolo de admiracin (!) tienen &id como prefijo
comn. Agrupemos estas alternativas ayudndonos de los estatutos 5 y 4 .
<Dato> ::= id [ <Dimensin> ]

| &id [ <Dimensin> ]

<Dato> ::= ( id | &id ) [ <Dimensin> ]

An puede aplicarse otra


simplificacin en el
primer trmino :
( id | &id )

Se aplica el estatuto 4 :
[x] 0 o una ocurrencia

<Dato> ::= [ & ] id [ <Dimensin> ]

83

Ing. Fco. Ros Acosta

84

Gramticas

friosam@prodigy.net.mx

Por ltimo escribimos la gramtica resultante en notacin BNF.


<InstLectura> ::= scanf ( CteLit , <ListaDatos> )
<ListaDatos> ::= <Dato> { , <Dato> }
<Dato>
::= [ & ] id [ <Dimensin> ]
<Dimensin>
::= { [ <Indice> ] } 1
<Indice>
::= id | num

2.5 EJERCICIOS PROPUESTOS.


1. Dadas las siguientes gramticas, obtener sus componentes, Vt, Vn, S y :
a) S
L

(L) | a
L,S | S

c) R
P
Q
S

readln | readln ( P )
P,Q | Q
id | id [ S ]
S,T | T
id | num

b) S
Aa | bAc | Bc | bBa
A d
B d
2. Encuentra el lenguaje generado por las siguientes gramticas :
(a) S

aSb | ab

(b) S
A

aSd | aAd
bAc | bc

(c)

S
A
B

AB
aAb | ab
cBd | cd

(d)

0S1 | 01

(e)

S
S
bB
bC
CB
cC

aSBC
abC
bb
bc
BC
cc
84

Ing. Fco. Ros Acosta

85

(f) A
A0
A1
0B0
1B1
(g) K
T

A0B0 | A1B1
1
0
1
0
K,T | T
num

(h) S

(S)S |

friosam@prodigy.net.mx

Gramticas

(i)

S
ccc
S
Abccc
A
Ab
A
aBa
B
aBa
B
AC
C
Cb
C
b
3. Modificar la gramtica del ejemplo 2.12 para que en adicin especifique tipos
subrango y tipos string [ ].
var
i,j
subrango
limite
sNombre

: integer;
: 1 .. MAX;
: MIN .. 40;
: string [40];

4. Escribe la gramtica para especificar el encabezado de :


a) Una funcin en C. Los tipos son void, int, char, float y apuntadores a ellos.
b) Una funcin en Pascal. Los tipos aceptados son integer, char, real. El pasaje de
parmetros por valor y por referencia.
c) Un procedure en Pascal. Los tipos y pasaje de parmetros igual que el inciso b).
5. Encuentra la derivacin y el rbol de parse para las sentencias :
readln ( i , j , x [ i ,j ] )
readln ( x [ 3 ] , y [ i,j ] , z )

85

86

Ing. Fco. Ros Acosta

friosam@prodigy.net.mx

Gramticas

utilizando la gramtica del ejercicio 1 c).


6. Escribe la gramtica para la instruccin puts en lenguaje C. Recuerda que puts
escribe una cadena en la pantalla.
puts ( HOLA );
puts ( sCad [ 1 ] [ 5 ] );
puts ( sCad [ i ]);
puts ( sLinea);
7. Escribe la gramtica para el printf en C. Los especificadores de formato no los toma
en cuenta, es decir, el token CteLit (Constante literal o cadena) ya los considera. En la
lista de datos a escribir aceptar slo identificadores simples, apuntadores y arreglos.
printf ( HOLA \ n );
printf ( % d % f , i , *x );
printf ( % f , y [ 0 ] [ i ] );
8.
9.

El encabezado del FOR en Pascal.


Convierte a notacin B.N.F. las gramticas obtenidas en los ejercicios 4, 5, 6, 7
y 8.

10. Escribe la gramtica para la declaracin de tipos definidos por el usuario en


Pascal. Incluye los arreglos de n dimensiones en notacin array [ 1 .. 10 , 1 .. max ].

86

También podría gustarte