Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Curso 2014/2015
Gramáticas
Producciones y derivaciones
Una producción o regla de una gramática tiene una parte izquierda y una parte derecha. Tanto la parte izquierda
como la parte derecha son una cadena de sı́mbolos terminales y no terminales
Normalmente, solamente se especifica el conjunto de producciones P , y se asume que el sı́mbolo inicial de la
gramática es la parte izquierda de la primera producción.
Ejemplo:
A → a B C
B → b bas
B → big C boss
C →
C → c
A ⇒ a B C
⇒ a b bas C
⇒ a b bas
En los ejemplos, la primera derivación se dice que es una derivación por la derecha, porque siempre se deriva
el no terminal situado más a la derecha, y la segunda es una derivación por la izquierda
IMPORTANTE: El lenguaje generado por una gramática es el conjunto de cadenas de terminales obtenidas
a partir de derivaciones válidas usando las reglas de la gramática
Un árbol de derivación es un árbol en el que se representa una derivación válida de una cadena (pero no se
especifica el orden en que se han aplicado las reglas)
PL, 2013/2014 2
a B C
b bas ε
Caracterı́sticas especiales
Se dice que una gramática es ambigua cuando, para una cadena determinada, existe más de un árbol de
derivación
IMPORTANTE: la única forma de saber si una gramática es ambigua es encontrando una cadena con más
de un árbol de derivación, no hay otra forma
Ejemplo:
E → E opsuma E
E → num
La cadena “2+3-4” tiene dos árboles de derivación, y la cadena “2+3-4+5” tiene más de dos árboles
(¿cuántos?)
Una gramática se dice que es recursiva por la izquierda si tiene al menos una regla de esta forma:
E → E opsuma T
E → T opsuma E
Una gramática se dice que tiene factores comunes por la izquierda si tiene en al menos dos reglas (con la misma
parte izquierda) sı́mbolos comunes al principio de la parte derecha de la regla:
A → B a C
A → B a d
...
Jerarquı́a de gramáticas
Según la forma de las producciones, las gramáticas se clasifican en:
Regulares: en la parte izquierda sólo hay un no terminal, y la parte derecha puede haber:
no terminal → terminal
no terminal → terminal no terminal
no terminal →
Independientes del contexto (context-free): en la parte izquierda sólo hay un no terminal, en la parte derecha
no hay restricciones
Dependientes del contexto: en la parte izquierda puede haber terminales y no terminales, pero al menos debe
haber un no terminal, y la longitud de la parte derecha debe ser mayor o igual que la de la parte izquierda
No restringidas
PL, 2013/2014 3
Las GIC se utilizan para especificar la sintaxis de las construcciones del lenguaje fuente
En los lenguajes de programación hay restricciones semánticas (p.ej. es necesario haber declarado una variable
antes de utilizarla), que hacen que en realidad los lenguajes de programación sean lenguajes sensibles al contexto,
pero no se utilizan gramáticas sensibles al contexto, se utilizan GIC a las que se añaden acciones para la
comprobación de las restricciones semánticas.
Es importante por tanto diseñar una buena gramática, pero luego es posible que se tenga que modificar según
el tipo de analizador sintáctico que se desee utilizar
Además, es posible que al diseñar el proceso de traducción sea necesario rediseñar la gramática para facilitar
el diseño del traductor
Pero... ¿no son todos los operadores asociativos por la izquierda? Sı́, casi todos, pero no todos: “a=b=c=0”
Algunos operadores no permiten usar más de dos operandos, como por ejemplo: “a<b<c” ⇒ “a<b && b<c”
PL, 2013/2014 4
Operador Asociatividad
@ izquierda
% derecha
# izquierda
A −→ A @ B
A −→ B
B −→ C % B
B −→ C
C −→ C # D
C −→ D
D −→ ...
Operadores unarios
Los operadores unarios son más difı́ciles de reflejar en una gramática, requiere un buen conocimiento del
lenguaje y de las gramáticas
Los ejemplos más conocidos son:
• el operador de negación, “!”, que además permite que se repita el operador: “!!!true”
ExpRel −→ ! ExpRel
• el operador de cambio de signo, “-” o “+”, que no permite repeticiones (por ejemplo, “----3” no es
correcto)
E −→ opsuma T
if (a<3)
if (b<4)
c=7;
else
c=8;
¿Con qué “if” se asocia el “else”? La regla que se usa normalmente es asociar el “else” al “if” más cercano:
if (a<3)
if (b<4)
c=7;
else
c=8;
if (a<3)
{
if (b<4)
{
c=7;
}
else
{
c=8;
}
}
PL, 2013/2014 5
2. ¡¡¡¡¡Es ambigua!!!!!
. . . y sin embargo, se utiliza en prácticamente todos los compiladores basados en análisis sintáctico ascendente
(los que usan yacc o bison).