Está en la página 1de 83

Anlisis Sintctico

Universidad de Caldas Estructura de lenguajes Rubn Daro Garca Guzmn 2012

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.

El papel del analizador sintctico


El analizador sintctico obtiene una cadena de componentes lxicos del analizador lxico y comprueba si la cadena pueda ser generada por la gramtica del lenguaje fuente. El analizador sintctico informar sobre cualquier error de sintaxis de manera inteligible. Tambin debera recuperarse de errores que ocurren frecuentemente para poder continuar procesando el resto de su entrada.

El papel del analizador sintctico

El papel del analizador sintctico


Existen tres tipos generales de analizadores sintcticos para gramticas. Los mtodos universales de anlisis sintctico, como el algoritmo de Cocke-Younger-Kasami y el de Earley, pueden anlizar cualquier gramtica. Pero son mtodos bastante ineficientes para usarlos en la creacin de compiladores. Los mtodos empleados generalmente en los compiladores se clasifican como ascendentes o descendentes. Los analizadores sintcticos descendentes construyen rboles de anlisis sintctico desde arriba (la raz) hasta abajo (las hojas). Los analizadores sintcticos ascendentes comienzan en las hojas y suben hacia la raz. En ambos casos, se examina la entrada al analizador sintctico de izquierda a derecha, un smbolo a la vez.

El papel del analizador sintctico


Los mtodos descendentes y ascendentes ms eficientes trabajan slo con subclases de gramticas, pero varias de estas gramticas, como las LL y LR son suficientemente expresivas para describir la mayora de construcciones de los lenguajes de programacin. Los analizadores sintcticos implantados a mano a menudo trabajan con gramticas LL1. Los analizadores sintcticos para la clase ms grande de gramticas LR se construyen normalmente con herramientas automatizadas. En teora, la salida del analizador sintctico es una representacin del rbol de anlisis sintctico para la cadena de componentes lxicos producida por el analizador lxico. En la prctica, hay tareas que se pueden realizar durante el anlisis sintctico, como recoger informacin sobre distintos componentes lxicos en la tabla de smbolos, realizar la verificacin de tipos y otras clases de anlisis semntico y generar cdigo intermedio.

Manejo de Errores Sintcticos


Un buen compilador debe ayudar al programador a identificar y localizar los errores. La mayora de las especificaciones de los lenguajes de programacin no describen como deben responder un compilador a los errores; la respuesta se deja al diseador del compilador. Considerar desde el principio el manejo de errores puede simplificar la estructura de un compilador y mejorar su respuesta a los errores. Los errores pueden ser:
Lxicos, como escribir mal un identificador, palabra clave u operador. Sintcticos, como una expresin matemtica con parntesis mal equilibrados. Semnticos, como un operador aplicado a un operando incompatible. Lgicos, como una llamada infinitamente recursiva.

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.

Manejo de Errores Sintcticos


El manejador de errores en un analizador sintctico tiene objetivos fciles de establecer:
Debe informar de la presencia de errores con claridad y exactitud. Se debe recuperar de cada error con la suficiente rapidez como para detectar errores posteriores. No debe retrasar de manera significativa el procesamiento de programas correctos.

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.

Manejo de Errores Sintcticos


Cmo debe informar un manejador de errores de la presencia de un error? Al menos debe informar el lugar en el programa fuente donde se detecta el error, por que es muy probable que el error real se haya producido en alguno de los componentes lxicos anteriores. Si hay una posibilidad razonable de saber cul es realmente el error, tambin se incluye un mensaje de diagnstico informativo y comprensible; por ejemplo "Falta punto y coma en esta posicin". Una vez detectado el error, cmo se debe recuperar el analizador sintctico? No es adecuado que el analizador sintctico abandone despus de detectar el primer error, por que el posterior procesamiento de la entrada podra revelar ms errores. Una recuperacin inadecuada puede introducir una avalancha abrumadores de errores "espurios", no cometidos por el programador De igual manera, la recuperacin del error sintctico puede introducir errores semnticos espurios.

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.

Gramticas Independientes del Contexto


Una gramtica independiente del contexto consta de terminales, no terminales, un smbolo inicial y producciones. Los terminales son smbolos bsicos con que se forman las cadenas. Los no terminales son variables sintcticas que denotan conjuntos de cadenas. Ayudan a definir el lenguaje generado por la gramtica, tambin impone una estructura jerrquica sobre el lenguaje que es til tanto para el anlisis sintctico como para la produccin. Un no terminal es considerado como el smbolo inicial, y el conjunto de cadenas que representa es el lenguaje definido por la gramtica. Las producciones de una gramtica especifican cmo se pueden combinar los terminales y los no terminales para formar cadenas. Cada produccin consta de un no terminal, seguido por una flecha (a veces un smbolo ::=, en lugar de la flecha), seguida por una cadena de terminales y no terminales.

