You are on page 1of 0

1/18/2011

© 2007 Roberto Solis Robles,
Derechos Reservados 1
Introducción a las Técnicas de
Traducción y a los Aspectos
Formales
Compiladores e Intérpretes
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 2
Contenido
 Evolución de los lenguajes de
programación
 Tipos de Traducción
 Análisis y Síntesis
 Terminología de Lenguajes
 Forma Backus Naur (BNF)
 Lenguajes Formales
 Técnicas de análisis
 Grafos sintácticos
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 3
Evolución de los lenguajes de
programación (1)
¿Qué es un lenguaje de programación?
 Un lenguaje de programación es una
herramienta que puede ser usada para
controlar el comportamiento de una
computadora.
 Se utiliza para facilitar la comunicación
entre un usuario y la computadora y para
expresar de manera precisa un
algoritmo
 Al igual que el lenguaje humano, un
lenguaje de programación se define a
través de reglas sintácticas y semánticas.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 4
Evolución de los lenguajes de
programación (2)
 Primera Generación
 Operaban a nivel del código binario de la
computadora.
 Programación difícil y problemática
 Un pequeño avance con el advenimiento de
programación en octal o hexadecimal
 Segunda Generación
 Lenguajes ensambladores
 Estos lenguajes permiten usar abreviaciones
nemónicas y ya trabajan a nivel de registros en vez
de flip flops
 Primeros pasos hacia la programación estructurada,
la desventaja es la dependencia de la arquitectura y
la poca legibilidad de los programas
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 5
Evolución de los lenguajes de
programación (3)
 Tercera Generación
 Lenguajes de Alto Nivel.
 Usan estructuras de control basadas en objetos de datos
lógicos.
 Permite la representación de datos y funciones en forma
independiente de la computadora
 ALGOL-60, PASCAL, C, ADA, JAVA
B80001  MOV AX, 100
01C0  ADD AX, AX
A35001  MOV [150], AX  N = 100 + 100;
 Cuarta Generación
 Lenguajes diseñados con un proposito específico en
mente, tal como el desarrollo de software comercial de
negocios
 Generadores de reportes, SAS, SPSS
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 6
Evolución de los lenguajes de
programación (4)
 El diseño de programas para resolver
problemas es mas sencillo con los
lenguajes de alto nivel puesto que no se
requieren de conocimientos de la
arquitectura de la computadora
 Sin embargo, la computadora, lo único
que entiende es el código máquina
 Es por ello que se requiere de alguna
forma de traducción entre los lenguajes
de alto nivel y el lenguaje máquina
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 7
 Ensamblador (Assembler)
 Traduce un lenguaje escrito en lenguaje
ensamblador (assembly) a código
máquina.
 Compilador
 Traduce un programa escrito en lenguaje
de alto nivel a código objeto el cual puede
ser un código intermedio ó código
máquina. El código intermedio pudiera ser
un lenguaje ensamblador o alguna otra
forma de representación intermedia.
Tipos de Traducción (1)
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 8
Tipos de Traducción (2)
 Intérprete
 Un intérprete no genera código objeto sino que
analiza y ejecuta directamente cada sentencia
del código fuente.
 Preprocesador
 Entre sus tareas esta la sustitución de macros
o la inclusión de archivos.
 En este curso nos interesan los
compiladores e intérpretes, y dado que
ambos tienen las primeras fases en
común, nos enfocaremos específicamente
en los compiladores.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 9
código fuente
alto nivel
código máquina
bajo nivel
compilador
por ejemplo un programa en J ava
fácil de entender
sintáxis amigable con el usuario
muchas construcciones de programación de
alto nivel
independiente de la máquina
variables, métodos, clases, ...
por ejemplo el código MIPS
difícil de entender
especifico al hardware
registros & localidades sin nombre
Compilación (1)
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 10
Compilador:
Intérprete:
programa fuente
assembler enlazador compilador cargador
código ensamblador
código máquina
código máquina
librerías
datos
resultado
intérprete
datos
resultado programa fuente
J ava usa tanto un compilador (javac) como un intérprete (java)
Compilación (2)
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 11
Lenguaje Fuente Traductor Lenguaje Destino
LaTeX Formateador de Texto PostScript
J ava compilador javac bytecodes
J ava compilador cruzado códig en C++
Expresiones Regulares generador de scanners J Lex un scanner en J ava
BNF de un lenguaje generador de parsers CUP un parser en J ava
Otros ejemplos de traductores
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 12
 Muchas variaciones:
 muchos lenguajes de programación (por
ejemplo C++, Java)
 muchos paradigmas de programación
