Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Introduccin
Todo lenguaje de programacin tiene reglas que prescriben la estructura sintctica de programas bien formados. Se puede describir la sintaxis de las construcciones de los lenguajes de programacin por medio de gramticas independientes del contexto o notacin BNF. Una gramtica da una especificacin sintctica precisa y fcil de entender de un lenguaje de programacin. A partir de algunas clases de gramticas se puede construir automticamente un analizador sintctico eficiente. Una gramtica diseada adecuadamente imparte una estructura a un lenguaje de programacin til para la traduccin de programas fuente a cdigo objeto correcto y para la deteccin de errores. Los lenguajes evolucionan con el tiempo, adquiriendo nuevas construcciones y realizando tareas adicionales. Estas se pueden aadir con ms facilidad cuando existe una aplicacin basada en una descripcin gramatical del lenguaje.
Gran parte de la deteccin y recuperacin de errores en un compilador se centra en la fase de anlisis sintctico. Una razn es que muchos errores son de naturaleza sintctica. Otra razn es la precisin de los mtodos modernos de anlisis sintctico.
Afortunadamente los errores ms comunes son simples y a menudo basta con un mecanismo sencillo de manejo de errores. En algunos casos un error pudo haber sucedido mucho antes de la posicin en que se detect su presencia y puede ser muy difcil deducir la naturaleza precisa del error. En los casos difciles, el manejador de errores tal vez tenga que adivinar qu tena en mente el programador cuando escribi el programa. Varios mtodos de anlisis sintctico, como los mtodos LL y LR detectan un error lo antes posible, es decir, tienen la propiedad de prefijo viable Detectan la presencia de un error, nada ms ver un prefijo en la entrada que no es prefijo de ninguna cadena del lenguaje.
Estrategias de recuperacin
Recuperacin en modo pnico: Es el mtodo ms sencillo de implantar y se puede utilizar la mayora de los mtodos de anlisis sintctico. Al descubrir un error, el analizador sintctico desecha smbolos de entrada, de uno en uno, hasta que encuentra uno perteneciente a un conjunto designado de componentes lxicos de sincronizacin. Los componentes lxicos de sincronizacin son delimitadores como el punto y coma. Quien disea el compilador debe determinar los componentes lxicos de sincronizacin Es una manera sencilla, aunque no eficiente, pero permite evitar por ejemplo, ciclos infinitos.
Estrategias de recuperacin
Recuperacin a nivel de frase Al descubrir un error, el analizador sintctico puede realizar una correccin local de la entrada restante Esto es sustituir un prefijo de la entrada restante por alguna cadena que permita continuar al analizador sintctico. Una correccin local tpica sera sustituir una coma por un punto y coma, suprimir un punto y coma sobrante o insertar un punto y coma que falta. La eleccin de la correccin local corresponde al diseador del compilador. Su principal desventaja es su dificultad para afrontar situaciones en que el error se produjo antes del punto de deteccin.
Estrategias de recuperacin
Producciones de error Si se tiene una buena idea de los errores comunes que pueden encontrarse, se puede aumentar la gramtica del lenguaje con producciones que generan las construcciones errneas. Entonces se usa esta gramtica aumentada para construir el analizador sintctico. Si el analizador sintctico usa una produccin de error, se pueden generar diagnsticos de error apropiados para indicar la construccin errnea reconocida en la entrada.
Estrategias de recuperacin
Correccin global Existen algoritmos para elegir una secuencia mnima de cambios para obtener una correccin global de menor costo. Dada una cadena de entrada incorrecta x y la gramtica G, estos algoritmos encontrarn un rbol de anlisis sintctico para una cadena relacionada y, tal que el nmero de inserciones, supresiones y modificaciones de componentes lxicos necesarios para transformar x en y sea el mnimo posible. Por desgracia, la implantacin de estos mtodos es demasiado costosa en trminos de tiempo y espacio.
3. Las ltimas letras maysculas del alfabeto, como X, Y, Z, representan smbolos gramaticales, es decir, terminales o no terminales. 4. Las ltimas letras minsculas del alfabeto, principalmente u, v, ..., z, representan cadenas de terminales.
Derivaciones
Hay varias formas de considerar el proceso mediante el cual la gramtica define un lenguaje. Una manera se refiere a considerar el proceso como la construccin de un rbol de anlisis sintctico. Existe tambin una visin derivativa relacionada, la cual da una descripcin precisa de la construccin descendente de un rbol de anlisis sintctico. La idea central es que se considera una produccin como una regla de reescritura, donde el no terminal de la izquierda es sustituido por la cadena del lado derecho de la produccin. Se dice que aAb agB si A g es una produccin y a y b son cadenas arbitrarias de smbolos gramaticales. Si a1a2...an, se dice que a1deriva a an. El smbolo significa "deriva en un paso". A menudo se desea decir "deriva en cero o ms pasos" para este propsito se puede usar el smbolo
Derivaciones
SIMBOLO SIGNIFICADO Deriva Deriva en un paso Deriva en cero o ms pasos Deriva en uno o ms pasos Derivacin por la izquierda se deriva en un paso que sustituye el no terminal ms a la izquierda EJEMPLO
Derivaciones
Dada una gramtica G con smbolo inicial S, se puede utilizar la relacin para definir L(G) el lenguaje generado por G. Las cadenas L(G) pueden contener slo smbolos terminales de G. Una cadena de terminales w est en L(G) si, y solo si, La cadena w se llama frase de G. De un lenguaje que pueda ser generado por una gramtica, se dice que es un Lenguaje Independiente del Contexto. Si dos gramticas generan el mismo lenguaje, se dice que son equivalentes. Si donde a puede contener no terminales, entonces se dice que a es una forma de frase de G. Una frase es una forma de frase sin no terminales.
Derivaciones
Ejemplo: La cadena es una frase de la gramtica de ejemplo por que existe una derivacin Las cadenas son formas de frase de esta gramtica. Se escribe para indicar que se puede derivar de . En cada paso de una derivacin hay que hacer dos elecciones. Qu no terminal se debe sustituir ?y, qu alternativa usar para este no terminal?. Hay que considerar derivaciones donde tan slo el no terminal de ms a la izquierda de cualquier forma de frase se sustituya a cada paso. Se denominan por la izquierda.
Ambigedad
Se dice que una gramtica que produce ms de un rbol de anlisis sintctico para alguna frase es ambigua. Una gramtica ambigua es la que produce ms de una derivacin por la izquierda o ms de una derivacin por la derecha para la misma frase. Para algunos tipos de analizadores sintcticos es preferible que la gramtica no sea ambigua, pues no se podra determinar de manera exclusiva qu rbol de anlisis sintctico seleccionar para una frase.
Supresin de la ambigedad
Eliminar la ambiguedad de la siguiente gramtica con else ambiguo:
otra representa cualquier otra proposicin. De acuerdo con esta gramtica, la proposicin condicional compuesta tiene el rbol de anlisis sintctico que se muestra. La gramtica es ambigua, puesto que la cadena tiene dos rboles de anlisis sintctico.
Supresin de la ambigedad
A veces, una gramtica ambigua se puede reescribir para eliminar la ambigedad. En todos los lenguajes de programacin con proposiciones condicionales de esta forma, se prefiere el primer rbol de anlisis sintctico. La regla general es, "emparejar cada else con el then sin emparejar anterior ms cercano". Esta regla para eliminar ambigedades se puede incorporar directamente a la gramtica. A continuacin se presenta una gramtica equivalente a la del ejemplo, de una manera no ambigua. La idea es que una proposicin que aparezca entre un then y un else debe estar "emparejada"; es decir, no debe terminar con un then sin emparejar seguido de cualquier proposicin, por que entonces el else estara obligado a concordar con este then no emparejado. Una proposicin emparejada es o una proposicin if-then-else que no contenga proposiciones sin emparejar o cualquier otra clase de proposicin no condicional.
Independientemente de cuntas producciones de A existan, se puede eliminar de ellas la recursin directa por la izquierda mediante la siguiente tcnica: Primero se agrupan las producciones de A en la forma donde ninguna bi comienza con una A. Despus se sustituyen las producciones de A por
El no terminal A genera las mismas cadenas que antes, pero ya no es recursivo por la izquierda. Este procedimiento elimina toda la recursin inmediata por la izquierda de las producciones de A y A' (suponiendo que ningn ai es ), pero no elimina la recursin por la izquierda que incluya derivaciones de dos o ms pasos. Por ejemplo, considrese la gramtica
, pero no es recursivo
Eliminando la recursin directa por la izquierda a las producciones de E y despus a las de T, se obtiene
Se ordenan los no terminales S, A. No hay recursin directa por la izquierda entre las producciones de S, de modo que no ocurre nada durante el paso 2 para el caso i=1, i=2, se sustituyen las producciones de S en A en para obtener las siguientes producciones de A.
Eliminando la recursin directa por la izquierda entre las producciones de A, se obtiene la siguiente gramtica.
La factorizacin por la izquierda es una transformacin gramatical til para producir una gramtica adecuada para el anlisis sintctico predictivo. La idea bsica es que cuando no est claro cul de dos producciones alternativas utilizar para ampliar un no terminal A, se pueden reescribir las producciones de A para retrasar la decisin hasta haber visto lo suficiente de la entrada como para elegir la opcin correcta. Ejemplo: Si se tienen las dos producciones
al ver el componente lxico de entrada if, no se puede saber de inmediato qu produccin elegir para expandir prop. Si son dos producciones de A y la entrada comienza con una cadena no vaca derivada de a, no se sabe si expandir A a ab1 o a ab2. Sin embargo, se puede retrasar la decisin expandiendo A a aA'. Entonces, despus de ver la entrada derivada de a, se puede expandir A' a b1 o a b2. Es decir, factorizadas por la izquierda, las producciones originales se convierten en
Si X = a $, el analizador sintctico saca a X de la pila y mueve el apuntador de entrada al siguiente smbolo de entrada. Si X es un no terminal, el programa consulta la entrada M[X, a] de la tabla M de anlisis sintctico. Esta entrada ser o una produccin de X de la gramtica o una entrada de error. Si, por ejemplo, M[X, a] = {X UVW}, el analizador sintctico sustituye la X de la cima de la pila por WVU (con U en la cima). Como salida, se sabe que el analizador sintctico slo imprime la produccin utilizada; ah se podra ejecutar cualquier otro cdigo. Si M[X, a] = error, el analizador sintctico llama a una rutina de recuperacin de error.
Primero y siguiente
Se facilita la construccin de un analizador sintctico predictivo con dos funciones asociadas a una gramtica G. Estas funciones, PRIMERO y SIGUIENTE, permiten rellenar, siempre que sea posible, las entradas de una tabla de anlisis sintctico predictivo para G. Tambin se pueden utilizar los conjuntos de componentes lxicos devueltos por la funcin SIGUIENTE como componentes lxicos de sincronizacin durante la recuperacin de errores en modo de pnico. Si a es una cadena de smbolos gramaticales, se considera PRIMERO(a) como el conjunto de terminales que inician las cadenas derivadas de a. Si , entonces tambin est en PRIMERO(a). Se define SIGUIENTE(A), para el no terminal A, como el conjunto de terminales a que pueden aparecer inmediatamente a la derecha de A en alguna forma de frase, es decir, el conjunto de terminales a tal que haya una derivacin de la forma para algn a y b.
Primero y siguiente
Obsrvese que en algn momento de la derivacin pudieron haber existido smbolos entre A y a, pero si as fue, derivaron a y desaparecieron. Si A puede ser el smbolo situado ms a la derecha en una forma de frase, entonces $ est en SIGUIENTE(A). Para calcular PRIMERO(X) para todos los smbolos gramaticales X, aplquense las reglas siguientes hasta que no se puedan aadir ms terminales o a ningn conjunto PRIMERO.
Si X es terminal, entonces PRIMERO(X) es {X}.
Si es una produccin, entonces adase a PRIMERO(X). Si X es no terminal y , es una produccin, entonces pngase a en PRIMERO(X) si, para alguna i, a est en PRIMERO(Yi) y est en todos los PRIMERO(Y1), ..., PRIMERO(Yi-1); es decir, . Si est en PRIMERO(Yj) para toda j= 1, 2, . . . , k, entonces adase a PRIMERO(X).
Primero y siguiente
Por ejemplo, todo lo que est en PRIMERO(Y1) sin duda est en PRIMERO(X). Si Y1, no deriva a , entonces no se aade nada ms a PRIMERO(X), pero si , entonces se le aade PRIMERO(Y2), y as sucesivamente. Ahora se puede calcular PRIMERO para cualquier cadena X1X2 . .. Xn de la siguiente forma:
Adanse a PRIMERO(X1X2 . .. Xn) todos los smbolos distintos de de PRIMERO(X1). Si est en PRIMERO(X1), adanse tambin los smbolos distintos de de PRIMERO(X2); si est tanto en PRIMERO(X1) como en PRIMERO(X2), adanse tambin los smbolos distintos de de PRIMERO(X3), y as sucesivamente. Por ltimo, adase a PRIMERO(X1X2 . .. Xn) si,
Primero y siguiente
Para calcular SIGUIENTE(X) para todos los no terminales A, aplquense las reglas siguientes hasta que no se pueda aadir nada ms a ningn conjunto SIGUIENTE.
Pngase $ en SIGUIENTE(S), donde S es el smbolo inicial y $ es el delimitador derecho de la entrada. Si hay una produccin , entonces todo lo que est en PRIMERO(b) excepto se pone en SIGUIENTE(B). Si hay una produccin o una produccin , donde PRIMERO(b) contenga (es decir, ), entonces todo lo que est en SIGUIENTE(A) se pone en SIGUIENTE(B).
Primero y siguiente
Puesto que PRIMERO(TE') = PRIMERO(T) = {(,id}, la produccin hace que M[E, (] y M[E, id] adquieran la entrada . La produccin hace que M[E, +] adquiera . La produccin hace que M[E', )] y M[E', $] adquieran , puesto que SIGUIENTE(E') = {), $}.
Gramaticas LL(1)
Se puede aplicar el algoritmo 4.4 a cualquier gramtica G para producir una tabla de anlisis sintctico M. Para algunas gramticas M puede tener algunas cadenas con definiciones mltiples. Por ejemplo, si G es recursiva por la izquierda o ambigua. Entonces M tendr al menos una entrada con definiciones mltiples.
Gramaticas LL(1)
Una gramtica cuya tabla de anlisis sintctico no tiene entradas con definiciones mltiples se define como LL(1). La primera L (left) representa el examen de la entrada de izquierda a derecha. La segunda L (left) representa una derivacin por la izquierda. El 1 es por utilizar un smbolo de entrada de examen por anticipado a cada paso para tomar las decisiones de la accin en el anlisis sintctico.
Gramaticas LL(1)
Ninguna gramtica ambigua o recursiva por la izquierda puede ser LL(1). Una gramtica G es LL(1) si, y solo si, cuando sean dos producciones distintas de G se cumplen las siguientes condiciones:
Para ningn terminal a tanto a como b derivan a la vez cadenas que comiencen a. A lo sumo una de a y b pueden derivar la cadena vaca. Si , a no deriva ninguna cadena que comience con un terminal en SIGUIENTE(A).
Gramticas LL(1)
Gramticas LL(1)
La entrada para contiene , puesto que La gramtica es ambigua en la eleccin de la produccin que se utiliza al encontrar e (else). Se puede resolver escogiendo Asociar else con then previos ms cercanos. La eleccin de impedira que e se insertar en la pila o se eliminar de la entrada, lo cual, es incorrecto.
Mangos
Informalmente un mango de una cadena es una subcadena que concuerda con el lado derecho de una produccin y cuya reduccin al no terminal del lado izquierdo de la produccin representa un paso a lo largo de la inversa de una derivacin por la derecha. Formalmente un mango de una forma de frase derecha g es una produccin y una posicin g donde la cadena b podra encontrase y sustituirse por A para producir la forma de frase derecha previa en una derivacin por la derecha de g.
Mangos
Es decir, si entonces si la posicin que sique de a es un mango de La cadena w a la derecha del mango contiene solo smbolos terminales. En el rbol de anlisis sintctico, el mango representa el subrbol completo situado mas a la izquierda que consta de un nodo y todos sus hijos.
Poda
Se puede obtener una derivacin por la derecha en orden inverso mediante la poda de mangos. Se comienza con una cadena de terminales w que se desee analizar sintcticamente. Si w es una frase de la gramtica en cuestin, entonces donde gn es la n-sima forma de frase derecha de una, an desconocida, derivacin por la izquierda
Poda
Para reconstruir esta derivacin en orden inverso, se coloca el mango bn en gn y se reemplaza bn por el lado izquierdo de alguna produccin para obtener la (n-1)-sima forma de frase derecha gn -1. Si w es una frase de la gramtica en cuestin, entonces donde gn es la n-sima forma de frase derecha de una, an desconocida, derivacin por la izquierda
En la prctica, este tipo de analizadores sintcticos pueden tener inconvenientes como manejar operadores con distintas precedencias (signo -) y que no siempre se tiene seguridad de que el analizador acepte el lenguaje deseado.
Hay dos maneras para determinar las relaciones de precedencia Establecer la precedencia arbitariamente. Construir primero una gramtica no ambiga para el lenguaje que refleje la precedencia en el rbol de anlisis sintctico.