Convenciones de Notacin e las GIC


1. Estos smbolos son terminales
1. 2. 3. 4. 5. Las primeras letras minsculas del alfabeto como a,b,c. Los smbolos de operador como +, -, etc. Los smbolos de puntuacin como parentesis, coma, etc. Los dgitos 0,1,2,...,9. Cadenas en negrilla, como id o if.

2. Estos smbolos son no terminales


1. Las primeras letras maysculas del alfabeto como A, B, C. 2. La letra S, que cuando aparece suele ser el smbolo inicial. 3. Los nombres en cursiva minsculas como expr o prop.

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.

Convenciones de Notacin e las GIC


5. Las letras griegas minsculas a, b, g, por ejemplo, representan cadenas de smbolos gramaticales. 6. Si A->a1, A->a2, ..., A->ak son todas producciones con A a la izquierda (se les llama producciones de A), se pueden escribir A->a1|a2| ak.a1, a2, ..., ak se denominan alternativas de A. 5. A menos que se diga otra cosa, el lado izquierdo de la primera produccin es el smbolo inicial.

Gramticas Independientes del Contexto


Ejercicio: Para la gramtica que contiene las siguientes reglas, escribirla con la notacin de GIC Una expresin puede estar compuesta por dos expresiones separadas por un operador matemtico, o puede ser una expresin precedida por la negacin o una expresin entre parntesis. Los operadores matemticos son: la suma (+), la resta (-), la multiplicacin (*), la divisin (/), la exponenciacin (^). proposicin condicional que no se puede definir con expresiones regulares

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.

rboles de Anlisis Sintctico y Derivaciones


Un rbol de anlisis sintctico se puede ver como una representacin grfica de una derivacin que no muestra la eleccin relativa al orden de sustitucin. Cada nodo interior del rbol de anlisis sintctico se etiqueta con algn no terminal de A. Los hijos del nodo se etiquetan, de izquierda a derecha, con los smbolos del lado derecho de la produccin por la cual se sustituy esta A en la derivacin. Las hojas del rbol de anlisis sintctico se etiquetan con terminales y no terminales y, ledas de izquierda a derecha, constituyen una forma de frase, llamada el producto o frontera del rbol.

rboles de Anlisis Sintctico y Derivaciones


Un rbol de anlisis sintctico ignora las variaciones en el orden en que se sustituyen los smbolos en las formas de frase. El ejemplo muestra dos construcciones de rbol para dos derivaciones distintas. Una forma de evitar esto es hacer slo derivaciones por la izquierda o slo derivaciones por la derecha.

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.

Escritura de una gramtica


Las gramticas son capaces de describir la mayora de las sintaxis de los lenguajes de programacin. Un analizador lxico efecta una cantidad limitada de anlisis sintctico conforme se produce la secuencia de componentes lxicos a partir de los caracteres de entrada. La secuencia de componentes lxicos aceptadas por el analizador sintctico forman un superconjunto de un lenguaje de programacin.

Expresiones Regulares vs GIC


Toda construccin que se pueda describir mediante una expresin regular tambin se puede describir por medio de una gramtica. Se puede convertir de manera mecnica un AFN en una gramtica que genere el mismo lenguaje reconocido por el AFN. Puesto que todo conjunto regular es un lenguaje independiente del contexto, es razonable preguntar: Por qu utilizar expresiones regulares para definir la sintaxis lexicogrfica de un lenguaje?

Expresiones Regulares vs GIC


Por qu utilizar expresiones regulares para definir la sintaxis lexicogrfica de un lenguaje? Las reglas lexicogrficas de un lenguaje a menudo son bastante sencillas, y para describirlas no se necesita una notacin tan poderosa como las gramticas. Las expresiones regulares por lo general proporcionan una notacin ms concisa y fcil de entender para los componentes lxicos que una gramtica. Se pueden construir automticamente analizadores lxicos ms eficientes a partir de expresiones regulares que de gramticas arbitrarias. Separar la estructura sintctica de un lenguaje en partes lxicas y no lxicas proporciona una forma conveniente de modularizar la etapa inicial de un compilador en dos componentes de tamao razonable. Las expresiones regulares son muy tiles para describir la estructura de construcciones lxicas y las gramticas son muy tiles para describir construcciones anidadas (recursivas).