(por ejemplo orientado a objetos,
funcional, lógico, estructurado)
 muchas arquitecturas de cómputo (por
ejemplo MIPS, SPARC, Intel, Alpha)
 muchos sistemas operativos (por
ejemplo Linux, Solaris, Windows)
Desafíos de un Compilador
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 13
 el compilador mismo debe estar libre de defectos
 debe generar código máquina correcto
 el código máquina generado debe ejecutarse
rápidamente
 el compilador mismo debe correr rápido (el tiempo
de compilación debe ser proporcional al tamaño del
programa)
 el compilador debe ser portable (modular, soportar
compilación separada)
 debe imprimir buenos mensajes de diagnóstico y
error
 el código generado debe trabajar bien con los
depuradores existentes
Cualidades de un Compilador
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 14
 Construir un compilador requiere
conocimientos de:
 lenguajes de programación (paso de
parámetros, alcance de las variables, asignación
de memoria, etc)
 teoría (automatas, lenguajes libres de contexto,
etc)
 algoritmos y estructuras de datos (tablas hash,
algoritmos de grafos, programación dinámica,
etc)
 arquitectura de computadoras (lenguaje
ensamblador)
 ingeniería de software
Desafíos en el Desarrollo de un
Compilador
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 15
 Suponga que desea escribir compiladores de m
lenguajes fuente a n plataformas de cómputo. Una
solución ingenua requiere n*mprogramas:
C++ MIPS
J ava SPARC
Pentium
FORTRAN PowerPC
• peropodemoshacerlocon n+mprogramas:
C++ MIPS
J ava SPARC
Pentium
FORTRAN PowerPC
FE
FE
FE
BE
BE
BE
BE
RI
–RI: Representación
Intermedia
–FE: Front-End
–BE: Back-End
Manejando la Portabilidad
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 16
 Un compilador típico del mundo real tiene múltiples
fases
 El front-end consiste de las siguientes fases:
 scanning (análisis léxico): un scanner agrupa los
caracteres de entrada en componentes léxicos
denominados tokens
 parsing (análisis sintáctico): un parser reconoce
secuencias de tokens de acuerdo a alguna gramática
y genera Arboles de Análisis Sintactico (ASTs)
 análisis semántico: realiza verificación de tipos y
traduce los ASTs en RIs (verifica el significado)
Fases de un Compilador (1)
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 17
 El back-end consiste de las siguientes
fases:
 selección de instrucciones : transforma las
RIs en código ensamblador
 optimización del código: optimiza el código
ensamblador usando análisis de control de flujo
y control de datos, asignación de registros, etc
 emisión del código: genera código máquina a
partir del código ensamblador
Fases de un Compilador (2)
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 18
Fases de un Compilador (3)
 A las fases del front-end se les conoce en
conjunto como análisis, ya que su
trabajo es básicamente determinar la
estructura y el significado de un código
fuente. Estas fases son independientes de
la máquina.
 A las fases del back-end se les conoce
como síntesis, puesto que sintetiza
(transforma) el código fuente en código
objeto. Estas fases son dependientes de
la máquina.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 19
Ambiente General de Compilación
Compilador
Análisis Léxico
Análisis Sintáctico
Análisis Semántico
Generador de Código
RI
Fuente
Código
Relocalizable
Ejecutable
Librerías
Enlazador
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 20
Un poco más sobre las fases de
análisis
 Veamos algunos ejemplos…
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 21
Análisis Léxico (Scanning)
 Si por ejemplo se tiene la línea
