Analisis Sintactico
Analisis Sintactico
Analisis Sintactico
Bibliograf a: Aho, A.V., Sethi, R., Ullman, J.D. (1990), Compiladores: principios, tcnicas y herramientas, Tema 4, pg.: 163-186. e a Louden, K.C. (1997), Compiler Construction: Principles and Practice, Tema 3, pginas: 93-140. a Contenidos: 1. El proceso de anlisis sintctico. a a 2. Especicacin sintctica de los lenguajes de programacin: o a o a a) Gramticas independientes del contexto versus expresiones regulares. b) Gramticas independientes del contexto versus gramticas a a dependientes del contexto. 3. Derivaciones y rboles sintcticos. a a 4. Gramticas limpias y bien formadas. a u a 5. El problema de la ambigedad en las gramticas. Eliminacin: o a) Mediante reglas de precedencia. b) Mediante transformacin. o o e a a 6. Clasicacin de los mtodos de anlisis sintctico.
71
72
3.1.
Funciones del analizador sintctico: a Comprobar si la cadena de componentes lxicos proporcionae da por el analizador lxico puede ser generada por la gramtica e a que dene el lenguaje fuente (Gramtica Independiente del a Contexto, GIC). Construir el rbol de anlisis sintctico que dene la estruca a a tura jerrquica de un programa y obtener la serie de derivaa ciones para generar la cadena de componentes lxicos. El e rbol sintctico se utilizar como representacin intermedia a a a o en la generacin de cdigo. o o Informar de los errores sintcticos de forma precisa y siga nicativa y deber estar dotado de un mecanismo de recua peracin de errores para continuar con el anlisis. o a
gram. indep. contexto
programa fuente
analizador lxico
componente lxico
analizador sintctico
analizador
rbol semntico anlisis sintctico
gestor errores
tabla de smbolos
El anlisis sintctico se puede considerar como una funcin que a a o toma como entrada la secuencia de componentes lxicos producie da por el anlisis lxico y produce como salida el rbol sintctico. a e a a En la realidad, el anlisis sintctico hace una peticin al anlisis a a o a lxico del componente lxico siguiente en la entrada (los s e e mbolos terminales) conforme lo va necesitando en el proceso de anlisis, a conforme se mueve a lo laro de la gramtica. a Reconocedor versus analizador sintctico a
Un reconocedor trata de determinar simplemente si la cadena puede o no ser generada por la gramtica (salida boolena). Poa dr amos preguntar algo ms. Si queremos reconocer las estruca turas propias de los lenguajes de programacin en el chero de o entrada para guiar la traduccin, es necesario conocer su estruco tura jerrquica, el rbol de anlisis sintctico. a a a a
3.2.
La mayor de las construcciones de los lenguajes de programacin a o se pueden representar con una gramtica independiente del cona texto (GIC). La mayor de las construcciones de los lenguajes de a programacin implican recursividad y anidamientos. o G = {S, VT , VN T , P }, S: el axioma o s mbolo de inicio VT : conjunto de terminales, los componentes lxicos e VN T : conjunto de no-terminales P: conjunto de reglas de produccin de la forma o VN T X1 , . . . , Xn , con Xi (VT VN T ) Pregunta: Si las expresiones regulares son un caso particular de GIC, por qu no se incluye la especicacin lxica como e o e parte de la sintaxis? Los AFD son muy sencillos de implementar y son muy ecientes frente a los autmatas a pila necesarios para reconocer las o GIC, la eciencia del traductor se ver comprometida. a Expresiones regulares o gramticas independientes del a contexto? Las expresiones regulares no permiten construcciones anidadas tan comunes en los lenguajes de programacin: parntesis equilio e brados, concordancia de pares de palabras clave como begin-end, do-while, ... Por ejemplo: consideremos el problema de los parntesis equilie brados en una expresin aritmtica. El hecho de que haya un o e
74
parntesis abierto obliga a que haya un parntesis cerrado. Este e e problema es similar a considerar el lenguaje L = {aba, aabaa, aaabaaa, . . . , } = {an ban 0} Si intentamos escribir una expresin regular, lo ms prximo ser o a o a: {a ba } pero no se garantiza que el nmero de as antes y u despus sea el mismo. e Las expresiones regulares NO SABEN contar. NO es posible especicar la estructura de un lenguaje de programacin con slo o o expresiones regulares. Son sucientes las gramticas independientes del cona texto? NO, existen ciertos aspectos de los lenguajes de programacin que o no se pueden representar con una GIC. A estos aspectos se les llama aspectos semnticos, son aspectos en general dependientes a del contexto. Por ejemplo, el problema de declaracin de los identicadores o antes de uso. Se podr representar mediante el lenguaje a L={wcw tal que w (a|b) } este lenguaje no puede ser representado por una GIC. Por qu no usar gramticas contextuales? e a Su reconocimiento es demasiado complejo para ser eciente en un problema prctico. a Ser en el tema de anlisis semntico donde se abordar esa a a a tos problemas mediante el uso de acciones concretas (acciones semnticas) que no son propias de la gramtica en s Ser codia a . a go escrito para hacer las comprobaciones semnticas necesarias a (tipos, declaracin antes de uso, ...) o
TypeList VarList IdList Parameter ParameterList SimpleType TypeDenoter CompositeType FieldList StatementList Statement AssignStm LeftValue IfStm ElseStm WhileStm FunctionStm ReturnStm WriteStm ReadStm Arg Num ArgList Expression
76
3.3.
Dada , (VT VN T ) cadenas arbitrarias de s mbolos gramaticales, se dice que A es una derivacin, si existe una produccin o o A . Sea S , si (VT VN T ) se dice que es una forma de frase o forma sentencial si (VT ) se dice que es una frase o sentencia. Existen dos tipos de derivaciones: Derivacin ms a la izquierda: se sustituye en cada paso el o a no-terminal ms a la izquierda de la forma de frase. La dea notaremos por: mi Derivacin ms a la derecha: se sustituye en cada paso el o a no-terminal ms a la derecha de la forma de frase. La denoa taremos por: md Por ejemplo para la gramtica: a
E id | num | E + E | ( E ) | - E
Si queremos derivar la frase (id + id) E E (E + E) (id + E) (id + id) derivacin ms a la izquierda. o a E E (E + E) (E + id) (id + id) derivacin ms a la derecha. o a
77
3.3.1.
Un rbol de anlisis sintctico indica cmo a partir del axioma a a a o de la gramtica se deriva una frase (cadena) del lenguaje. Dada a una gramtica independiente del contexto, un rbol de anlisis a a a sintctico es un rbol tal que: a a z a mbolo inicial. 1. La ra est etiquetada con el s 2. Cada hoja est etiquetada con un componente lxico. Las a e hojas de izquierda a derecha forman la frase (el programa fuente). 3. Cada nodo interior est etiquetado con un no-terminal. a 4. Si A es un no-terminal y X1 , X2 , . . . , Xn son sus hijos de izquierda a derecha, entonces existe la produccin A X1 , X2 , . . . , Xn , o con Xi (VT VN T ). El rbol de anlisis sintctico contiene en general mucha ms ina a a a formacin que la estrictamente necesaria para generar el cdigo. o o Se puede construir una estructura ms sencilla, los rboles aba a stractos de anlisis sintctico. Ejemplo: expresiones aritmticas a a e (igual semntica, menor complejidad) a
Entrada: id * id E E * E id * id
* + id id id
78
3.4.
Llamamos smbolo vivo al s mbolo a partir del cual se puede derivar una cadena de terminales. Llamamos s mbolo muerto a los s mbolos no-vivos, no generan una cadena del lenguaje. Llamamos smbolo inaccesible si nunca aparece en la parte derecha de una produccin. A las gramticas que contienen estos tipos de o a s mbolos se les llama gramticas sucias. a Teorema 1: si todos los s mbolos de la parte derecha de una produccin son s o mbolos vivos, entonces el s mbolo de la parte izquierda tambin lo es. e Algoritmo para detectar s mbolos muertos 1. Hacer una lista de no-terminales que tengan al menos una produccin con slo s o o mbolos terminales en la parte derecha. 2. Dada una produccin, si todos los no-terminales de la parte o derecha pertenecen a la lista, entonces podemos incluir en la lista al no-terminal de la parte izquierda de la produccin. o 3. Cuando ya no se puedan incluir ms s a mbolos en la lista mediante la aplicacin del paso 2, la lista contendr los s o a mbolos no-terminales vivos y el resto sern s a mbolos muertos.
79
Teorema 2: si el s mbolo no-terminal de la parte izquierda de una produccin es accesible, entonces todos los o s mbolos de la parte derecha tambin lo son. e Algoritmo para detectar smbolos inaccesibles 1. Se inicializa una lista de no-terminales que sabemos que son accesibles con el axioma. 2. Si la parte izquierda de una produccin est en la lista, eno a tonces se incluye en la misma al no-terminal que aparece en la parte derecha de la produccin. o a mbolos a la lista medi3. Cuando ya no se pueden incluir ms s ante la aplicacin del paso 2, entonces la lista contendr too a dos los s mbolos accesibles y el resto de los no-terminales sern innacesibles. a Para limpiar una gramtica primero se eliminan los s a mbolos muertos y despus los s e mbolos inaccesibles. Una gramtica est bien formada si es limpia y adems no cona a a tiene producciones- . Para eliminar producciones- , remitirse a la signatura de TALF. Ejemplo: limpiar la gramtica a
SaAB|A AcBd Be|fS CgD|hDt Dx|y|z
80
3.5.
Gramticas ambiguas a
Una gramtica es ambigua cuando para una determinada sentena cia produce ms de un rbol de derivacin. a a o La gramtica siguiente es ambigua: a
E id | num | E + E | E * E | ( E ) | - E
Supongamos la sentencia
id + id * id
E + E * E num
num E num
El signicado semntico es DIFERENTE. No existe una unica a traduccin posible. Se genera cdigo diferente. o o No existe un algoritmo que determine con certeza en un plazo nito de tiempo si una gramtica es ambigua o no. A lo sumo que a se ha llegado en el estudio de la ambigedad es que hay algunas u condiciones que de cumplirse determinan la ambigedad, pero en u el caso de no cumplirse no se puede decir que la gramtica es no a ambigua. Necesidad de evitar las gramticas ambiguas. Cmo? a o transformando la gramtica o a estableciendo precedencias entre operadores y de asociatividad. Se puede eliminar la ambigedad transformando la gramtica u a agrupando todos los operadores de igual precedencia en grupos y asociando a cada uno una regla, de forma que los que tengan menor precedencia aparezcan ms cercanos al s a mbolo de inicio, precedencia en cascada. Esto conlleva el aumento de la complejidad de la gramtica y con ello en la del rbol sintctico. La a a a gramtica deja de ser intuitiva. a
81
IMPORTANTE: Una regla recursiva a izquierdas, hace que el operador sea asociativo por la izquierda. Una regla recursiva a derechas hace que el operador sea asociativo por la derecha. Ejemplo 2: el problema del dangling else y el convenio de la asociacin al if ms cercano. o a
statement if stmt | other if stmt if ( exp) statement | if ( exp) statement else statement exp 0 | 1
Por ejemplo: para la sentencia if (0) if (1) other else other tenemos dos rboles de derivacin. a o Crear los dos rboles ... a
82
3.6.
Atendiendo a la forma en que se construye el rbol de anlisis a a sintctico los mtodos de anlisis sintctico se clasican: a e a a Mtodos descendentes: se parte del s e mbolo de inicio de la gramtica que se coloca en la ra y se va construyendo el a z rbol desde arriba hacia abajo hasta las hojas, eligiendo la a derivacin que da lugar a una concordancia con la cadena o de entrada. Se basa en la idea de predice una derivacin o y establece una concordancia con el s mbolo de la entrada (predict/match). El anlisis sintctico descendente correa a sponde con un recorrido prejo del rbol de anlisis sintctico a a a (primero expandimos el nodo que visitamos y luego procesamos los hijos).
S Sujeto Verbo Objeto Sujeto el Nombre | un Nombre Objeto el Nombre | un Nombre Verbo el Nombre | un Nombre Nombre perro | gato | len o
Ejemplo:
Crear el rbol... a Problemas: recursin a izquierdas, diferentes alternativas en o una produccin, cmo conseguir un coste lineal? o o
83
Mtodos ascendentes: se construye el rbol de anlisis sintctie a a a co desde las hojas hasta la ra En las hojas est la cadena z. a a analizar y se intenta reducirla al s mbolo de inicio de la gramtica que est en la ra Se trata de desplazar-se en la a a z. cadena de entrada y encontrar una subcadena para aplicar una reduccin (una regla de produccin a la inversa), (shifto o reduce). El anlisis sintctico ascendente corresponde con un a a recorrido postorden del rbol (primero reconocemos los hijos a y luego mediante una reduccin reconocemos el padre). o Insertar un ejemplo de como efectivamente los dos tipos de anlia sis corresponden con los tipos de recorrido prejo y postjo. Atendiendo a la forma en que procesan la cadena de entrada se clasican en: Mtodos direccionales: procesan la cadena de entrada s e mbolo a s mbolo de izquierda a derecha. Mtodos no-direccionales: acceden a cualquier lugar de la cae dena de entrada para construir el rbol. Necesitan tener toda a la cadena de componentes lxicos en memoria. Ms costosos, e a no se suelen implementar. Atendiendo al nmero de alternativas posibles en una derivacin u o se clasican en: Mtodos deterministas: dado un s e mbolo de la cadena de entrada se puede decidir en cada paso cul es la alternaa tiva/derivacin adecuada a aplicar, slo hay una posible. No o o se produce retroceso y el coste el lineal. Mtodos no-deterministas: en cada paso de la construccin e o del rbol se deben probar diferentes alternativas/derivaciones a para ver cual es la adecuada, con el correspondiente aumento del coste. Importancia de los mtodos direccionales y deterministas en e el diseo de traductores. El determinismo por la necesidad de n eciencia (coste lineal frente a exponencial que le har prohibitia vo en el diseo prctico de traductores) y porque las herramienn a tas para la generacin de traductores asumen esta condicin. Los o o
84
no direccionales no deterministas
Unger
Predice/Concuerda 1 en anchura 1 en profundida
direccionales
deterministas
mtodos direccionales por la propia naturaleza secuencial en que e se va procesando los s mbolos del chero fuente de izquierda a derecha.
3.7. EJERCICIOS
85
3.7.
Ejercicios
1. (0.2 ptos) Dadas la siguiente gramtica, elimina los s a mbolos muertos e inaccesibles.
SaABC|Dd AaBC Bb Cc Dd Egh
a o 2. (0.2 ptos) Dada la siguiente grmatica, escribe la derivacin ms a la izquierda, el rbol de anlisis sintctico y el rbol a a a a a sintctico abstracto para las siguientes expresiones: (a) 3+4*5a 6; (b) 3*(4-5+6)
exp exp addop term | term addop + | term term mulop factor | factor mulop *| / factor ( exp ) | num
3. (0.2 ptos) Dada la siguiente grmatica simplicada de una a expresin en LISP: (a) escribe las derivaciones ms a la o a derecha y ms a la izquierda de la entrada (a 23 (m x y)). a Dibuja el rbol de anlisis sintctico para esa sentencia. a a a
lexp atom | list atom number | identier list ( lexp-seq ) lexp-seq lexp-seq lexp | lexp
a a 4. (0.2 ptos) Dada la siguiente gramtica, construya el rbol de anlisis sintctico para la frase not (true or false). Es una a a gramtica ambigua? a
86
TEMA 3. INTRODUCCION AL ANALISIS SINTACTICO bexp bexp or bterm | bterm bterm bterm and bfactor | bfactor bfactor not bfactor | ( bexp ) | true | false
a 5. (0.2 ptos) Escribe una gramtica para expresiones booleanas que incluya las constantes true y false, los operadores and, or y not y los parntesis. Se ha de tener en cuenta que el e operador or tiene menor precedencia que el operador and y ste menor que el operador not. Construye la gramtica de e a forma que los operadores and y or sean asociativos por la izquierda y el operador not por la derecha. 6. (0.2 ptos) Comprueba que se puede resolver el problema de la ambigedad del dangling else transformando la gramtica u a a la forma:
statment matched-stmt | unmatched-stmt matched-stmt if ( exp ) matched-stmt else matched-stmt | other unmatched-stmt if ( exp ) statement | if ( exp ) matched-stmt else unmatched-stmt exp 0 | 1
Justicar usando un ejemplo. 7. (0.2 ptos) Comprueba que el intento de resolver el problema de la ambigedad del dangling else no es adecuado: u
statment if ( exp ) statement | matched-stmt matched-stmt if ( exp ) matched-stmt else statment | other exp 0 | 1