Comprobacin del lenguaje generado por una gramtica


Una prueba de que una gramtica G genera un lenguaje L tiene dos partes: se debe demostrar que toda cadena generada por G est en L, y que toda cadena de L puede ser generada por G. Considrese la gramtica Esta gramtica genera todas las cadenas de parntesis equilibrados Para comprobarlo, primero se demostrar que toda frase derivable de S est equilibrada y despus, que toda cadena equilibrada es derivable de S. Para demostrar que toda frase derivable de S est equilibrada, se usa una prueba inductiva sobre el nmero de pasos de una derivacin. Para el paso base, se observa que la nica cadena de terminales derivable de S en un paso es la cadena vaca, que sin duda est equilibrada.

Comprobacin del lenguaje generado por una gramtica


Ahora supngase que todas las derivaciones de menos de n pasos producen frases equilibradas y considrese una derivacin por la izquierda de exactamente n pasos. Dicha derivacin debe tener la forma Las derivaciones x e y a partir de S ocupan menos de n pasos, de modo que, por la hiptesis de induccin, x e y estn equilibradas. Por tanto, la cadena (x)y debe estar equilibrada. A continuacin se debe demostrar que toda cadena equilibrada es derivable de S. Para hacerlo, se utiliza induccin sobre la longitud de una cadena. Para el paso base, la cadena vaca es derivable de S. Ahora, supngase que toda cadena equilibrada de longitud menor que 2n es derivable de S y considrese una cadena equilibrada w de longitud 2n, n>=1. Sin duda, w comienza con un parntesis izquierdo. Sea (x) el prefijo ms corto de w que tenga un nmero igual de parntesis izquierdos y derechos. Entonces w se puede escribir (x)y, donde tanto x como y estn equilibrados. Puesto que x e y son de longitud menor que 2n, son derivables de S por la hiptesis de induccin. Por tanto, se puede encontrar una derivacin de la forma lo cual demuestra que w = (x)y tambin es derivable de S.

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.

Eliminacin de la recursin por la izquierda


Una gramtica es recursiva por la izquierda si tiene un no terminal A tal que existe una derivacin para alguna cadena a. Los mtodos de anlisis sintctico descendente no pueden manejar gramticas recursivas por la izquierda, as que se necesita una transformacin que elimine la recursin por la izquierda. Cualquier par de producciones recursivas por la izquierda se pueden sustituir por las producciones no recursivas por la izquierda sin modificar el conjunto de cadenas derivables de A.

Eliminacin de la recursin por la izquierda

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

El no terminal S es recursivo por la izquierda, por que inmediato por la izquierda

, pero no es recursivo

Algoritmo eliminar la recursin por la izquierda

Eliminacin de la recursin por la izquierda


Ejemplo Considrese la siguiente gramtica para expresiones aritmticas.
Ejemplo: Aplicar el algoritmo para eliminar recursividad por la izquierda a la gramtica

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.

Factorizacin por la izquierda

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

Algoritmo para factorizar una gramtica por la izquierda

Factorizacin por la izquierda


Ejemplo: La siguiente gramtica resume el problema del else ambiguo: Aqu, i, t y e representan if, then y else; E y P representan "expresin" y "proposicin". Factorizada por la izquierda, esta gramtica se convierte en: Asi, se puede expandir P a iEtPP' con la entrada i, y esperar hasta que iEtP haya aparecido para decidir si expandir P' a ePr o a . Por supuesto, las gramticas anteriores son ambiguas, y con la entrada e, no est claro qu alternativa de P' se debera elegir.

Anlisis Sintctico Descendente


La idea es conocer a que se refiere ste y aprender a construir un analizador sintctico sin retroceso, de manera efectiva. Tambin conocer las gramticas LL(1), a partir de las cuales se pueden construir analizadores sintcticos predictivos. Y finalmente un anlisis sobre la recuperacin de errores.

Anlisis sintctico por descenso recursivo


Se puede considerar el anlisis sintctico descendente como un intento de encontrar una derivacin por la izquierda para una cadena de entrada. Tambin se puede considerar como un intento de construir un rbol de anlisis sintctico para la entrada comenzando desde la raz y creando los nodos del rbol en orden previo. Un caso especial del anlisis sintctico por descenso recursivo, llamado anlisis sintctico predictivo, no necesita retroceso.