suma = x + 5.3 ;
 El scanner (analizador léxico) dividirá tal línea en
sus tokens:
 suma (identificador)
 = (asignación)
 x (identificador)
 + (operador suma)
 5.3 (número flotante)
 ; (delimitador)
 Todos los identificadores son colocados en una
tabla de símbolos, que es una estructura de
datos que contiene un registro con los atributos
de cada identificador.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 22
Análisis Sintáctico (Parsing) (1)
 Revisa si el programa fuente fue
diseñado de acuerdo con la sintáxis
del lenguaje de programación. Aquí
se detectan errores tales como:
suma + x = 67.4 * num;
 Las unidades gramaticales
(sentencias) son representadas
mediante ASTs (Arboles de Análisis
Sintáctico)
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 23
Análisis Sintáctico (Parsing) (2)
 Por ejemplo, para la sentencia
suma = x + y – x * y;
 el AST es:
asignación
identificador expresión
suma = x + y – x * y
identificador expresión
identificador expresión
identificador identificador
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 24
Análisis Semántico
 Este es mucho mas díficil que el sintáctico
pues debe considerar el significado de
una unidad gramatical, es decir, la tiene
que interpretar. Esto lo logra traduciendo
el AST a una RI.
 Por ejemplo, para el AST anterior, si la
variable suma es entera y las variables x
y son reales la asignación no se puede
realizar
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 25
Aspectos Formales
 Los compiladores traducen
lenguajes que usualmente consisten
en elementos sintácticos que
pueden ser fácilmente descritos de
manera formal
 Por lo tanto, no se pueden estudiar
los compiladores sin considerar los
aspectos formales de la definición
de lenguajes
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 26
Terminología (1)
 Alfabeto
 Es un conjunto arbitrario pero finito de
símbolos. Por ejemplo:
 A
1
= {0,1}
 A
2
={0,1,2,3,4,5,6,7,8,9}
 A
3
={+,-,*,/}
 Símbolo
 Elemento de un vocabulario (alfabeto)
 Componente Léxico (Token)
 Ocurrencia de múltiples símbolos
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 27
Terminología (2)
 Frase
 Secuencia de tokens
 Gramática
 La gramática ó sintáxis de un lenguaje define
si una secuencia arbitraria de símbolos es
correcta, es decir, si una frase es significativa
 Cadena
 Secuencia (finita) de elementos de un alfabeto.
De manera análoga al conjunto vacío de la
teoría de conjuntos, llamaremos a una cadena
vacía ε. La cadena vacía ε es una cadena que
no contiene símbolos. La cadena 0011 es un
ejemplo de una cadena del alfabeto A
1
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 28
Terminología (3)
 Producción
 Es una regla para la sustitución de
cadenas. Los símbolos → y ::== se
usan comúnmente para representar
producciones.
 Por ejemplo, la regla (producción)
s→ab (ó bien s::==a b) significa que
puede sustituirse s por ab, ó que s se
define como ab
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 29
Terminología (4)
 Símbolos terminales
 Son los símbolos que realmente aparecen en
una frase. Nunca aparecen en el lado izquierdo
de una producción. Los símbolos terminales
deben ser símbolos válidos del lenguaje. Los
símbolos {, }, if, else, while son ejemplos de
símbolos terminales pertenecientes a la
gramática que describe al lenguaje C.
 T representa al conjunto de símbolos
terminales, mientras que T
*
representa el
conjunto de todas las cadenas posibles en T.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 30
Terminología (5)
 Símbolos no terminales
 Los símbolos no terminales deben ser
definidos por otras producciones (ó
reglas BNF), es decir, también
aparecen en el lado izquierdo de las
producciones. Los símbolos no
terminales son variables sintácticas.
 N representa al conjunto de símbolos
no terminales, mientras que N
*
representa el conjunto de todas las
cadenas posibles en N.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 31
Terminología (6)
 Vocabulario = Alfabeto
 Al igual que los lenguajes naturales, los
