Académique Documents
Professionnel Documents
Culture Documents
aticas Formales
Lenguajes de Programacion
Primavera 2015
Repartido 1
Tasistro
A.
1. La noci
on de gram
atica formal. Gram
atica, en Ling
ustica, es la teora o descripcion (en intenci
on)
completa de un idioma:
1. La enumeraci
on de los sonidos empleados en el idioma (Fonetica).
2. Las reglas de las combinaciones de sonidos permitidas (Fonologa).
3. Los patrones de formaci
on de palabras (Morfologa).
4. Las reglas de escritura de las palabras (Ortografa).
5. Las reglas de formaci
on de las oraciones (Sintaxis).
6. El estudio del significado de las expresiones del idioma (Semantica).
Noam Chomsky, ling
uista estadounidense, propuso, a partir de un trabajo de 1956, estudiar sistemas de reglas
que permitieran generar todas las oraciones del idioma ingles y solo a ellas (es decir, una version generativa
de la sintaxis del ingles). Su propuesta general era, por lo tanto, la de estudiar sistemas de generaci
on
de ciertas secuencias (strings) o, en otras palabras, de definiciones inductivas de conjuntos de strings. Los
sistemas dados en un comienzo por Chomsky son las ahora denominadas gram
aticas formales. Adem
as de
su aplicaci
on en Ling
ustica, poseen muchas otras. Para dar apenas dos ejemplos: la especificacion de la
sintaxis de lenguajes de programaci
on y otros lenguajes artificiales, y la especificacion de secuencias de notas
o acordes musicales y por lo tanto de (sub)lenguajes de la m
usica.
2. Gram
aticas libres de contexto.
as natural de gramatica formal es, no muy sorprendemente, la definici
on de
Intuici
on. El ejemplo m
categoras sint
acticas de los idiomas, aqu en una version muy incompleta:
Oraci
on Sujeto Verbo Objeto
Sujeto Artculo Nombre
Objeto Artculo Nombre
Verbo . . .
Artculo . . .
Nombre . . .
Los ingredientes de la gram
atica son:
1. Categoras sint
acticas. Cada una es una clase o conjunto de strings. Hay un n
umero finito de categoras.
2. Reglas que especifican la formaci
on de los strings pertenecientes a cada categora. Por ejemplo, la
primera regla del ejemplo se lee como sigue: una oraci
on puede ser una secuencia formada por un
sujeto, un verbo y un objeto. Hay un n
umero finito de reglas y, en general, habra mas de una regla
para una misma categora, proveyendo distintas alternativas de formacion de strings de esa categora.
Todas las formas posibles de cada categora quedan dadas (cerradas) por el conjunto de reglas (es decir,
se trata de una definici
on inductiva).
3. Arboles
de reconocimiento. Es una especificacion en forma de arbol de la evidencia de que un string
pertenece al conjunto generado. Como toda evidencia, provee tambien (cierta) comprension. Por
ejemplo, el siguiente
arbol para La lava lava la ladera permite entender como se arma esa oraci
on
y que rol juega cada una de sus palabras:
Oraci
on
Sujeto
Verbo
Objeto
la
lava lava la
ladera
Los
arboles de reconocimiento son tambien llamados de reconocimiento sint
actico o de parsing y
tambien de derivaci
on. N
otese c
omo pueden ser usados para reconocer (ingles: to parse) al string
de palabras como una oraci
on v
alida:
(a) Leyendo el
arbol de arriba hacia abajo (top-down) uno realiza una derivacion que finalmente
produce el string en cuesti
on. En cada nodo del arbol se aplica una regla de la gramatica. S
olo
al final uno reconoce el rol de cada palabra del string.
(b) Leyendo el
arbol de abajo hacia arriba (bottom-up), uno inmediatamente es informado del rol de
cada palabra y al final reconstruye la manera en que ellas forman la oracion.
4. Palabras como la, lava, ladera son las unidades atomicas con las que se forman las oraciones. En
terminos ling
usticos, conforman lo llamaramos el lexico del idioma.
Una gram
atica simple. Consideremos ahora el conjunto de strings {an bn | n 0}. Se usa la siguiente
n
notaci
on: es la concatenaci
on n veces de , para cualquier string . La primera cosa a observar es
que el lexico en este caso est
a dado por los dos smbolos a y b. Se trata de hecho de un ejemplo de un
conjunto de strings de naturaleza muy diferente a la de un idioma. La tradicion ha mantenido sin embargo,
para todos los casos, una terminologa emparentada con la Ling
ustica: se dice que una gramatica genera
un lenguaje; a los miembros del lenguaje (los strings en cuestion) se los llama a veces sus frases y tambien
sus palabras. (Por ejemplo frase parece mas apropiado para cada uno de los miembros del lenguaje de
nuestro primer ejemplo, en tanto este segundo ejemplo de lenguaje parece mas naturalmente descripto como
formado por palabras; pero es claro que la eleccion no debe ser relevante para establecer las propiedades y
transformaciones que nos interesan.) Los componentes finales de las palabras o frases (es decir, lo que antes
intuitivamente asociamos al lexico de un idioma) son llamados uniformemente los smbolos terminales del
lenguaje y de la gram
atica. La siguiente gramatica genera el lenguaje que estamos considerando:
S
S aSb.
Observamos que en la primera regla aparece a la derecha un smbolo que no es uno de los terminales. El
punto es que esa regla tiene por fin introducir el string vaco, que efectivamente pertenece al conjunto a
un
generar (tomando n = 0 en {an bn | n 0}). El string vaco esta conformado, obviamente, por ning
smbolo, por lo que, para denotarlo, es necesario un metasmbolo, uno que no vaya a ser utilizado jam
as
es, precisamente, el rol de . De modo que la primera regla se lee: una palabra
como smbolo terminal. Ese
del lenguaje (llamemos a este S) puede ser vaca, lo cual es correcto. La segunda regla, en tanto, establece
que una palabra del del lenguaje S puede ser (tambien) un string formado por una a, seguida de una palabra
(ya formada) del mismo lenguaje, seguida de una b. No hay otras reglas, de modo que todas las palabras del
lenguaje son las generadas de esas dos maneras. Se trata de una generacion inductiva de un cierto conjunto
de strings caracterizado ya de antemano. La segunda regla funciona como un generador recursivo, y de esta
manera se logra tener un dispositivo finito para generar un conjunto infinito.
Naturalmente, es perfectamente posible establecer principios de inducci
on y de recursi
on asociados a
cada gram
atica, que permitan, respectivamente, demostrar propiedades de todas las palabras del lenguaje
2
generado y definir funciones sobre este. Por ejemplo en este caso, para demostrar que toda palabra de S
cumple una propiedad dada P es suficiente demostrar:
1. P .
2. P (ab), suponiendo que es una palabra de S para la cual vale P.
?1. Demostrar que la gram
atica precedente es correcta respecto de la caracterizacion dada, es decir, respecto
de {an bn | n 0}. Para ello:
1. Demostrar que la gram
atica es s
olida; es decir, que toda palabra de S es de la forma an bn para alg
un
n (demostrar que son todos los que estan).
2. Demostrar que la gram
atica es completa; es decir, que toda palabra de la forma an bn es generada por
la gram
atica (demostrar que est
an todos los que son).
on alternativa para las reglas es la llamada Backus-Naur Form (BNF). En
La notaci
on BNF. Una notaci
esta notaci
on todas las reglas para la misma categora sintactica se escriben como alternativas en una misma
cl
ausula, separadas por |. Se utiliza adem
as el smbolo ::= en lugar de . Por ejemplo el caso precedente
se escribe en BNF de la siguiente manera:
S ::= | aSb.
arbol
Ambig
uedad. Dado un lenguaje por una gramatica, podra ocurrir que un string tuviera mas de un
de reconocimiento, es decir, m
as de una manera de ser entendida como frase del lenguaje. Un ejemplo en
castellano es Arriba como papa, donde el verbo puede ser Arriba o puede ser como.
En tal caso decimos que la frase y el lenguaje todo son ambiguos. La ambig
uedad es bienvenida en el idioma natural porque, usando el contexto (implcito) en el que las manifestaciones tienen lugar, uno puede
expresarse econ
omicamente. En contrapartida, la ambig
uedad es intolerable en los lenguajes de programaci
on: considerese por ejemplo un lenguaje en el que exista un operador max que calcule el maximo de
dos n
umeros y se escriba de manera infija. Entonces como debe calcularse x + y max z? Es, para mayor
inconveniencia, indecidible el problema de determinar si una gramatica dada es o no ambigua, con lo cual
la (no) ambig
uedad es algo que el dise
nador del lenguaje debe vigilar especficamente. En breve veremos
ejemplos donde la situaci
on se presenta de manera natural.
El caso de los lenguajes de programaci
on. Al contrario que los idiomas, los lenguajes de programaci
on
son notaciones artificiales, empleadas para expresar datos y computaciones. Consideremos, para empezar,
expresiones aritmeticas: Una manera natural de introducirlas es mediante un tipo inductivo de
arboles,
determinado por constructores apropiados. En Haskell:
data Expr =
Lit Int
| Sum Expr Expr
| Minus Expr Expr
| Prod Expr Expr
| Div Expr Expr.
Esta especificaci
on es llamada la sintaxis abstracta del lenguaje de expresiones aritmeticas en cuestion. En
cambio, una gram
atica que especifique strings que representen esos arboles se denominara una sintaxis
concreta del mismo lenguaje. En otras palabras, las sintaxis abstractas especifican objetos como arboles
de un cierto tipo inductivo, mientras las sintaxis concretas definen una notacion lineal para los arboles en
cuesti
on. Existen en general m
ultiples maneras de linealizar una sintaxis abstracta. Antes de empezar a
recorrer algunas variantes, digamos que (los arboles de) las sintaxis abstractas se expresan a veces tambien
en notaci
on BNF. Por ejemplo la precedente se escribe habitualmente como sigue:
Expr ::=
l
| Expr + Expr
| Expr Expr
| Expr Expr
| Expr Expr,
3
entendiendose que l representa un literal entero, por ejemplo (y usualmente) en notacion decimal con signo.
Es muy importante que la definici
on precedente sea acompa
nada por la aclaracion de que se trata de una
sintaxis abstracta, es decir, de
arboles y no de strings. Si se tratara de una sintaxis concreta, sera ambigua:
?2. Interpretando la sintaxis precedente como concreta, mostrar strings ambiguos con sus m
ultiples arboles
de derivaci
on.
La siguiente es la linealizaci
on del lenguaje Expr empleada por la funcion show estandar de Haskell,
expresada en BNF:
E ::=
Lit l
| Sum (E) (E)
| Minus (E) (E)
| Prod (E) (E)
| Div (E) (E).
Aqu consideramos como smbolos terminales a Lit, Sum, Minus, Prod, Div, los parentesis, y los literales
enteros l. Deberamos ahora convencernos de que la gramatica no es ambigua. Esto implica demostrar que
para cada frase del lenguaje existe un u
nico arbol de derivacion, o sea una u
nica manera de generar o derivar
la frase en cuesti
on. Comenzamos observando que para cada frase del lenguaje existe una u
nica alternativa en
la gram
atica siguiendo la cual la frase se ha formado. Esa alternativa queda determinada por el terminal con
el que la frase comienza, que es necesariamente uno de Lit, Sum, Minus, Prod, y Div. Una vez determinada la
alternativa en cuesti
on, el resto de la frase es directamente un terminal l (en el caso Lit) o se descompone de
forma u
nica en dos frases (expresiones), a las cuales se puede aplicar recursivamente el mismo razonamiento
que estamos efectuando. Que la descomposicion mencionada es u
nica puede verse considerando que la
primera sub-expresi
on es la comprendida entre el primer parentesis izquierdo y aquel parentesis derecho que
le corresponde; y similarmente para la segunda subexpresion. O sea que para identificar estas subexpresiones
uno debe poder determinar cu
al es el parentesis que cierra al que abre cada subexpresion. Que esto u
ltimo
es posible se sigue a su vez de la inmediata observacion de que el n
umero de parentesis izquierdos y derechos
en cada frase del lenguaje es el mismo. O sea que el algoritmo para determinar el parentesis que cierra es
sencillo y seguramente ha sido ya empleado reiteradamente por el lector: se recorre la expresion de izquierda
a derecha llevando la cuenta del desbalance a favor de los parentesis izquierdos, la cual comienza en 1.
Cuando esa cuenta se haga cero se habr
a encontrado el parentesis derecho buscado. Finalmente, la recursi
on
o razonamiento inductivo que estamos realizando es bien fundada: tiene su caso base, correspondiendo con
el caso Lit; y los strings sobre los que se razona recursivamente son mas cortos que el original.
?3. En que aspectos falla el razonamiento precedente cuando se intenta aplicar a la sintaxis concreta ambigua
considerada en el ejercicio ?2?
La notaci
on precedente es prefija, puesto que cada operador binario es colocado precediendo a sus operandos. La sintaxis prefija hace de hecho innecesario el uso de parentesis:
?3. Mostrar (convencerse de) que la siguiente gramatica es no ambigua:
E ::=
l
| +EE
| EE
| EE
| E E.
(Sugerencia: ning
un prefijo propio de una E es una E.)
Lo mismo ocurre con la notaci
on postfija:
?4.
1. Escribir la gram
atica de la versi
on postfija del lenguaje precedente.
2. Convencerse de que no es ambigua.
Sin embargo, la notaci
on tradicional y preferida para expresiones aritmeticas es la infija, y como se ha
visto, su formulaci
on ingenua conduce a un lenguaje ambiguo. Una solucion es usar sistematicamente
parentesis para marcar el orden en que las subexpresiones deben ser consideradas como, por ejemplo, en
(((14 + 4) (8 3)) + (21 + 11)):
?5.
1. Escribir una gram
atica para la versi
on infija de las expresiones aritmeticas en la que cada aplicaci
on
de un operador (binario) este parentizada, como en el ejemplo precedente.
2. La siguiente gram
atica evita los parentesis exteriores redundantes de la precedente; pero a que precio?
E ::= l | (E) Op (E)
Op ::= + | | | .
3. Pueden ser evitados ambos inconvenientes?
Es natural procurar evitar el uso obligatorio de parentesis en cada aplicacion de un operador binario infijo.
La soluci
on cl
asica y bien conocida consiste en establecer un orden de precedencia entre los operadores. As
pues, 12+35 es una suma, en la que se debe realizar primero el producto 35 aunque figure mas a la derecha
y no se encuentre entre parentesis. La convencion especifica tambien el orden en que se deben considerar
los operadores de la misma precedencia; por ejemplo en 3 + 4 2 lo usual es considerar los operadores en el
orden en que aparecen de izquierda a derecha en la expresion, lo cual es equivalente a decir que, en el caso
de tales secuencias, se asocia a la izquierda. La siguiente gramatica establece esas convenciones usuales de
precedencia y asociaci
on, permitiendo el ahorro de parentesis:
E0 ::= E0 + E1 | E0 E1 | E1
E1 ::= E1 E2 | E1 E2 | E2
E2 ::= l | (E0).
Observando la primera cl
ausula, vemos que una E0 es una secuencia de sumas y restas armada, como es l
ogico,
recursivamente. Que la recursi
on se realice a la izquierda en cada uso de + y tiene como consecuencia
que las sumas y restas del operando izquierdo deban componerse primero y por lo tanto impone que la
asociaci
on se realice a la izquierda. O, dicho de otro modo, que las sumas y restas se vayan aplicando
(formando) de izquierda a derecha. De hecho, la manera apropiada de entender esta gramatica (y cualquier
otra) es visualizando los
arboles de derivacion que van quedando definidos. La clausula primera en este
caso define arboles cuyos nodos (operadores) principales son + y . Pensando en la computacion de las
expresiones como
arboles, uno comprende que el operador principal es el u
ltimo a ser aplicado. Los que
aparezcan en niveles inferiores del
arbol tendran por lo tanto una precedencia o prioridad mayor. Entonces
en particular, por obra de la recursi
on a la izquierda, las sumas y restas apareceran con precedencia mayor
(o sea, en los niveles m
as inferiores del
arbol) cuanto mas a la izquierda aparezcan en el string original.
Por otro lado, los componentes de las secuencias E0 de sumas y restas son a su vez secuencias de productos
y cocientes. En otras palabras, las expresiones principales (E0) son sumas y restas de productos y cocientes.
Esto quiere decir que los segundos ser
an computados primero cuando las expresiones sean interpretadas.
Finalmente, los componentes u
ltimos de las expresiones son los simples literales o expresiones completas
escritas entre parentesis. Estos u
ltimos componentes seran los primeros a ser evaluados y as vemos c
omo
el uso de parentesis efectivamente provee una prioridad superior a la correspondiente expresion, de acuerdo
con la sem
antica usual.
?6. Escribir los
arboles de derivaci
on de 3 + 41 5 8 y de (4 + 3) 8 9.
Arboles
de derivaci
on vs. Arboles
de Sintaxis Abstracta. En la seccion anterior partimos de la especificaci
on de expresiones por medio de un tipo inductivo, a saber:
data Expr =
Lit Int
| Sum Expr Expr
| Minus Expr Expr
| Prod Expr Expr
| Div Expr Expr,
y afirmamos que las diferentes sintaxis concretas no eran sino linealizaciones de este tipo. Que significa esta
afirmaci
on? Bueno, para empezar, que cada frase de cada una de las sintaxis concretas mostradas puede
asociarse a un (
unico)
arbol del tipo Expr sin perder informacion. Naturalmente, esto puede ser realizado
caso a caso. Consideremos por ejemplo la gramatica prefija introducida arriba:
E ::=
l
| +EE
| EE
| EE
| E E.
Sabemos que todo string bien formado de esta gramatica puede descomponerse en una de las cinco formas
all enumerada. De hecho, la descomposici
on es u
nica por ser la gramatica no ambigua. Entonces la siguiente
especificaci
on es suficiente para calcular el arbol de sintaxis abstracta de cada string del lenguaje:
ast l = Lit l
ast (+ e1 e2 ) = Sum (ast e1 ) (ast e2 )
ast ( e1 e2 ) = Minus (ast e1 ) (ast e2 )
ast ( e1 e2 ) = Prod (ast e1 ) (ast e2 )
ast ( e1 e2 ) = Div (ast e1 ) (ast e2 ).
All usamos l para denotar el valor de tipo entero (Int) representado por el literal numerico (string) l.
?8.
1. Programar una funci
on que a cada expresion lineal de la version postfija asocie su arbol de sintaxis
abstracta. (Proceder por recursi
on en la gramatica.)
on est
an ligados a las gramaticas (sintaxis concretas) y contienen informacion relevante
a ellas (concretamente, a las derivaciones). En el caso de los lenguajes de programacion, gran parte de esa
informaci
on no es relevante.
Definiciones. Pasando en limpio, una gramatica libre de contexto1
que:
la secci
on subsiguiente aclararemos esta calificaci
on.
la notaci
on para el conjunto de strings cuyos smbolos pertenecen a . Cuando se trata de los strings no vacos
se usa la notaci
on + .
2 Usamos
P es un conjunto finito de reglas de la gramatica, llamadas producciones. Cada produccion es una pareja
A formada por un no terminal A y un string cuyos smbolos pueden ser tanto terminales como
no terminales. (Es decir, P N (N T ) .)
S es el no terminal principal (categora sintactica que corresponde al conjunto del lenguaje).
El lenguaje generado (definido, especificado) por una gramatica G = (N, T, P, S) es el conjunto de strings
de terminales a los que se llega comenzando desde el smbolo no terminal principal S y sustituyendo en cada
paso un no terminal A por , siendo A una regla de P . Formalmente:
Una reescritura o paso de derivaci
on es el pasaje de un string A a otro , donde A P .
Decimos que se deriva en un paso de A, en smbolos A .
es simplemente la iteraci
on de un n
umero finito de veces (su clausura reflexiva y transitiva).
El lenguaje generado por G es L(G) = {s T | S s}. Los miembros del lenguaje se denominan
sus frases o palabras.
Decimos que es una forma oracional (ingles: sentential form) de la gramatica si S . N
otese
entonces que el lenguaje consiste en aquellas formas oracionales formadas solamente por terminales.
Un
arbol de derivaci
on (o reconocimiento sint
actico o parsing) a partir de un no terminal A es un
arbol
(finitario) con raz A y con sub
arboles t1 , t2 , . . . , tn cuyas races son 1 , 2 , . . . , n , donde A 1 2 . . . n
es una producci
on de la gram
atica. En a
nadidura, si el subarbol ti tiene a su vez subarboles (es decir, no
consta solamente de la raz i ) entonces debe ser un arbol de derivacion a partir de i (que debe ser por
lo tanto un no terminal). La frontera de todo arbol de derivacion a partir de S es claramente una forma
oracional de la gram
atica.
?11. Escribir gram
aticas libres de contexto para los siguientes lenguajes:
1. {ai bj | j i}.
2. {ai bj bj ai }.
3. {ai bi aj bj }.
4. {ai bi } {bj aj }.
5. {ww1 | w {a, b} }.
6. {ai bj ci+j }.
7. Palabras en {a, b} con la misma cantidad de a que de b.
3. Jerarqua de Chomsky. Ejercicio. Escribir una gramatica libre de contexto para el lenguaje
an bn cn .
El ejercicio precedente no tiene soluci
on: Puede demostrarse que ese lenguaje no es generable por una
gram
atica libre de contexto. S lo es por la siguiente:
S
S aSQ repitiendo esta se genera an+1 SQn+1
S abc ahora se tiene an+2 bcQn+1 o simplemente se genera directamente abc.
cQ Qc cada Q deber
a ser reemplazada por bc, pero primero hay que ponerla en el lugar apropiado;
para esto se la corre hacia la izquierda (repitiendo la aplicacion esta regla mientras sea necesario).
bQc bbcc aqu la Q encontr
o su lugar y es reemplazada.
Estas
se llaman lineales a derecha. Tambien son regulares las gramaticas lineales a izquierda. (Notar que
no es admisible dentro de este tipo de gramaticas la mezcla de reglas lineales a izquierda con lineales a la
derecha.) Las gram
aticas regulares son llamadas de tipo 3 y resultan especialmente apropiadas para definir
lo que hemos llamado arriba el lexico de los lenguajes (ver ejercicios en la seccion subsiguiente).
La jerarqua precedente est
a ordenada por inclusion de las clases de lenguajes generados. Es decir: los
lenguajes (generados por gram
aticas) de tipo i + 1 estan estrictamente incluidos en los de tipo i (i = 0, 1, 2).
?12. Verificar la afirmaci
on anterior repasando las definiciones de los distintos tipos de gramaticas y los
teoremas enunciados arriba.
Por ejemplo, {an bn } es libre de contexto (tipo 2) pero no regular (tipo 3). Y {an bn cn } es sensible
al contexto (tipo 1) pero no tipo 2. Estas dos afirmaciones requieren, obviamente, demostraciones, que
todava no hemos dado totalmente. (Hemos s mostrado que {an bn cn } es de tipo 1, dando una gramatica no
contractiva. Tambien definimos {an bn } mediante una gramatica libre de contexto. Es un poco mas difcil
llegar a los resultados negativos.) Tambien hara falta mostrar un lenguaje tipo 0 que no sea de tipo 1, pero
esto nos llevara a estudiar casos un poco demasiado intrincados y poco informativos.
En general ocurre que las gram
aticas que no son libres de contexto tienden a ser intrincadas: representan
algoritmos de generaci
on m
as que conjuntos de conceptos o categoras sintacticas bien definidas. Por ello, en
la pr
actica, las gram
aticas de interes son las libres de contexto, y las restricciones adicionales que no pueden
imponerse por medio de la gram
atica son tratados por procedimientos separados.
10
11