Anlisis sintctico por descenso recursivo


Ejemplo. Considrese la gramtica y la cadena de entrada w = cad. Raz del rbol S El siguiente smbolo de la entrada es c. Segunda regla ab. Falla, se retorna a A y se intenta con a.

Analizadores Sintcticos Predictivos


Escribiendo con cuidado una gramtica, eliminando su recursin por la izquierda y factorizando por la izquierda se puede obtener una gramtica analizable con un analizador sintctico por descenso recursivo que no necesite retroceso. un analizador sintctico predictivo. Para construir un analizador sintctico predictivo, se debe conocer, dado el smbolo actual a de entrada y el no terminal A a expandir, cul de las alternativas de produccin es la nica alternativa que da lugar a una cadena que comience con a. La alternativa apropiada debe ser detectable con slo ver el primer smbolo al que da lugar. As se detectan generalmente las construcciones de flujo de control de la mayora de los lenguajes de programacin, con sus palabras clave diferenciadoras.

Anlisis sintctico predictivo no recursivo


Se puede construir un analizador sintctico predictivo no recursivo explcitamente manteniendo una pila, en lugar de hacerlo implcitamente mediante llamadas recursivas. El problema clave durante el anlisis sintctico predictivo es determinar la produccin que debe aplicarse a un no terminal.

Anlisis sintctico predictivo no recursivo


Un analizador sintctico predictivo guiado por tablas tiene un buffer de entrada, una pila, una tabla de anlisis sintctico y una cadena de salida. El buffer de entrada contiene la cadena que se va a analizar, seguida de $, un smbolo utilizado como delimitador derecho para indicar el fin de la cadena de entrada. La pila contiene una secuencia de smbolos gramaticales con $ en la parte de abajo, que indica la base de la pila. Al principio, la pila contiene el smbolo inicial de la gramtica encima de $. La tabla de anlisis sintctico es una matriz bidimensional M[A, a], donde A es un no terminal, y a es un terminal o el smbolo $.

Anlisis sintctico predictivo no recursivo


Se controla el analizador sintctico mediante un programa que se comporta como sigue: El programa tiene en cuenta X, el smbolo de la cima de la pila, y a, el smbolo en curso de la entrada. Estos dos smbolos determinan la accin del analizador. Existen tres posibilidades:
Si X = a = $, el analizador sintctico se detiene y anuncia el xito de la realizacin del anlisis.

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.

Anlisis sintctico predictivo no recursivo

Anlisis sintctico predictivo no recursivo

Anlisis sintctico predictivo no recursivo

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,

para toda i, PRIMERO(Xi) contiene .

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

Construccin de tablas de anlisis sintctico


Se puede utilizar el siguiente algoritmo para construir una tabla de anlisis sintctico predictivo para una gramtica G. Supngase que es una produccin con a en PRIMERO(a). El analizador sintctico expandir A por a cuando el smbolo actual de la entrada sea a. La nica complicacin surge cuando . En este caso, se debe expandir de nuevo A en a si el smbolo actual de la entrada est en SIGUIENTE(A), o si ya se ha alcanzado en $ de la entrada y $ est en SIGUIENTE(A).

Construccin de tablas de anlisis sintctico

Construccin de tablas de anlisis sintctico


Ejemplo. Aplicacin del algoritmo anterior a la gramtica

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.

Recuperacin de errores en el anlisis sintctico predictivo


La pila de un analizador sintctico no recursivo hace explcitos los terminales y no terminales que el analizador espera emparejar con el resto de la entrada. Durante el anlisis sintctico predictivo se detecta un error cuando el terminal de la cima de la pila no concuerda con el siguiente smbolo de entrada. Tambin cuando el no terminal A est en la cima de la pila, a es el siguiente smbolo de entrada, y la entrada M[A, a] de la tabla de anlisis sintctico est vaca.

Recuperacin de errores en el anlisis sintctico predictivo


La recuperacin en modo de pnico se basa en la idea de saltarse smbolos de la entrada hasta que aparezca un componente lxico que pertenezca a un conjunto seleccionado de componentes lxicos de sincronizacin. Su efectividad depende de la eleccin del conjunto de sincronizacin. Los conjuntos deben elegirse de forma que el analizador sintctico se recupere con rapidez de los errores con ms probabilidades de ocurrir en la prctica.

Recuperacin de errores en el anlisis sintctico predictivo