lenguajes formales se basan en un vocabulario
específico, a saber, los elementos del lenguaje.
El vocabulario de un lenguaje formal es la
unión de los símbolos terminales y no
terminales.
 V = N ∪ T representa el vocabulario, mientras
que V
*
representa el conjunto de todas las
cadenas posibles en V.
 El símbolo
*
usado en estas definiciones
indica la cerradura ó clausura de un
determinado conjunto.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 32
Forma de Backus-Naur (BNF) (1)
 Para poder compilar un programa escrito
en un lenguaje de programación
específico, es necesario conocer la
definición de dicho lenguaje.
 Definir un lenguaje de programación
significa describir la sintáxis y la
sémántica del mismo.
 Podemos especificar la sintáxis de un
lenguaje de programación usando la
forma de Backus Naur (BNF), la cual fue
creada para definir la estructura sintáctica
del lenguaje ALGOL60
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 33
Forma de Backus-Naur (BNF) (2)
 BNF es un metalenguaje, es decir, un lenguaje
para describir otros lenguajes. En la siguiente
tabla se muestran los metasímbolos mas
comunes en BNF.
Símbolo Significado
→ “se define como”
| “or”, alternativa
[x] una ó ninguna ocurrencia de x
{x} número arbitrario de ocurrencias de
x (0, 1, 2, …)
(x | y) selección (x ó y)
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 34
Ejemplo: Definición de números
enteros positivos y negativos
 T = {+, -, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
 N = { int, unsigned_int, digit}
 Producciones (Reglas):
 int → [ + | - ] unsigned_int
 unsigned_int → digit | unsigned_int digit
 digit → 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8| 9
 Si con un número finito de reglas se puede
derivar cualquier frase del lenguaje entonces
existe una descripción formal de tal
lenguaje. En este caso, el conjunto de reglas
anteriores describe formalmente el conjunto
infinito de números enteros.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 35
Lenguajes Formales (1)
 Para explicar algunas de las reglas y la
terminología de los lenguajes formales
vamos a usar BNF para describir
enunciados en español.
 Un enunciado en español consiste de un
sujeto(S) y un predicado(P)
 E → S P
 En esta producción, S y P son símbolos no
terminales
 S y P son definidos por tanto también a través
de producciones
 S → A N
 P → V S
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 36
Lenguajes Formales (2)
 A define un artículo, N define un sustantivo y V
define un verbo, todos son símbolos no
terminales. Por ejemplo:
 A → el
 N → hombre | balón | libro
 V → tomó | compró
 ¿Cuáles son los símbolos no terminales?
 ¿Cuántos enunciados podrán ser generados
usando estas definiciones?
 ¿Cuáles son?
 Como podemos ver, sólo se esta considerando la
sintáxis, mas no la semántica.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 37
Lenguajes Formales (3)
 A una descripción sintáctica completa de
un lenguaje, como ésta, se le llama
gramática.
 Una gramática consiste de un conjunto de
reglas donde está definido cada símbolo
no terminal
 Uno de los símbolos no terminales se
marca como símbolo inicial y por tanto, es
el punto de partida de la gramática.
 ¿Cuál es el símbolo inicial en el ejemplo
de los enunciados en español de las
diapositivas anteriores?
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 38
Lenguajes Formales (4)
 Una gramática G se definirá como
una tupla de 4 elementos G (T, N,
P, S) donde
 T es el conjunto de símbolos terminales
 N es el conjunto de símbolos no
terminales
 P es el conjunto de producciones
 S ∈ N es el símbolo inicial
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 39
Lenguajes Formales (5)
 Un lenguaje formal se caracterizará con
referencia a una gramática G
 L(G) = L (T, N, P, S)
 Decimos que una cadena β puede
derivarse directamente de una cadena α
 α → β
si existe una sola producción que produce
β a partir de α, por ejemplo
 α → α
1
α
2
α
3
 β → α
1
β
2
α
3
y existe la producción
 α
2
→ β
2
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 40
Lenguajes Formales (6)
 Decimos que una cadena α
n
se puede
derivar de una cadena α
0
si y sólo si
existe una secuencia de cadenas α
0
, α
1
,
α
2
, …, α
n-1
, tal que cada α
i
puede
derivarse directamente de α
i-1
(i = 1, 2,
…, n):
 α
0
→ α
1
→ α
2
→ … → α
n-1
→ α
n
 Podemos abreviar una secuencia de
producciones de este tipo con →:
 α
0
→ α
n
≡ (α
i-1
→ α
1
, i = 1, 2, …, n)
 → se conoce como la cerradura transitiva
reflexiva de →.
*
*
*
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 41
Lenguajes Formales (7)
 Por ejemplo, el enunciado “el hombre
compró el libro” puede derivarse con la
siguiente secuencia de producciones:
E → S P
→ A N P
→ el N P
→ el hombre P
→ el hombre V S
→ el hombre compró S
→ el hombre compró A N
→ el hombre compró el N
→ el hombre compró el libro
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 42
Lenguajes Formales (8)
 Por tanto, si abreviamos “el hombre
compró el libro” con ehcel, decimos que
E → ehcel
y que ehcel será un enunciado aceptado
por el lenguaje definido por el conjunto
de producciones anterior, ehcel∈ L, ya
que ehcel ∈ T
*
.
 Ahora podemos definir entonces un
lenguaje L(G) como el conjunto de todas
las cadenas de símbolos terminales que
pueden derivarse a partir del símbolo
inicial S:
 L = { σ | S → σ y σ ∈ T
*
}
*
*
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 43
Lenguajes Formales (9)
 Una derivación puede ser por la izquierda
o por la derecha.
 Una derivación se denomina por la
izquierda (o por la derecha) si siempre se
reemplaza el no terminal más a la
izquierda (ó más a la derecha).
 Más adelante veremos ejemplos de
derivaciones por la derecha o la izquierda
(de hecho, ya vimos uno de derivación
por la izquierda)
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 44
Lenguajes Formales (10)
 Una regla BNF
V → σ
especifica que un solo símbolo no
termina V ∈ N puede ser sustituido
por σ ∈ (N ∪ T
*
) sin importar el
contexto donde aparezca V. Estas
producciones se conocen como
independientes del contexto.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 45
Lenguajes Formales (11)
 Una gramática y el lenguaje
correspondiente son independientes del
contexto si y sólo si pueden definirse con
un conjunto de producciones
independientes del contexto
 Las gramáticas independientes del
contexto son muy importantes en la
teoría de los lenguajes de programación
ya que los lenguajes que definen tienen
en general una estructura muy sencilla.
Las técnicas de análisis sintáctico suelen
basarse en gramáticas independientes del
contexto.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 46
Lenguajes Formales (12)
 Una gramática independiente del contexto es no
ambigua si y sólo so hay una sola derivación por
la derecha (o por la izquierda) y por ende, un solo
árbol de análisis sintáctico (AST) para cada frase
que puede derivarse con las producciones de la
gramática. En caso contrario se llama ambigua.
 Una frase de una gramática ambigua puede tener
más de un AST y por consiguiente más de un
significado y por ello, tales gramáticas no son
muy útiles para el análisis y la definición de los
lenguajes de programación.
 Más adelante veremos ejemplos y como convertir
de una gramática ambigua a no ambigua.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 47
Lenguajes Formales (13)
 Se dice que una gramática G(T, N, P, S)
es lineal izquierda si cada producción P
tiene la forma
A → Ba ó A → a
donde A y B ∈ N y a ∈ T
*
.
 G(T, N, P, S) es lineal derecha si cada
producción P tiene la forma
A → aB ó A → a
 Las gramáticas lineales derechas también
se conocen como regulares (ó de estado
finito)
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 48
Lenguajes Formales (14)
 En general, la sintáxis de un
lenguaje de programación no puede
expresarse con una gramática
regular, pero ciertos elementos del
lenguaje, como nombres y
números, se describen mejor con
gramáticas regulares. Por lo tanto,
el análisis léxico que veremos
posteriormente se basa en una
gramática regular.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 49
Lenguajes Formales (15)
 Un símbolo no terminal X ∈ N en una gramática
independiente del contexto G(T, N, P, S) es
recursivo si
X → αXβ
para algunas α y β. Se dice que X es recursivo
izquierdo (ó recursivo derecho) si α = ε (β = ε)
 Si todos los símbolos no terminales (con la
posible excepción del símbolo inicial) son
recursivos, decimos que la gramática es
recursiva. Algunos algoritmos de análisis sintático
no funcionan con las gramáticas recursivas
izquierdas dado el riesgo de que se presente un
ciclo infinito.
*
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 50
Lenguajes Formales (16)
 La inversa de una derivación es la
reducción. En lugar de “β puede derivarse
(directamente) de α (α→β)”, también es
posible decir que “β puede reducirse
(directamente) a α ( β←α )”. Estas formas
son equivalentes:
α → β ≡ β ← α
α → β ≡ β ← α
 Obviamente, la inversa de una derivación
por la izquierda es una reducción por la
derecha, mientras que la inversa de una
derivación por la derecha es una
reducción por la izquierda
* *
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 51
J erarquía de Gramáticas (1)
 Las gramáticas se clasifican de acuerdo a
su complejidad. Esta clasificación,
conocida como jerarquía de Chomsky, se
estable aumentando las restricciones
sobre la forma de las producciones.
 Tipo 0. Gramáticas sin restricciones.
 Tipo 1. Gramáticas dependientes del contexto.
 Tipo 2. Gramáticas independientes del
contexto.
 Tipo 3. Gramáticas regulares
 Las gramáticas del tipo i+1 son también de
tipo i.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 52
J erarquía de Gramáticas (2)
Tipo 0: Sin Restricciones
Tipo 1: Todas las producciones tienen la forma:
αAβ → αγβ, A ∈ N, α,β,γ ∈ V
*
, γ puede ser ε
Tipo 2: Todas las producciones tienen la forma:
A → α, A ∈ N, α∈ V
*
Tipo 3: Todas las producciones tienen la forma:
A → a ó A → a B
(lineal derecha)
ó bien
A → a ó A → B a
(lineal izquierda)
A,B ∈ N, a ∈ T
*
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 53
Gramáticos Tipo 0 (Sin Restricciones)
 No hay restricciones para el lado
izquierdo ó el lado derecho de las
producciones.
 Estas gramáticas generales no
tienen relevancia en los lenguajes
de programación de la actualidad.
 Escribir un analizador sintáctico
para una gramática tipo 0 sería una
tarea muy ardua.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 54
Gramáticos Tipo 1 (Dependientes del
Contexto)
 Las sustituciones sólo pueden
efectuarse en cierto contexto dada
la forma que tienen las
producciones.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 55
Gramáticos Tipo 2 (Independientes del
Contexto)
 Las sustituciones se efectúan sin
tomar en cuenta el contexto (que
hay alrededor del símbolo no
terminal)
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 56
Gramáticos Tipo 3 (Regulares)
 Son gramáticas lineales izquierda
y/o derecha.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 57
Gramáticas importantes para el
desarrollador de un compilador
 Las gramáticas independientes del
contexto definen la sintaxis de las
declaraciones, sentencias, expresiones,
etc.
 Las gramáticas regulares definen la
sintáxis de los identificadores, números,
cadenas y otros símbolos básicos del
lenguaje.
 Por ello, las primeras se usan en el
análisis sintáctico mientras que las
segundas se usan en el análisis léxico.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 58
Nota importante sobre los lenguajes de
programación típicos
 Los lenguajes de programación típicos
tienen propiedades que no pueden
expresarse con gramáticas
independientes del contexto (ni con
gramáticas regulares).
 Por ejemplo, la sentencia x = n * x sólo
puede ser válida si x y n fueron
declaradas y son de tipos compatibles.
 Estos problemas dependientes del
contexto se suelen manejar con tablas de
símbolos.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 59
Arboles de análisis sintáctico (AST)
 Hasta ahora hemos mostrado como usar
una gramática para generar frases de un
lenguaje específico
 Pero un compilador no debe generar
frases, sino revisar una cadena de
símbolos para determinar si pertenecen ó
no al lenguaje, es decir, encontrar de que
manera se puede derivar la secuencia de
símbolos a partir del inicial mediante las
producciones gramaticales. Este es el
problema de análisis sintáctico.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 60
Ejemplo de AST (1)
 Suponga la existencia de la gramática
G
0
(T
0
, N
0
, P
0
, S
0
) la cual acepta
expresiones aritméticas simples.
 T
0
= {x, y, +, -, *, /, (, )}
 N
0
= {EXPR, TERM, FACTOR}
 P
0
= { EXPR → TERM | EXPR + TERM |
EXPR – TERM
TERM → FACTOR | TERM * FACTOR |
TERM / FACTOR
FACTOR → x | y | (EXPR) }
 S
0
= {EXPR}
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 61
Ejemplo de AST (2)
 Consideremos la derivación por la izquierda de la
expresión x+y-x*y
EXPR → EXPR – TERM
→ EXPR + TERM – TERM
→ TERM + TERM – TERM
→ FACTOR + TERM – TERM
→ x + TERM – TERM
→ x + FACTOR – TERM
→ x + y – TERM
→ x + y – TERM * FACTOR
→ x + y – FACTOR * FACTOR
→ x + y – x * FACTOR
→ x + y – x * y
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 62
Ejemplo de AST (3)
 Consideremos ahora la derivación por la derecha
de la expresión x+y-x*y
EXPR → EXPR – TERM
→ EXPR - TERM * FACTOR
→ EXPR - TERM * y
→ EXPR - FACTOR * y
→ EXPR – x * y
→ EXPR + TERM – x * y
→ EXPR + FACTOR – x * y
→ EXPR + y – x * y
→ TERM + y – x * y
→ FACTOR + y – x * y
→ x + y – x * y
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 63
Ejemplo de AST (4)
 Considerando una gramática
independiente del contexto, podemos
enunciar las siguientes propiedades con
respecto a un AST:
 La raíz está marcada con el símbolo inicial
 Cada hoja está marcada con un símbolo no
terminal ó con ε
 Cada nodo está marcado con un símbolo no
terminal
 Al proceso de generación de un AST para
una expresión se le denomina análisis
sintáctico.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 64
Gramáticas Ambiguas y No Ambiguas
(1)
 Ahora que hemos visto los árboles
sintácticos, podemos examinar de
nuevo las gramáticas ambiguas y
no ambiguas.
 Si consideramos el lenguaje
generado por la gramática G
0
,
podemos hallar al menos otras dos
gramáticas que generan el mismo
lenguaje: G’
0
y G’’
0
.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 65
Gramáticas Ambiguas y No Ambiguas
(2)
 G’
0
(T’
0
, N’
0
, P’
0
, S’
0
):
 T’
0
= {x, y, +, -, *, /, (, )}
 N’
0
= {EXPR, OP}
 P’
0
= { EXPR → EXPR OP EXPR |
(EXPR) | x | y
OP → + | - | * | /}
 S’
0
= {EXPR}
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 66
Gramáticas Ambiguas y No Ambiguas
(3)
 G’’
0
(T’’
0
, N’’
0
, P’’
0
, S’’
0
):
 T’’
0
= {x, y, +, -, *, /, (, )}
 N’’
0
= {EXPR}
 P’’
0
= { EXPR → EXPR + EXPR |
EXPR – EXPR |
EXPR * EXPR |
EXPR / EXPR |
(EXPR) | x | y}
 S’’
0
= {EXPR}
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 67
Gramáticas Ambiguas y No Ambiguas
(4)
 Se puede ver con estos ejemplos que no hay una
correspondencia única entre un cierto lenguaje y
una gramática: gramáticas con diferentes
conjuntos de producciones pueden generar el
mismo lenguaje.
 Estos ejemplos de distintos AST para la misma
frase del lenguaje muestran de manera explícita
el problema de las gramáticas ambiguas:
mientras que en la gramática G
0
sólo es posible
una interpretación para una misma frase, con G’
0
y G’’
0
es posible más de una interpretación para la
frase.
 Esto explica por qué las gramáticas ambiguas son
problemáticas con respecto a los lenguajes de
programación.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 68
Técnicas de Análisis (1)
 El análisis sintáctico es el proceso
donde hay que determinar el árbol
sintáctico correspondiente a una
frase dada, de acuerdo con la
gramática del lenguaje de
programación. En principio, hay dos
métodos para realizar un análisis:
 Análisis sintáctico descendente
 Análisis sintáctico ascendente
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 69
Técnicas de Análisis (2)
 Es importante señalar que llegamos a la
solución correcta con ambos métodos sólo
porque sabíamos cual era la frase por
analizar, es decir, disponíamos de todos
los símbolos por anticipado.
 Sin embargo, sin la técnica de examen
por anticipado (preanálisis), habría
muchas posibilidades de tomar decisiones
erróneas.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 70
Técnicas de Análisis (3)
 Por ejemplo, si eligieramos ENN →
DIGITO en el primer paso del análisis
sintáctico descendente, no podríamos
obtener el árbol de análisis sintáctico de
la frase 123.
 A esta situación se le denomina bloqueo
mutuo (deadlock). Para resolver
problemas de este tipo definiremos los
conjuntos llamados FIRST y FOLLOWS
más adelante en el curso.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 71
Grafos Sintácticos (1)
 Una forma de representar la
estructura sintáctica de un lenguaje
es con la notación BNF. Los grafos
sintácticos son otra manera
(gráfica) de representar la sintáxis
de un lenguaje.
 La representación del lenguaje con
grafos sintácticos es equivalente a
la representación con BNF.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 72
Grafos Sintácticos (2)
 R1. Las producciones de la forma
N → α
1
| α
2
| … | α
n
se representarán con el siguiente grafo:
α
1
α
2
α
n
.
.
.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 73
Grafos Sintácticos (3)
 R2. Las producciones de la forma
N → a
1
a
2
… a
n
se representarán con el siguiente grafo:
. . .
a
1
a
2
a
n
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 74
Grafos Sintácticos (4)
 R3. Si un elemento tiene uno o cero
ocurrencias, o sea, [ α ],
será representado con el siguiente grafo:
α
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 75
Grafos Sintácticos (5)
 R4. Si un elemento se repite
arbitrariamente (0 veces inclusive), o sea,
{ α },
se representará con el siguiente grafo:
α
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 76
Grafos Sintácticos (6)
 R5. Los símbolos no terminales N se
representarán dentro de un rectángulo:
N
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 77
Grafos Sintácticos (7)
 R6. Los símbolos terminales t se
representarán dentro de un óvalo:
t
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 78
Grafos Sintácticos (8)
 Una frase dada será correcta si y
sólo si los elementos de la frase
describen un camino correcto por
los grafos.
 Con base a las reglas R1 a R6
podemos representar la gramática
G
0
(T
0
, N
0
, P
0
, S
0
) con los siguientes
grafos sintácticos.
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 79
Grafos Sintácticos (9)
TERM
EXPR
EXPR
TERM
TERM
+
-
EXPR
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 80
Grafos Sintácticos (10)
FACTOR
TERM
TERM
FACTOR
FACTOR
*
/
TERM
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 81
Grafos Sintácticos (11)
EXPR
x
(
FACTOR y
)
1/18/2011
© 2007 Roberto Solis Robles,
Derechos Reservados 82
Ejercicio
 E
 ES
 OR
 T
 OA
 F
 OM
 EU
 OU
 Cambia el terminal OR por || y AND por &&
 Genera solución