Algunas tcnicas heursticas son las siguientes: 1. Como punto de partida, se pueden colocar todos los smbolos de SIGUIENTE(A) dentro del conjunto de sincronizacin para el no terminal A. Si se saltan componentes lxicos hasta encontrar un elemento de SIGUIENTE(A) y se saca a A de la pila, es probable que el anlisis sintctico pueda continuar.

Recuperacin de errores en el anlisis sintctico predictivo


2. No es suficiente usar SIGUIENTE(A) como conjunto de sincronizacin para A. Por ejemplo, si los smbolos de punto y coma terminan las proposiciones, como en C, entonces las palabras clave que comienzan proposiciones pueden no aparecer en el conjunto SIGUIENTE del no terminal que genera las expresiones. Por tanto, un punto y coma que falte despus de una asignacin puede dar como resultado que se salte la palabra clave que inicia la siguiente proposicin. Se pueden aadir al conjunto de sincronizacin de una construccin de menor jerarqua los smbolos que inician las construcciones de mayor jerarqua.

Recuperacin de errores en el anlisis sintctico predictivo


3. Si se aaden smbolos de PRIMERO(A) al conjunto de sincronizacin para el no terminal A, entonces se puede continuar el anlisis sintctico segn A si aparece en la entrada un smbolo de PRIMERO(A). 4. Si un no terminal puede generar la cadena vaca, se puede usar la produccin que derive a como alternativa por omisin. 5. Esto puede posponer alguna deteccin de errores pero no la omisin de un error. Este mtodo reduce el nmero de no terminales que hay que considerar durante la recuperacin del error.

Recuperacin de errores en el anlisis sintctico predictivo


5. Si no se puede emparejar un terminal de la cima de la pila, una idea sencilla es sacar el terminal, emitir un mensaje que indique que se insert el terminal y continuar el anlisis. En realidad, este mtodo considera al conjunto de sincronizacin de un componente lxico como si estuviera compuesto por todos los otros componentes lxicos.

Recuperacin de errores en el anlisis sintctico predictivo


Ejemplo Utilizar los smbolos de SIGUIENTE y PRIMERO como componentes lxicos de sincronizacin segn la gramtica (4.11). La tabla de anlisis sintctico para esta gramtica se muestra a continuacin:

Recuperacin de errores en el anlisis sintctico predictivo


"sinc" indica los componentes lxicos de sincronizacin obtenidos del conjunto SIGUIENTE del no terminal en cuestin. Si el analizador sintctico busca la entrada M[A, a] y ve que est en blanco, debe saltarse el smbolo de entrada a.

Recuperacin de errores en el anlisis sintctico predictivo


Si la entrada es sinc, se saca el no terminal de la cima de la pila para continuar el anlisis siempre y cuando la pila tenga ms de dos smbolos (un no terminal y $) En ese caso se salta el smbolo de la entrada. Si un componente lxico de la cima de la pila no concuerda con el smbolo de entrada, entonces se saca el componente lxico de la pila de igual manera siempre y cuando la pila tenga mas de dos smbolos, sino se salta el smbolo de la entrada.

Recuperacin de errores en el anlisis sintctico predictivo

Anlisis Sintctico Ascendente


Tambin conocido como anlisis sintctico por desplazamiento y reduccin. Este intenta construir un rbol de anlisis sintctico para una cadena de entrada que comienza por las hojas (el fondo) y avanza hacia la raz (la cima). Se puede considerar este proceso como de reducir una cadena w al smbolo inicial de la gramtica S.

Anlisis Sintctico Ascendente


En cada paso de la reduccin, se sustituye una subcadena que concuerde con el lado derecho de una produccin por el smbolo del lado izquierdo.

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

Anlisis sintctico por precedencia de operadores


Existe un subconjunto de gramtica con la propiedad de que ningn lado derecho de una produccin es ni tiene dos no terminales adyacentes. Este tipo de gramticas se llaman gramtica de operadores. Son viables para implementar un analizador sintctico a mano, por desplazamiento y reduccin.

Anlisis sintctico por precedencia de operadores

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.

Anlisis sintctico por precedencia de operadores


Aunque su sencillez ha permitido que se construyan muchos compiladores que usan esta tcnica, para parte del lenguajes (expresiones) o para el lenguaje completo. El anlisis sintctico por precedencia de operadores define 3 relaciones de precedencia disjuntas entre algunos pares de terminales:

Anlisis sintctico por precedencia de operadores


Su significado es:

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.

Anlisis sintctico por precedencia de operadores

Anlisis sintctico por precedencia de operadores

También podría gustarte