Lenguajes y Automatas II - Repaso

61
1 REPASO DE SINTAXIS Programación de sistemas. Conjunto de reglas para crear soluciones a problemas computables. Conjunto de herramientas que nos permiten crear software de base que son de utilidad para interactuar con la máquina. Software de base. Compilador, Sistema Operativo, Cargador. Autómata. Son las cadenas posibles que aceptan un lenguaje. Expresiones regulares. Conjunto de símbolos que aceptan una palabra reservada. Gramática. Reglas para escribir las sentencias del lenguaje. Lenguaje de programación. Un lenguaje de programación está formado por un conjunto de símbolos básicos (alfabeto) y un conjunto de reglas que especifican como manipularlos. También debe darle significado a las cadenas formadas al manipular los símbolos básicos. Los lenguajes de programación pueden clasificarse de acuerdo a su semejanza con el lenguaje maquina (bajo nivel) o a su semejanza con el lenguaje humano, generalmente inglés (Lenguajes de alto nivel).Entre los lenguajes de bajo nivel se encuentra el lenguaje ensamblador. Un programa escrito en un lenguaje de programación necesita pasar por un proceso de compilación, es decir, ser traducido al lenguaje de máquina, o ser interpretado para que pueda ser ejecutado por el ordenador. Los lenguajes son sistemas de comunicación. Un lenguaje de programación consiste en todos los símbolos, caracteres y reglas de uso que permiten a las personas comunicarse con las computadoras. Existen por lo menos varios cientos de lenguajes y dialectos de programación diferentes. Algunos se crean para una aplicación especial, mientras que otros son herramientas de uso general más flexibles que son apropiadas para muchos tipos de aplicaciones. En todo caso los lenguajes de programación deben tener instrucciones que pertenecen a las categorías ya familiares de entrada/salida, cálculo/manipulación de textos, lógica/comparación y almacenamiento/recuperación. No obstante, aunque todos los lenguajes de programación tienen un conjunto de instrucciones que permiten realizar dichas operaciones, existe una marcada diferencia en los símbolos, caracteres y sintaxis de los lenguajes de máquina, lenguajes ensambladores y lenguajes de alto nivel.

description

Resumen sobre aspectos básicos en la materia de lenguajes y automatas

Transcript of Lenguajes y Automatas II - Repaso

  • 1

    REPASO DE SINTAXIS Programacin de sistemas. Conjunto de reglas para crear soluciones a problemas computables. Conjunto de herramientas que nos permiten crear software de base que son de utilidad para interactuar con la mquina. Software de base. Compilador, Sistema Operativo, Cargador. Autmata. Son las cadenas posibles que aceptan un lenguaje. Expresiones regulares. Conjunto de smbolos que aceptan una palabra reservada. Gramtica. Reglas para escribir las sentencias del lenguaje. Lenguaje de programacin. Un lenguaje de programacin est formado por un conjunto de smbolos bsicos (alfabeto) y un conjunto de reglas que especifican como manipularlos. Tambin debe darle significado a las cadenas formadas al manipular los smbolos bsicos.

    Los lenguajes de programacin pueden clasificarse de acuerdo a su semejanza con el lenguaje maquina (bajo nivel) o a su semejanza con el lenguaje humano, generalmente ingls (Lenguajes de alto nivel).Entre los lenguajes de bajo nivel se encuentra el lenguaje ensamblador.

    Un programa escrito en un lenguaje de programacin necesita pasar por un proceso de compilacin, es decir, ser traducido al lenguaje de mquina, o ser interpretado para que pueda ser ejecutado por el ordenador.

    Los lenguajes son sistemas de comunicacin. Un lenguaje de programacin consiste en todos los smbolos, caracteres y reglas de uso que permiten a las personas comunicarse con las computadoras. Existen por lo menos varios cientos de lenguajes y dialectos de programacin diferentes. Algunos se crean para una aplicacin especial, mientras que otros son herramientas de uso general ms flexibles que son apropiadas para muchos tipos de aplicaciones. En todo caso los lenguajes de programacin deben tener instrucciones que pertenecen a las categoras ya familiares de entrada/salida, clculo/manipulacin de textos, lgica/comparacin y almacenamiento/recuperacin. No obstante, aunque todos los lenguajes de programacin tienen un conjunto de instrucciones que permiten realizar dichas operaciones, existe una marcada diferencia en los smbolos, caracteres y sintaxis de los lenguajes de mquina, lenguajes ensambladores y lenguajes de alto nivel.

  • 2

    Traductores Un traductor es un programa que recibe como entrada cdigo escrito en un cierto lenguaje (programa fuente) y produce como salida cdigo en otro lenguaje (programa objeto). Generalmente el lenguaje de entrada es de ms alto nivel que el de salida. Ejemplos de traductores son los ensambladores y los compiladores. Un ensamblador es un programa que traduce de un lenguaje ensamblador a lenguaje mquina, mientras que un compilador es un programa que traduce de un lenguaje de alto nivel a un lenguaje de bajo nivel o a lenguaje mquina. Si el fuente es un lenguaje de alto nivel y si el objetivo es un lenguaje de ensamble de bajo nivel o de mquina, el traductor es un compilador. Diseo de lenguajes. El lenguaje de programacin puede definirse al describir 1. Lo que parecen sus programas (la sintaxis del lenguaje) 2. lo que significan sus programas (la semntica del lenguaje).

    La sintaxis es la disposicin de palabras como elementos en una oracin para mostrar su relacin, describe la serie de smbolos que constituyen programas validos. El enunciado en C: X=Y+Z representa una serie vlida de smbolos, en tanto que X,Y+- no representa una secuencia valida de smbolos para un programa en C.

    La sintaxis suministra informacin significativa que se necesita para entender un programa y proporciona informacin imprescindible para la traduccin del programa fuente o un programa objeto. Ejemplo de la expresin: 2+3*4 tiene el valor de 14 y no 20, se puede especificar una u otra interpretacin, si se desea, por sintaxis y con ello guiar al traductor a la generacin de las operaciones correctas para evaluar esta expresin.

    Como en la expresin ambigua en espaol, nada en el agua, el solo desarrollo de una sintaxis de lenguaje es insuficiente para especificar sin ambigedad la estructura de un enunciado. En un enunciado como X= 2.45+3.67, la sintaxis no nos puede decir si se declar la variable X, o si X se declaro como tipo real.

    Los resultados de X=5, X=6 y X=6.12, son todos posibles si X y + denotan enteros, X denota un entero y + es adicin de nmeros reales, y X y + denotan valores reales, respectivamente. Se necesita algo ms que solo estructuras sintcticas, para la plena descripcin de un lenguaje de programacin. Otros atributos, bajo el trmino general de semntica, como en el uso de declaraciones, operaciones, control de secuencia y entornos de refinamiento, afecta a una variable y no siempre estn determinados por reglas de sintaxis.

    Criterios generales de sintaxis.

    El propsito primordial de la sintaxis es proveer una notacin para la comunicacin entre el programador y el procesador de lenguajes de programacin. Sin embargo, la eleccin de estructuras sintcticas particulares esta restringida slo ligeramente por la necesidad de comunicar elementos particulares de informacin. A continuacin se citan criterios generales de sintaxis.

  • 3

    Legibilidad

    Facilidad de escritura

    Facilidad de verificacin

    Facilidad de traduccin

    Carencia de ambigedad

    ELEMENTOS SINTCTICOS DE UN LENGUAJE

    Conjunto de caracteres

    Smbolos de operadores

    Palabras clave y palabras reservadas

    Palabras pregonadas

    Comentarios

    Espacios en blanco

    Delimitadores y corchetes

    Formatos de campos libres y fijos

    Expresiones

    Enunciados

    EJEMPLO DE SMBOLOS QUE COMPONEN UN PROGRAMA:

    LENGUAJE

    PASCAL

    DELIMITADORES

    OPERACIONALES

    +,-,*,/,MOD

    PALABRAS RESERVADAS

    :=ASIGNACION

    RELACIONALES

    ==>b Entonces a=c+d: FinEntonces: pasara a ser Si a>b Entonces a=c+d: FinEntonces: en nuestra lista de entrada.

    Una vez que tenemos la lista de entrada limpia se procede a la creacin de los tokens; para ello, se ha definido otro tipo de lista llamado Tokens que contendr el nombre del token (cadena leda por la pantalla) junto con el tipo al que pertenece.

    La implementacin del analizador lxico responde al mtodo general de

    programacin visto en teora, por lo tanto se manejan dos punteros, uno al ltimo carcter ledo y otro al ltimo carcter aceptado con lo cual podemos movernos por la lista de entrada en bsqueda del siguiente token sin perder la posicin desde donde comenzamos la presente bsqueda. Los tokens, o smbolos terminales de la gramtica, han sido representados mediante dos tablas, una para los que van acompaados de un parntesis y otra para los que no.

    El motivo de esta separacin ha sido el trato distinto que se les ha dado a

    ambos para no tener que distinguir, dentro de las rdenes que lleva un parmetro, si entre el final de la orden y el parntesis que rodea al parmetro hay o no espacios. As las ordenes Mira (id) y Mira(id) son tratadas como el mismo token y toman el ``('' como parte de l.

    Los smbolos separadores (espacios, ``:'', etc.) han sido recogidos del mismo modo en otra tabla dado el trato distinto de los anteriores que recibirn.

    Con esta forma de recoger los tokens que reconoce este analizador hemos conseguido no tener que realizar grandes modificaciones sobre esta fase del compilador, si algn da fuera modificado el conjunto de smbolos terminales de la gramtica.

    ANLISIS LXICO: DESARROLLO Objetivo

    El objetivo bsico del scanner o analizador lxico es separar el programa fuente en unidades mnimas y asociarles una determinada clase o token. Por qu? Formalmente, para separar lo lineal de lo jerrquico. En el scanner no hay que

    mirar hacia atrs: las unidades lxicas se forman con caracteres siempre consecutivos y no pueden solaparse dos unidades lxicas. Hay que tener en cuenta que las reglas lxicas son bastante sencillas y no necesitan una notacin tan poderosa como una gramtica; las expresiones regulares son ms sencillas y fciles de entender que una gramtica.

  • 21

    Eficiencia, porque es el nico proceso que lee el programa fuente y por ello pueden estudiarse tcnicas especializadas de manejo de dispositivos de almacenamiento (la eficiencia es ms fcilmente alcanzable partiendo de expresiones regulares que de gramticas).

    Diseo modular del compilador, relacionado con esto ltimo. Portabilidad, ya que la mayora de diferencias del mismo lenguaje entre distintos

    entornos suele ser en caracteres especiales, capitalizacin, cdigos de caracteres, etc. y as se encapsulan en el scanner.

    Funciones del scanner Las funciones bsicas del scanner son:

    Leer el programa fuente Delimitar los lexemas Identificar cada token Asignar atributo a cada unidad lxica

    Para hacer la interaccin con el parser, lo ms habitual es convertir al scanner en

    una subrutina del parser, para que as pueda responder a la orden "obtener la siguiente unidad lxica" recibida del parser.

    Como el scanner lee el programa fuente, tambin realiza ciertas funciones secundarias como son eliminar comentarios y caracteres no significativos (espacios, tabuladores, retornos de carro...) o preprocesar las macros.

    Otra funcin secundaria del analizador lxico es relacionar los mensajes de error

    con el programa fuente (ya que para que al usuario le sean significativos es necesario que no se pierda esta relacin).

    En este sentido, en algunos compiladores el scanner va produciendo una copia

    del fuente en la que se marcan los mensajes de error, se expanden las macros, etc.

    La ltima funcin del scanner es detectar los errores lxicos que puedan producirse. A este nivel, los errores se restringen a localizar caracteres no reconocidos, combinaciones de caracteres imposibles, o intentos de lectura por detrs del fin de fichero. Tipos de unidades lxicas: concepto de patrn Hay dos clases de unidades lxicas: Las definidas por el lenguaje: palabras clave, operadores, smbolos especiales.

    Nmero finito (quizs 1) de lexemas. Las definidas por el programador (bajo ciertas normas genricas): identificadores,

    literales, comentarios. Normalmente, el nmero "posible" de lexemas es infinito.

    El patrn de las primeras es la simple enumeracin de los lexemas; de las segundas, una serie de normas que describen todas las cadenas que corresponden al mismo token.

  • 22

    El patrn permite identificar el token y asignar el atributo (suponiendo delimitado el lexema). Es decir, una vez delimitado el lexema, cumplir algn patrn, y ese es el que marca el token. Se dice que el patrn concuerda con el lexema que cumple ese patrn.

    De este modo, lo primero que debe definirse en todo lenguaje de programacin

    es una tabla con todos los patrones lxicos del lenguaje indicando token y atributo para cada patrn. Por ejemplo, tomando un subconjunto de JAVA:

    Token Lexemas ejemplo Descripcin del patrn

    pc-then then (t/T)(h/H)(e/E)(n/N)

    pc-while while while

    pc-printf write write

    op-rel < <

    > >

    par-ab ( (

    par-cer ) )

    ident Hola, A77aH, pepe

    Letra seguida de letras y dgitos

    lit-ent 34, 23442, 1 Dgito no cero seguido de dgitos

    lit-real 34.0, 23.4e-5 Dgito no cero seguido de dgitos seguido opcionalmente de punto decimal y dgitos, seguido opcionalmente de 'E' o 'e' y dgitos

    lit-string 'Hola', 'pe pe ' Caracteres entre ', excepto '

    En la mayora de los lenguajes se consideran tokens las construcciones: palabras clave, operadores, identificadores, literales y signos de puntuacin. Por supuesto, dependiendo del lenguaje se subdividirn en varios componentes lxicos ms.

    Normas lxicas El problema ahora es cmo delimitamos el lexema? En un principio,

    podramos pensar en utilizar un carcter fijo para delimitar lexemas, por ejemplo el espacio. De este modo, la sentencia

    if A < 50 then write ( 4 )

    puede verse fcilmente separada en los lexemas "if", "A", "

  • 23

    En este funcionamiento es fundamental, por ello, la influencia de las distintas normas lxicas: si las palabras clave pueden usarse como identificadores, cules son los separadores, etc. De hecho, la evolucin de los distintos lenguajes de programacin ha ido tendiendo a utilizar reglas lxicas que hagan cada vez ms sencillo el desarrollo del scanner. Vamos a enunciar brevemente las ms influyentes en este sentido: En general, los espacios (y tambin tabuladores y retornos) no son significativos

    (es decir, no forman parte de ningn lexema ni constituyen un token) pero s son separadores.

    Las palabras clave suelen ser reservadas. Cuando no lo son (por ejemplo, en

    PL/I), el scanner debe distinguir entre palabras clave e identificadores, lo cual suele ser complicado. Por ejemplo:

    if then then then = else ; else else = then;

    El scanner, no puede diferenciar entre identificadores y palabras clave, o bien diferenciarlos le supone trabajo "extra".

    En caso de conflicto, se elige el lexema ms largo. Por ejemplo, ifa es el identificador ifa y no la palabra clave if seguida del identificador a. Esto es lgico porque si no limitaramos mucho los identificadores, al no poder indicar ninguna variable ni nombre de procedimiento o funcin empezada por do, ni por if, ni por or, ni por and ... (imaginemos lo que ocurrira con lenguajes con muchas palabras reservadas).

    El problema del anlisis lxico, se reduce entonces a reconocer el cumplimiento

    de patrones por determinados lexemas. Hay dos herramientas formales que nos permiten hacer este trabajo de un modo muy sencillo: Los autmatas finitos.

    Son las posibles cadenas que acepta un lenguaje. Se compila una expresin regular en un reconocedor construyendo un diagrama de transicin que es una instrumentacin de un modelo formal denominado autmatas finitos, conocidos tambin como mquinas de estado finito o (con menos frecuencia en la actualidad) mquinas secuenciales. Es la representacin grfica de las posibles cadenas que acepta un lenguaje dentro de un conjunto de smbolos, se conforma por una quntupla donde: Q es el conjunto de posibles estados

    representa al alfabeto

  • 24

    representa la funcin de transicin y los estados por los que se acepta cada uno de los smbolos

    qo estado inicial F conjunto de estados finales

    Las expresiones regulares.

    Son los posibles smbolos que puede aceptar un lenguaje los cuales se pueden representar con un autmata. Conjunto de smbolos para aceptar una palabra reservada.

    Una expresin regular es una frmula para denotar "ciertos" lenguajes. Advirtase que decimos lenguaje, no cadena de caracteres. Una expresin regular nica denota un conjunto de cadenas, es decir un lenguaje, no una simple cadena. Las expresiones regulares se pueden usar para especificar unidades lxicas presentes en un lenguaje de programacin. No todos los lenguajes pueden ser expresados utilizando una expresin regular.

    Sea un alfabeto . La expresin regular sobre y los conjuntos que denotan se definen de manera recursiva como sigue:

    1. es una expresin regular y denota al conjunto vaco {}.

    2. Para cada a , a es una expresin regular y denota al conjunto {a}. 3. Si r y s son expresiones regulares que denotan a los lenguajes R y S.;

    respectivamente, entonces tenemos lo siguiente.

    r+s es una expresin regular que denota a los conjuntos R S. (r) es una expresin regular que denota al conjunto R. rs es una expresin regular que denota a los conjuntos RS. r* es una expresin regular que denota al conjunto R*, equivale desde

    cero a ms repeticiones del lenguaje R. r+ es una expresin regular que denota al conjunto R+, equivale a una

    o ms repeticiones del lenguaje R. ri es una expresin regular que denota al conjunto Ri, a s mismo.

    Errores Lxicos Son pocos los errores detectables en el analizador lxico porque se tiene una visin restringida del programa, ya que no se puede distinguir entre un error de escritura de un identificador y una palabra reservada, as como la declaracin y utilizacin de una funcin, porque todas las consideran en esta fase como un identificador vlido y los errores se empiezan a detectar entre el analizador semntico o el analizador sintctico, segn sea el caso. Tcnicas de correccin de errores

  • 25

    Existen algunas tcnicas de correccin que son utilizadas en compiladores, sin embargo no es conveniente modificar la idea original, ni la lgica de programacin del usuario. Las tcnicas son las siguientes:

    a) Modo de pnico. Donde se guardan los caracteres sucesivos de la entrada restante, hasta encontrar un componente lxico vlido.

    b) Borrar un carcter extrao que no haya sido declarado o definido dentro del lenguaje

    c) Insertar un carcter que falte d) Reemplazar un carcter faltante e) Intercambiar caracteres adyacentes

    TABLAS DE SMBOLOS

    Es una estructura de datos que contiene un registro por cada token o identificador que define los atributos de ellos mismos. La estructura de datos permite encontrar rpidamente el registro para ser almacenado o consultado por otras fases. Cuando el anlisis lxico detecta un token en el programa fuente, este se introduce e la tabla de smbolos, sin embargo, sus atributos no pueden determinarse durante el anlisis lxico. Por ejemplo, dada la siguiente instruccin: Var inicial, velocidad: integer ;

    Token Valor Posicin en

    memoria Utilizado

    por

    ; Delimitador

    integer P. R. Int

    : S. Punt.

    velocidad Id

    , Separador

    inicial Id

    Var P. R. Var

    El tipo entero no se conoce cuando el analizador lxico pasa por toda la

    instruccin, las fases restantes introducen informacin sobre los tokens en la tabla y despus hace uso de ella.

    Cuando se hace el anlisis semntico y la generacin de cdigo intermedio se

    necesita saber los tipos de cada uno de los identificadores para comprobar si el programa fuente los usa en forma vlida y as generar las operaciones apropiadas con ellos.

    MTODOS GENERALES PARA LA IMPLANTACIN DE UN ANALIZADOR LXICO

  • 26

    a) Utilizar un generador de analizador lxico automtico. Por ejemplo: La herramienta Lex, que proporciona rutinas para leer la entrada y generar componentes lxicos.

    b) Describir el analizador lxico en un lenguaje convencional de programacin utilizando subrutinas de entrada / salida.

    c) Escribir el analizador lxico en lenguaje ensamblador.

  • 27

    ANLISIS SINTCTICO

    El objetivo fundamental del anlisis sintctico es "construir un rbol sintctico" con la cadena de entrada (el "programa"), en la forma de unidades lxicas que determina el analizador lxico, como se muestra en la siguiente figura:

    El Analizador Sintctico dentro del modelo de un compilador.

    Si esto se consigue, el programa es (sintcticamente) correcto; y es incorrecto

    en caso contrario. Se supone que el analizador sintctico informar de cualquier error de sintaxis de manera inteligible. Tambin deber recuperarse de los errores que ocurren frecuentemente para poder continuar procesando el resto de su entrada.

    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 analizar cualquier gramtica. Estos mtodos sin embargo, son demasiado ineficientes para usarlos en la produccin de compiladores. Los mtodos empleados generalmente en la produccin de compiladores se clasifican como descendentes o ascendentes. Los dos tipos principales de anlisis sintctico son: Descendente: construye el rbol desde la raz hacia las hojas. Ascendente: construye el rbol desde las hojas hacia la raz.

    En ambos casos, se examina la entrada al analizador sintctico de izquierda a derecha, un smbolo a la vez. Los mtodos descendentes y ascendentes ms eficientes trabajan slo con subclases de gramticas.

    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 varias 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 tipo y otras clases de anlisis semntico. Para la implementacin del analizador sintctico debe de ser necesaria la redefinicin de la gramtica dada en la prctica de modo que sea ``entendible'' por la computadora. Dentro de la gramtica generada se deber eliminar la recursividad a izquierdas.

    Se sabe que los programas pueden contener errores de muy diversos tipos. Por ejemplo los errores pueden ser:

  • 28

    Lxicos, como escribir mal un identificador, palabra clave u operador.

    Sintcticos, como una expresin aritmtica con parntesis no equilibrados.

    Semnticos, como un operador aplicado a un operando incompatible.

    Lgicos, como una llamada infinitamente recursiva.

    A menudo, 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 o se manifiestan cuando la cadena de componentes lxicos que proviene del analizador lxico desobedece la reglas gramaticales que definen el lenguaje de programacin. Otra razn es la precisin de los mtodos modernos de anlisis sintctico, que pueden detectar la presencia de errores dentro de los programas de una forma muy eficiente. La deteccin exacta de la presencia de errores semnticos y lgicos en el momento de la compilacin es mucho ms difcil.

    El manejador de errores en un analizador sintctico tiene objetivos fciles de

    establecer:

    Debe de informar de la presencia de errores con claridad y exactitud.

    Se debe de recuperar de cada error con la suficiente rapidez como para detectar errores posteriores.

    No de be retrazar de manera significativa el procesamiento de programas correctos.

    Afortunadamente lo errores ms comunes son simples y a menudo basta con un mecanismo sencillo de manejo de errores. sin embargo, en algunos casos un error pudo haber ocurrido mucho antes de la posicin en que se detect su presencia, y puede ser muy difcil deducir su naturaleza precisa de error. En los casos difciles, el manejador de errores quiz tenga que adivinar qu tena en mente el programador cuando escribi el programa.

    Varios mtodos de anlisis sintctico, detectan un error lo antes posible. Es decir,

    tienen la propiedad del prefijo viable, la cual quiere decir que detectan la presencia de un error nada ms con ver un prefijo de la entrada que no es prefijo de ninguna cadena del lenguaje. Cmo debe informar un manejador de errores de la presencia de un error ?, al menos debe informar del lugar en el programa fuente donde se detecta el error, porque es muy probable que el error real se haya producido en alguno de los componentes lxicos anteriores. Una estrategia comn empleada por muchos compiladores e imprimir la lnea errnea con un apuntador a la posicin donde se detecta el error. 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 de recuperar el analizador sintctico ?, En la mayora de los casos, no es adecuado que el analizador sintctico abandone despus de detectar el primer error, porque el posterior procesamiento de

  • 29

    la entrada podra revelar ms errores. Normalmente, hay alguna forma de recuperacin del error donde el analizador sintctico intenta volver l mismo a un estado en el que el procesamiento de la entrada pueda continuar con una esperanza razonable de que har el anlisis de la entrada correcta o de que ser manejada correctamente por el compilador.

    Una estrategia conservadora para un compilador es inhibir los mensajes de error que provengan de errores descubiertos demasiado cerca uno de otros en la cadena de entrada. Despus de descubrir un error sintctico, el compilador podra exigir que varios componentes lxicos se analizarn sintcticamente con xito antes de permitir otro mensaje de error. En algunos casos, puede haber demasiados errores como para que el compilador contine un procesamiento razonable. Parece que una estrategia de recuperacin de errores tiene que ser un compromiso cuidadosamente considerado, teniendo en cuenta la clase de errores que se pueden presentar y que sean de procesamiento razonable. Algunos compiladores intentan reparar el error proceso en el cual el compilador intenta adivinar lo que pretenda escribir el programador.

    Hay muchas estrategias generales distintas que puede emplear un analizador sintctico para recuperarse de un error sintctico. Aunque ninguna de ellas ha demostrado ser la aceptacin universal, algunos mtodos tienen una amplia aplicabilidad. Mencionaremos algunas estrategias, entre las cuales estn:

    Recuperacin en modo de pnico: Este es el mtodo ms sencillo de implantar y pueden utilizarlo la mayora de los mtodos de anlisis sintctico. Al descubrir un error, el analizador sintctico desecha smbolo de entrada, de uno en uno, hasta que encuentra uno perteneciente a un conjunto designado de componente lxicos de sincronizacin. Estos componente lxicos de sincronizacin son generalmente delimitadores, como el punto y coma o la palabra clave end, cuyo papel en el programa fuente est claro. Es evidente que quien disea el compilador debe seleccionar los componentes lxicos de sincronizacin adecuados para el lenguaje fuente. Aunque la correccin en modo de pnico a menudo omite una cantidad considerable de entrada sin comprobar la existencia de errores adicionales, tiene la ventaja de la sencillez y, a diferencia de otros mtodos, esta garantizado contra lazos infinitos. En situaciones en donde son raros los errores mltiples en la misma proposicin, este mtodo puede resultar bastante adecuado.

    Recuperacin a nivel de frase: Al descubrir un error, el analizador sintctico puede realizar una correccin local de la entrada restante; es decir, puede 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 e insertar un punto y coma que falta. La eleccin de la correccin local corresponde al diseador del compilador. Por supuesto se debe de tener cuidado de elegir sustituciones que no conduzcan a lazos infinitos.

    Este tipo de sustitucin puede corregir cualquier cadena de entrada y ha sido empleado en varios compiladores que corrigen los errores. El mtodo se us por primera vez en el anlisis sintctico descendente. Su principal desventaja es su

  • 30

    dificultad para afrontar situaciones en que el error real se produjo antes del punto de deteccin.

    Producciones de error: Si se tiene una buena idea de los errores comunes que puede encontrarse, se puede aumentar la gramtica del lenguaje con producciones que generen la construcciones errneas. Entonces se usa esta gramtica aumentada con las producciones de error 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.

    Correccin global: Idealmente, sera deseable que un compilador hiciera el mnimo de cambios posibles al procesar una cadena de entrada incorrecta. 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 en general demasiado costosa en trminos de tiempo y espacio, as que estas tcnicas en la actualidad slo son de inters terico.

    Se debe sealar que un programa correcto ms parecido al original puede no

    ser lo que el programador tena en mente. Sin embargo, la nocin de correccin de costo mnimo proporciona una escala para evaluar las tcnicas de recuperacin de errores, y se ha usado para encontrar cadenas de sustitucin ptimas para recuperacin a nivel de frase.

    Gramticas.

    Las gramticas describen lenguajes. Los lenguajes naturales como el espaol, o el ingles, son con frecuencia descritos por una gramtica que agrupa las palabras en categoras sintcticas tales como sujetos, predicados, frases preposicionales, etc.

    Expresndolo en forma matemtica, una gramtica es un dispositivo formal

    para expresar un lenguaje potencialmente infinito, en una manera finita, puesto que es imposible enumerar todas las cadenas de caracteres en un lenguaje, ya sea espaol ingls o Pascal. Al mismo tiempo un gramtica impone una estructuras a la sentencias en el lenguaje. Es decir una gramtica, G, define un lenguaje L(G) mediante la definicin de una manera de para derivar todas las cadenas en el lenguaje. De una manera mas general:

    Una gramtica es un sistema para definir un lenguaje, como tambin una herramienta para imponer a las cadenas del lenguaje una estructura til.

    Una gramtica G es una 4-tupla G = {N,,P, S} donde:

  • 31

    N : alfabeto de no-terminales " n N n : alfabeto terminal

    P : Conjunto finito de producciones consistente de expresiones de la forma

    con (N )+ y (N )*

    S : smbolo inicial S N

    NS =

    GRAMTICAS Y LENGUAJES SENSIBLES AL CONTEXTO.

    Una forma de definir un lenguaje es mediante un reconocedor que acepte las palabras que pertenecen a l. Los lenguajes sensibles al contexto contienen, propiamente, a los lenguajes independientes al contexto a su vez, los lenguajes recursivos contienen propiamente a los lenguajes sensibles al contexto.

    DEFINICION FORMAL MATEMATICA DE LAS GRAMTICAS SENSIBLES AL

    CONTEXTO (CSGS)

    Es una 4-TUPLA formada por (N, S ,S ,P) donde: N: Coleccin de smbolos no terminales.

    : Alfabeto del lenguaje. S: Smbolo especial llamado smbolo inicial.

    P: Conjunto de producciones si todas las producciones son de la forma ,

    donde , (N U )+ y | |

  • 32

    deterministico

    Lenguaje sensible al contexto

    +Gramtica Sensible al contexto

    Autmata Lineal-Vinculada

    abc

    Lenguajes Recursivos

    Enumerables

    + Gramtica no-restringida

    Maquina de Turng Cualquier Funcin

    Computable

    Jerarqua de Chomsky.

    En 1959, Noam Chomsky clasific las gramticas en cuatro tipos de lenguajes y esta clasificacin es conocida como la jerarqua de Chomsky, tal como se muestra en al Tabla 3.1, en la cual cada lenguaje es descrito por el tipo de gramtica generado. Estos lenguajes sirven como base para la clasificacin de lenguajes de programacin.

    Los cuatro tipos son: lenguajes recursivamente enumerables, lenguajes sensibles al contexto, lenguajes libres de contexto y lenguajes regulares. Dichos lenguajes tambin se identifican como lenguajes de tipo 0,1,2 y 3.

    Las gramticas sensibles al contexto reciben el nombre de gramticas de tipo 1, porque del lado izquierdo puede haber ms de un elemento, lo que implica que un smbolo puede reemplazarse en el contexto de otros.

    Una gramtica es de tipo 1 si se exige que la longitud del miembro derecho de toda regla de produccin sea mayor o igual que la longitud del izquierdo. Con esto se impide que las cadenas que se obtengan en el transcurso de la aplicacin de las reglas sean de longitud decreciente, y se impide as mismo el caso extremo de que mediante una gramtica de tipo1 puedan desaparecer cadenas de smbolo.

    Gramtica y lenguaje Reconocedor

    Que genera Autmatas lineal

    TIPO 1

    (Sensible al contexto)

    Entre las gramticas no restringidas y la forma restringida de las gramticas

    independientes al contexto, se pueden definir varias gramticas con diferentes niveles de restriccin.

    Existe una exacta correspondencia entre cada uno de estos tipos de lenguajes y particulares arquitecturas de mquinas en el sentido que por cada lenguaje tipo T hay una arquitectura de mquina A que reconoce el lenguaje A hay un tipo T tal que todos los lenguajes reconocidos por A son de tipo T. La correspondencia entre lenguajes y arquitectura son mostrados en la siguiente tabla:

    Tipo Lenguajes Tipo de Mquina

    0 Recursivamente Enumerables

    Mquina de Turing

    1 Sensibles al Autmata

  • 33

    contexto Lineal Acotado

    2 Libres de contexto Autmatas de Pila

    3 Lenguajes Regulares

    Autmatas Finitos y Expresiones Regulares

    Los cuatro tipos de gramticas.

    Sobre un alfabeto dado, el conjunto de lenguajes recursivamente enumerables contiene propiamente al conjunto de lenguajes recursivos que contiene propiamente al conjunto de lenguajes sensibles al contexto que contiene propiamente al conjunto de lenguajes libres de contexto, que a su vez contiene propiamente a los lenguajes regulares, tal como se muestra:

    Gramticas Ambiguas

    Si una oracin en espaol tiene mas de un significado, se dice que es ambigua. Con frecuencia tales oraciones pueden analizarse sintcticamente en mas de una forma. La oracin:

    El tiempo vuela como una flecha.

  • 34

    Puede interpretarse tiempo como sustantivo, vuela como verbo y una flecha, como una frase adverbial. Esta interpretacin es un comentario acerca del rpido paso del tiempo. Sin embargo, si "tiempo" se interpreta como adjetivo, "vuela" como sustantivo, "como" como un verbo y flecha como un sujeto directo, la oracin se convertira en un comentario acerca de la vida amorosa de alguna especie.

    En forma similar, se asigna significado a las construcciones en los lenguaje de programacin con base en sus sintaxis. Por consiguiente, preferimos que las gramticas de los lenguajes de programacin describan programas sin ambigedad alguna.

    Una sentencia es ambigua si hay mas de una derivacin distinta. Si una sentencia es ambigua, su rbol de anlisis sintctico no es nico; podemos crear mas de un rbol sintctico para la misma sentencia.

    Una gramtica se dice que es ambigua si hay dos o ms rboles de

    derivacin distintos para la misma cadena.

    Para ver lo anterior consideraremos esta gramtica. O lo que es lo mismo:

    Es la gramtica que produce mas de una derivacin por la derecha o por la izquierda para la misma frase

    S SbS | ScS | a Podemos derivar la cadena "abaca" de dos formas distintas como sigue:

    S SbS SbScS SbSca Sbaca abaca

    S ScS SbScS abScS abacS abaca El rbol de derivacin para la derivacin 1 es el que se muestra en la Figura:

    Primer rbol de derivacin para la gramtica dada.

    mientras que el rbol para la derivacin 2 es el que se muestra en la siguiente figura:

  • 35

    Segundo rbol de derivacin para la gramtica dada.

    Obsrvese que los dos rboles son distintos, aunque las cadenas producida

    son la misma. La ambigedad puede ser un problema para ciertos lenguajes en los que su significado depende, en parte, de su estructura, como ocurre con los lenguajes naturales y los lenguajes de programacin. Si la estructura de un lenguaje tienen ms de una composicin y si la construccin parcial determina su significado, entonces el significado es ambiguo. La ambigedad no siempre es una propiedad inherente de los lenguajes; existen gramticas ambiguas y no ambiguas para algunas construcciones.

    Para demostrar que una gramtica es ambigua, lo nico que hay que hacer es encontrar una cadena de componentes lxicos que tanga mas de un rbol sintctico. Como una cadena que cuenta con mas de un rbol sintctico suele tener mas de un significado, para aplicaciones de compilacin es necesario disear gramticas no ambiguas o utilizar gramticas ambiguas con reglas adicionales para resolver las ambigedades.

    Recurdese que una gramtica independiente del contexto es ambigua si hay dos derivaciones por la izquierda que son distintas para la misma cadena. La gramtica independiente del contexto:

    S ASB |SS | B b

    Es ambigua, ya que hay dos derivaciones por la izquierda de a2b2. Por desgracia, en general no es posible determinar si una gramtica

    independiente del contexto es ambigua. Es decir, la cuestin de la ambigedad de gramticas independientes del contexto. CONCEPTOS:

  • 36

    SMBOLO TERMINAL: Es un smbolo que no aparece en el lado izquierdo de ninguna produccin. NO TERMINALES: Los no-terminales son los nodos no-hojas en un rbol de anlisis sintctico. PRODUCCIONES: Se pueden pensar como un conjunto de reglas de reemplazo. SMBOLO DE INICIO: El smbolo de partida o de inicio, tambin denominado smbolo meta es un no- terminal especial diseado como el nico a partir del cual todas las cadenas son derivadas. FORMA SENTENCIAL: Una forma sentencial es cualquier cadena de caracteres derivada desde el smbolo de inicio. SENTENCIA: una sentencia es una forma que consiste solamente de terminales tales como a + a * a

    MTODOS DESCENDENTES O TOP-DOWN. El anlisis sintctico descendente crea una derivacin ms a la izquierda, los

    pasos son:

    1) Comenzar con el smbolo de inicio como la raz del rbol de anlisis sintctico.

    2) En cada paso, reemplace el no terminal del lado izquierdo en la forma sentencial actual.

    Se puede considerar el anlisis sintctico descendente como un intento de

    encontrar una derivacin por la izquierda para una cadena de entrada. Equivalentemente puede ser visto como el intento de construir un rbol de anlisis sintctico para la entrada comenzando desde la raz y creando los nodos del rbol en orden previo. Por ejemplo considere la gramtica:

    S cAd

    A ab | a

    y la cadena de entrada w = cad. Para construir un rbol de anlisis sintctico descendente para esta cadena, primero se crea un rbol formado por un solo nodo etiquetado con S. Un apuntador a la entrada apunta a c, el primer smbolo de w. Despus se utiliza la primera produccin de S para expandir el rbol y obtener el rbol de la Fig.(a).

    Se empareja la hoja ms a la izquierda, etiquetada con c, con el primer

    smbolo de w, y a continuacin se aproxima el apuntador de entrada a a, el segundo smbolo de w, y se considera la siguiente hoja etiquetada con A. Entonces se puede expandir A utilizando la primera alternativa de A para obtener el rbol de la Fig. (b).

  • 37

    Como ya se tiene una concordancia para el segundo smbolo de la entrada, se lleva el apuntador de entrada a d, el tercer smbolo de la entrada, y se compara d con la hoja siguiente, etiquetada con b. Como b no concuerda con d, se indica fallo y se regresa a A para saber si existe otra alternativa de A que no se haya intentado, pero se puede dar lugar a un emparejamiento.

    Al regresar a A, se debe restablecer el apuntador de entrada a la posicin 2,

    aquella que tenia al ir a A por primera vez, se intenta a continuacin la segunda alternativa de A para obtener el rbol de la Fig. (c).

    Se empareja la hoja a con el segundo smbolo de w, y la hoja d, con el tercer smbolo. Como ya se ha producido un rbol de anlisis sintctico par w, se para y se anuncia el xito de la realizacin completa del anlisis sintctico.

    Pasos en el Anlisis Sintctico Descendente. Anlisis Sintctico por Descenso Recursivo.

    Un analizador sintctico de descenso recursivo se compone de un procedimiento

    para cada smbolo no terminal de la gramtica, cuando se llama un procedimiento

    este intenta encontrar una subcadena de la entrada, empezando por el

    componente lxico actual, que se pueda interpretar como el no terminal con el

    cul est asociado al procedimiento.

    Durante este proceso puede llamar a otros procedimientos o llamarse a s

    mismo recursivamente, para buscar otros no terminales. Si un procedimiento encuentra el no terminal que pretende, devuelve una indicacin con xito a quin lo llam, y tambin avanza el apuntador al componente lxico situado despus de la subcadena que acaba de reconocer. Si el procedimiento es incapaz de encontrar una subcadena que pueda interpretarse como el no terminal deseado, devuelve una

  • 38

    indicacin de fallo o invoca a una rutina de diagnstico y recuperacin de errores. A modo de ejemplo considrese la siguiente gramtica:

    ::=READ( ::=id | ,id que definen la sintaxis de la proposicin READ del lenguaje PASCAL.

    El procedimiento para es un analizador sintctico de descenso recursivo examina primero los 2 siguientes componentes lxicos de entrada buscando READ y (. Si se encuentran, entonces el procedimiento para llama el procedimiento para . Si ese procedimiento tiene xito, el procedimiento , examina el siguiente componente lxico buscando un ). Si todas estas pruebas tienen xito el procedimiento devuelve una indicacin de xito a quien lo llama y avanza al prximo componente lxico que sigue a ). En otro caso el procedimiento devuelve una indicacin de fallo. El procedimiento es ligeramente ms complicado cuando hay varias opciones definidas por la gramtica para un no terminal. En este caso el procedimiento debe decidir que opcin intentar. Para la tcnica de descenso recursivo, se debe poder decidir qu opcin utilizar examinando el siguiente componente lxico de entrada. Hay otros mtodos descendentes que eliminan este requisito, aunque no son tan eficientes como el descendente recursivo. Si se intentara escribir los procedimientos para la gramtica anterior, se descubrira un problema. El procedimiento para , sera incapaz de decidir entre sus dos opciones, pues tanto id, como pueden comenzar con id. Sin embargo hay una dificultad ms importante, si el procedimiento hubiera decidido intentar la segunda opcin , se llamara de inmediato a si mismo recursivamente para encontrar una . Esto podra producir otra llamada recursiva inmediata, que dara lugar a una cadena sin fin. La razn de esto es que una de las opciones para empieza con . Los analizadores sintcticos descendentes no pueden usarse directamente con una gramtica que contenga esta clase de recursin por la izquierda inmediata.

    A continuacin se muestra la gramtica anterior por la recursin por la izquierda eliminada: ::= READ() ::= id

    ::= , id | Pudindose representarse tambin as:

  • 39

    ::= READ() ::= id{,id}

    Esta notacin, que es una extensin comn a BNF, especifica que los trminos entre { y } se pueden omitir o repetir una o mas veces. De esta forma la gramtica define a compuesta de un id seguida de cero o mas ocurrencias de ",id". Con la definicin revisada, el procedimiento para simplemente busca primero un id, y despus sigue explorando la entrada mientras los dos siguientes componentes lxicos sean una como(,) e id. Esto elimina el problema de la recursin por la izquierda y tambin la dificultad de decidir que opcin intentar para .

    Anlisis Sintctico descendente recursivo de una proposicin READ.

    La Fig. anterior ilustra el anlisis sintctico descendente recursivo de la

    proposicin READ, con la gramtica anterior. En el apartado (1), se ha llamado el procedimiento LECT y se han examinado los componentes lxicos READ y "(" del flujo de entrada (indicado con lneas punteadas). En el apartado (2), LECT ha llamado a LISTA_ID (indicado con lnea continua), que ha examinado el componente id. En el apartado (3), LISTA_ID ha vuelto a LECT indicando que ha tenido xito; por lo que LECT ha examinado el componente lxico de entrada ), con esto se completa el anlisis de la proposicin fuente. El procedimiento READ regresara ahora a quin lo llam, indicando que se encontr satisfactoriamente un . Obsrvese que la secuencia de llamadas a procedimientos y la exploracin de componentes lxicos ha definido por completo la estructura de la proposicin READ.

  • 40

    Ejemplo Descendente Recursivo Gramtica

    Programa

    Sentencias

    Sentencias

    Sentencia Sentencias'

    Sentencias'

    Sentencias |

    Sentencia

    Asignacin ;

    Asignacin

    Id := Expresin

    Expresin

    Termino Expresin'

    Expresin'

    + Termino Expresin' |

    Termino

    Factor Termino'

    Termino'

    * Factor Termino' |

    Factor

    ( Expresin )

    | Id

    | Literal

    Anlisis sintctico Predictivo. Un analizador sintctico predictivo, llamado tambin anlisis sintctico

    descendente recursivo es un mtodo descendente en el que se ejecuta un conjunto de producciones para procesar una entrada, a cada smbolo no terminal de una gramtica se le asocia con una produccin. Es una forma eficiente de implementar el anlisis sintctico descendente implcitamente manteniendo una pila, en vez de hacerlo implcitamente mediante llamadas recursivas. El modelo sintctico predictivo puede verse en la figura de abajo. Un analizador sintctico es guiado por una tabla en la que se encuentran las producciones.

  • 41

    Modelo de un analizador sintctico predictivo.

    Caractersticas:

    Es una forma eficiente de un analizador sintctico recursivo. Mantiene una PILA en vez de hacer llamadas recursivas. El analizador sintctico predictivo tiene una ENTRADA, una TABLA de

    anlisis sintctico y una SALIDA, adems de la PILA. La Pila contiene una secuencia de smbolos de alguna gramtica que debe

    de finalizar con un $ (delimitador). El elemento inicial de la gramtica debe de ser la cima de la PILA. La TABLA es un arreglo bidimensional (matriz), M [smbolo_no_terminal ,

    smbolo_terminal_$]

    El analizador sintctico esta controlado por un programa que trabaja como sigue. El programa determina a X, el smbolo en la cima de la pila, y a, el smbolo de la entrada actual. Estos dos smbolos determinan la accin del analizador sintctico: hay tres posibilidades:

    1.Si X = a = $, el analizador sintctico se detiene y anuncia el xito de la realizacin del anlisis sintctico.

    2.Si X = a$, el analizador sintctico saca a X dela pila y avanza el apuntador de entrada al siguiente smbolo de entrada.

    3.Si X es un smbolo no terminal el programa consulta la entrada M[X,a] de la tabla de anlisis sintctico. Esta entrada podra ser una produccin cualquiera de la

    gramtica o un error. Si M[X,a] = {XUVW}, el analizador sintctico reemplaza a X en la cima de la pila por WVU (con U en la cima). Si M[X,a] = error el analizador sintctico llama a una rutina de recuperacin de error.

    Se puede describir el comportamiento del analizador sintctico en trminos de su configuracin, la cual es dada por el contenido de la pila y la entrada restante. Inicialmente el analizador sintctico esta en la configuracin:

    Pila Entrada

    $S w$

  • 42

    donde S es el smbolo de inicio dela gramtica y w es la cadena que ha de ser analizada. Gramtica

    E TE'

    E' TE' |

    T FT'

    T' FT |

    F (E) | id Algoritmo 1. Si X = a = $, el analizador sintctico se detiene y anuncia el xito de la

    realizacin del anlisis sintctico.

    2. Si X = a $,el analizador sintctico saca a X de la pila y avnzale apuntador de entrada al siguiente smbolo de entrada.

    3. Si X es un smbolo no terminal el programa consulta la entrada M[X,a] de la tabla de anlisis sintctico. Esta entrada podra ser una produccin cualquiera

    dela gramtica o un error. Si M[X,a] = {XUVW}, el analizador sintctico reemplaza a X en la cima dela pila por WVU (con U en la cima). Si M[X,a] = error el analizador sintctico llama a una rutina de recuperacin de error.

    Se puede describir el comportamiento del analizador sintctico en trminos de

    su configuracin, la cual es dada por el contenido de la pila y la entrada restante. Inicialmente el analizador sintctico esta en la configuracin:

    Pila Entrada

    $S w$

    donde S es el smbolo de inicio dela gramtica y w es la cadena que ha de ser analizada.

    Matriz de precedencia resultante

    id + ( ) $

    E E TE E TE

    E E +TE E E

    T T FT T FT

    T T T *FT T T

    F F id F ( E )

    Anlisis Se analizar la cadena siguiente:

    id + id * id $

  • 43

    Paso 1 Inicialmente la pila contiene el smbolo de inicio de la gramtica precedido por el delimitador "$", as que tenemos en la pila a "$E". Y en la entrada tenemos a la cadena completa.

    Paso Pila Entrada Salida

    1 $ E id + id * id $

    Paso 2 En la cima de la pila tenemos a "E" verificamos en la gramtica y tenemos que es un no terminal, ocupamos la regla 3 del algoritmo, y reemplazamos X = E por su produccin la cual es TE'. Introduciremos la produccin en el orden inverso, y tendremos en la pila "$ E' T", y la salida ser la produccin del no terminal "E". Paso 3 En la cima de la pila tenemos a "T" verificamos en la gramtica y tenemos que es un no terminal, ocupamos la regla 3 del algoritmo, y reemplazamos X = T por su produccin la cual es FT'. Introduciremos la produccin en el orden inverso, y tendremos en la pila "$ E' T' F", y la salida ser la produccin del no terminal "T". Paso 4 Como la cima de la pila esta X= F y este produce el smbolo de la cadena leda, se sustituye por su produccin que es el terminal "id" y avanza el apuntador de entrada al siguiente smbolo de la cadena, ahora tendremos en la pila "$ E' T' id", y la salida ser la produccin de "F". Paso 5 Como "id" es igual al smbolo de entrada actual se compara y se saca de la pila y avanza el apuntador al siguiente smbolo de entrada.

    Paso 6 En la cima de la pila tenemos a "T'" verificamos en la gramtica y tenemos que es un no terminal, ocupamos la regla 3 del algoritmo, y reemplazamos X = T' por su

    produccin la cual es . Introduciremos la produccin en el orden inverso, y

    tendremos en la pila "$ E' " "$ E' ", y la salida ser la produccin del no terminal " T' ". Paso 7 En la cima de la pila tenemos a " E' " verificamos en la gramtica y tenemos que es un no terminal, ocupamos la regla 3 del algoritmo, y reemplazamos X = E' por su produccin la cual es +TE'. Introduciremos la produccin en el orden inverso, y tendremos en la pila "$ E' T +" y la salida ser la produccin del no terminal " E' ".

    Paso 8 Como "+" es igual al smbolo de entrada actual se compara y se saca de la pila y avanza el apuntador al siguiente smbolo de entrada. Paso 9 En la cima de la pila tenemos a " T " verificamos en la gramtica y tenemos que es un no terminal, ocupamos la regla 3 del algoritmo, y reemplazamos X = T por su produccin la cual es FT'. Introduciremos la produccin en el orden inverso, y tendremos en la pila "$ E' T' F" y la salida ser la produccin del no terminal " T ".

  • 44

    Paso 10 Como la cima de la pila esta X= F y este produce el smbolo de la cadena leda, se sustituye por su produccin que es el terminal "id" y avanza el apuntador de entrada al siguiente smbolo de la cadena, ahora tendremos en la pila "$ E' T' id", y la salida ser la produccin de "F". Paso 11 Como "id" es igual al smbolo de entrada actual se compara y se saca de la pila y avanza el apuntador al siguiente smbolo de entrada.

    Paso 12 En la cima de la pila tenemos a " T' " verificamos en la gramtica y tenemos que es un no terminal, ocupamos la regla 3 del algoritmo, y reemplazamos X = T' por su produccin la cual es *FT'. Introduciremos la produccin en el orden inverso, y tendremos en la pila "$ E' T' F *" y la salida ser la produccin del no terminal " T' ".

    Paso 13 Como "*" es igual al smbolo de entrada actual se compara y se saca de la pila y avanza el apuntador al siguiente smbolo de entrada.

    Paso 14 Como la cima de la pila esta X= F y este produce el smbolo de la cadena leda, se sustituye por su produccin que es el terminal "id" y avanza el apuntador de entrada al siguiente smbolo de la cadena, ahora tendremos en la pila "$ E' T' id", y la salida ser la produccin de "F". Paso 15 Como "id" es igual al smbolo de entrada actual se compara y se saca de la pila y avanza el apuntador al siguiente smbolo de entrada.

    Paso 16 En la cima de la pila tenemos a " T' " verificamos en la gramtica y tenemos que es un no terminal, ocupamos la regla 3 del algoritmo, y reemplazamos X = T' por su

    produccin la cual es . Introduciremos la produccin en el orden inverso, y

    tendremos en la pila "$ E'" "$ E' " y la salida ser la produccin del no terminal " T' ".

    Paso 17 En la cima de la pila tenemos a " E' " verificamos en la gramtica y tenemos que es un no terminal, ocupamos la regla 3 del algoritmo, y reemplazamos X = E' por su

    produccin la cual es . Introduciremos la produccin en el orden inverso, y

    tendremos en la pila "$ E'" "$ E' " y la salida ser la produccin del no terminal " T' ".

    Paso Pila Entrada Salida

    1 $ E id + id * id $

    2 $ E' T id + id * id $ E TE

  • 45

    3 $ E' T' F id + id * id $ T FT

    4 $ E' T' Id id + id * id $ F id

    5 $ E' T' + id * id $

    6 $ E' + id * id $ T

    7 $ E' T + + id * id $ E +TE

    8 $ E' T id * id $

    9 $ E' T' F id * id $ T FT

    10 $ E' T' Id id * id $ F id

    11 $ E' T' * id $

    12 $ E' T' F * * id $ T *FT

    13 $ E' T' F id $

    14 $ E' T' Id id $ F id

    15 $ E' T' $

    16 $ E' $ T

    17 $ $ E

    En la cima de la pila tenemos a " $ " y este es igual al smbolo ledo y a su vez es igual al delimitador, entonces el analizador sintctico se detiene y anuncia el xito de la realizacin del anlisis de la cadena.

    MTODOS ASCENDENTES O BOTTOM UP.

    El anlisis sintctico por desplazamiento 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. En cada paso de reduccin se sustituye una subcadena determinada que concuerde con el lado derecho de una produccin por el smbolo del lado izquierdo de dicha produccin y si en cada paso se elige correctamente la subcadena, se traza una derivacin por la derecha en sentido inverso.

    Considrese la siguiente gramtica:

    S aABe

    A Abc | b

    B d La frase "abbcde" se puede reducir a S por los siguientes pasos:

    abbcde aAbcde aAde aABe S

  • 46

    Se examina abbcde buscando una subcadena que concuerde con el lado derecho de alguna produccin. La subcadenas b y d sirven. Eljase la b ms situada

    a la izquierda y sustityase por A, el lado izquierdo de la produccin A b; as se obtiene la cadena aAbcde. A continuacin, las subcadenas Abc, b y d concuerdan con el lado derecho de alguna produccin. Aunque b es la subcadena situada ms a la izquierda que concuerda con el lado derecho de una produccin, se elige sustituir

    la subcadena Abc por A, que es el lado derecho de la produccin A Abc. Se obtiene ahora aAde. Sustituyendo despus d por B que es el lado izquierdo de la

    produccin B d, se obtiene aABe, ahora se puede sustituir toda la cadena por S. Por tanto, mediante una secuencia de cuatro reducciones se puede reducir abbcde a S. De hecho, estas reducciones trazan la siguiente derivacin por la derecha en orden inverso:

    S aABe aAde aAbcde abbcde

    Anlisis Sintctico de Precedencia Simple. Este mtodo realiza el anlisis sintctico buscando rpidamente el mango

    (frase simple mas a la izquierda) u de la forma sentencial actual y reducindola a un

    no terminal U, usando una regla U u . El problema en cualquier analizador sintctico ascendente es encontrar el mango, entonces saber a que no terminal se reducir.

    Dada una forma sentencial X, considerar dos smbolos R y S en el vocabulario V de una gramtica G . Suponer que hay una forma sentencial ...RS... . En algn punto cualquiera R o S (o ambas), deben de estar en un mango. Las siguientes tres posibilidades surgiran: R es parte de un mango pero S no Fig. (a). En este caso escribimos R > S y decimos que R es mas grande que S, o que R tiene precedencia sobre S, porque deber ser

    reducido primero. Note que R deber ser el smbolo final de alguna regla U ...R. Note que debido a que el mango esta a la izquierda de S, S deber ser un terminal. R y S estn ambos en un mango Fig.(b). Decimos que R S, ellos tienen la misma precedencia y debern ser reducidos al mismo tiempo. Obviamente deber existir

    una regla U ...RS... en la gramtica. S es parte de un mango pero R no Fig. (c), decimos que R < S o que R es menor

    que S y S deber ser la cabeza de alguna regla U S... Si no hay una funcin sentencial ...RS... entonces decimos que no hay relacin entre el par ordenado(R,S).

  • 47

    Ilustracin de las Relaciones de Precedencia. Algoritmo de Anlisis de Precedencia Simple.

    Cuando se usan las relaciones de precedencia para reconocer sentencias, lo

    mejor es usar una forma compacta para representarlas, la tcnica usual es tener la matriz P con los valores:

    P[i,j] = 0 si no existe relacin entre Si y Sj

    P[i,j] = 1 si Si < Sj P[i,j] = 2 si Si = Sj P[i,j] = 3 si Si > Sj

    Podemos hacer esto para una gramtica de precedencia porque sabemos

    que a lo sumo una relacin existe entre los entre dos smbolos cualquiera. Las reglas deben estar en una tabla, estructurada de tal forma que, dado un

    lado derecho, podamos encontrarlo en las reglas y encontrar el correspondiente lado izquierdo.

    El algoritmo trabaja como sigue: Los smbolos de la cadena de entrada son procesados de izquierda a derecha y almacenados en una pila S, hasta que la relacin de precedencia > exista entre el smbolo de la cima de la pila y el siguiente smbolo entrante. Esto significa que el smbolo de la cima de la pila es el final del mango, y por lo tanto el mango entero esta en la pila. Este mango es entonces encontrado en la lista de reglas y reemplazado en la pila, por el correspondiente no terminal el cual debe ser reducido. El proceso se repite hasta que la pila contenga Z y el siguiente smbolo de entrada sea $ (delimitador). Cada forma sentencial est encerrada entre los smbolos $ y $ (asumiendo que $ no es un smbolo de la gramtica). Adems se establece que $ < S y S > $ para cualquier smbolo S de la gramtica.

    En la Fig. se muestra un diagrama de flujo para el analizador sintctico usando la siguiente notacin:

    S es una pila usada para mantener los smbolos; su contador es i. j es un ndice usado para hacer referencia los elementos en la cima de la pila. La sentencia a ser analizada sintcticamente es TiT2...Tn. Empezamos con el

    delimitador de la sentencia $ en la pila y asumimos que ha sido anexada a la sentencia como T[n+1].

  • 48

    Q y R son variables para mantener ciertos smbolos durante el proceso de anlisis.

    Note que la cadena T1...Tn no es una sentencia, entonces el algoritmo parar e indicar esto.

    Analizador sintctico de precedencia simple.

    BLOQUE 1: Inicializar la pila S para mantener el delimitador de sentencia ($).

    Poner el ndice de la sentencia apuntando al primer smbolo. BLOQUE 2: Obtener el siguiente smbolo, colocarlo en R e incrementar k. BLOQUE 3 - 4: Si (S(i),R) no esta en >, el mango no esta completamente en

    la pila, entonces metemos R en la pila y obtenemos el siguiente smbolo. BLOQUE 5 - 7: Si S(i) >R, el mango deber estar en la pila. Estos bloques

    buscan la cabeza del mango. BLOQUE 8 - 9 :Checar la cadena S(j)...S(i). Si no esta en la parte derecha de

    una regla, el proceso ha terminado. La cadena fue una sentencia si y solamente si 1 = 2 y S(i) = Z. Si es la parte derecha de una regla, borramos el mango de la pila (bloque 9), metemos en la pila el smbolo el cual es reducido y regresamos al bloque 3 para buscar el siguiente mango.

    Una ventaja acerca de este y otros analizadores sintcticos similares es que

    la cadena completa de los smbolos de entrada no necesitan estar en memoria al mismo tiempo. Los smbolos son ledos uno a la vez de la entrada y almacenados en

  • 49

    la pila, pero como el mango es reducido, estos desaparecen. Solamente si el mango est en el final derecho de la cadena necesita que la cadena completa est almacenada.

    Ejemplo

    Gramtica

    E E + T | T

    T T * F | F

    F ( E ) | id

    Matriz de precedencia resultante

    E T F + * ( ) id

    E = =

    T > = >

    F > > >

    + = < < <

    * = < <

    ( = < < < <

    ) > > >

    id > > >

    Anlisis Se analizar la cadena siguiente: ( x + y )

    Paso

    Pila Relaci

    n R

    Token

    0 $ < ( x+y)$

    1 $( < x +y)$

    2 $(x > + y)$

    3 $(E = + y)$

    4 $(E+ < y )$

    5 $(E+y > ) $

    6 $(E+

    T > ) $

    7 $(E = ) $

    8 $(E) > $ $

    Anlisis Sintctico LR. El nombre de esta tcnica de anlisis sintctico LR(k) proviene de L por el

    exmen de la entrada de izquierda a derecha (en ingls Left-to-Right), la R por

  • 50

    construir una derivacin por la derecha (en ingls rightmost derivation) en orden inverso, y la k por el nmero de smbolos de entrada de examen por anticipado utilizados para tomar las decisiones del anlisis sintctico. Cuando sta se omite, se asume que k es 1. Esta tcnica de anlisis sintctico resulta conveniente por varias razones:

    Se puede construir analizadores sintcticos LR para reconocer prcticamente todas las construcciones de los lenguajes de programacin para los que se pueden escribir gramticas libres de contexto.

    El mtodo de anlisis sintctico LR es el mtodo de anlisis por desplazamiento y reduccin sin retroceso ms general que se conoce y sin embargo se puede aplicar tan eficientemente como los otros mtodos de desplazamiento y reduccin.

    La clase de gramticas que pueden analizarse con los mtodos LR es un supraconjunto de la clase de gramticas que se puedan analizar con analizadores sintcticos predictivos.

    Un analizador sintctico predictivo LR puede detectar un error sintctico tan pronto como sea posible hacerlo en un examen de izquierda a derecha de la entrada.

    El principal inconveniente del mtodo es que supone demasiado trabajo construir un analizador sintctico LR a mano para una gramtica de un lenguaje de programacin tpico. Se necesita una herramienta especializada: un generador de analizadores sintcticos LR, por ejemplo YACC. Con este generador se puede escribir una gramtica libre de contexto y el generador produce automticamente un analizador sintctico para dicha gramtica .

    Modelo de un analizador sintctico LR.

    En la Fig se muestra de forma esquemtica de un analizador sintctico LR. Consta de una entrada, una salida, una pila, un programa conductor y una tabla de anlisis sintctico de dos partes (accin, ir_a). El programa conductor es el mismo para todos los analizadores sintcticos LR; solo cambian las tablas de un analizador a otro. La tabla de anlisis sintctico consta de dos partes, la funcin accin que

  • 51

    indica una accin del analizador, y la funcin ir_a, que indica las transiciones entre los estados.

    Realizacin

    Gramtica

    E E + T

    E T

    T T * F

    T F

    F ( E )

    F id Algoritmo

    inicializar la pila al estado cero agregar $ al final de la entrada apuntar al primer smbolo de la entrada repetir begin sea s el estado de la cima de la pila y a el smbolo de entrada actual if accin [s,a] = desplazar # then begin

    meter a y despus # (el nuevo estado) en la pila avanzar al siguiente smbolo de entrada end

    else if accin [s,a] = reducir A then begin

    sacar 2*| | smbolos de la pila sea S el estado que ahora esta en la cima de la pila meter a y despus ir_a[s,a] en la pila. end else if accin[s,a] = aceptar then Return else error() end.

    Matriz de precedencia resultante

    Estado Accin ir_a

    id + * ( ) $ E T F

    0 d5 d4 1 2 3 1 d6 Aceptar

  • 52

    Anlisis

    Inicializa la pila al estado cero, agregar el smbolo $ al final de la cadena de entrada, paso 1:

    id*(id+id)

    Pila Entrada Accin S a

    (1) 0 id*(id+id)$ 0 id

    Como [S,a] = [0,id], tenemos a S5 que es = desplazar, entonces se mete a

    (id) y despus a # (5) (el nuevo estado) en la pila, avanzar al siguiente smbolo, paso 2:

    Verificando en la tabla tenemos (R6), como [S,a] = [5,*] = reducir A , =

    1 tenemos que sacar 2*||, ahora el tope de la pila es 0 y F el lado izquierdo de la produccin 6, meter A que es F y el 3 obtenido en la interseccin 0,F, paso 3:

    Verificando en la tabla tenemos (R4), como [S,a] = [3,*] = reducir A , =

    1 tenemos que sacar 2*||, ahora el tope de la pila es 0 y T el lado izquierdo de la produccin 4, meter A que es T y el 2 obtenido en la interseccin 0,T, paso 4:

    Verificando en la tabla tenemos (S7), como [S,a] = [2,*] = desplazar, entonces

    se mete a(*) y despus a # (7) (el nuevo estado) en la pila, avanzar al siguiente smbolo, paso 5:

    Verificando en la tabla tenemos (S4), como [S,a] = [7,(] = desplazar, entonces

    se mete a(() y despus a # (4) (el nuevo estado) en la pila, avanzar al siguiente smbolo, paso 6:

    Verificando en la tabla tenemos (S5), como [S,a] = [4,id] = desplazar,

    entonces se mete a(id) y despus a # (5) (el nuevo estado) en la pila, avanzar al siguiente smbolo, paso 7:

    2 r2 d7 r2 r2 3 r4 r4 r4 r4 4 d5 d4 8 2 3 5 r6 r6 r6 r6 6 d5 d4 9 3

    7 d5 d4 10

    8 d6 d11 9 r1 d7 r1 r1

    10 r3 r3 r3 r3 11 r5 r5 r5 r5

  • 53

    Verificando en la tabla tenemos (R6), como [S,a] = [5,+] = reducir A , =

    1 tenemos que sacar 2*||, ahora el tope de la pila es 4 y F el lado izquierdo de la produccin 6, meter A que es F y el 3 obtenido en la interseccin 4,F, paso 8:

    Verificando en la tabla tenemos (R4), como [S,a] = [3,+] = reducir A , =

    1 tenemos que sacar 2*||, ahora el tope de la pila es 4 y T el lado izquierdo de la produccin 4, meter A que es T y el 2 obtenido en la interseccin 4,T, paso 9:

    Verificando en la tabla tenemos (R2), como [S,a] = [2,+] = reducir A , =

    1 tenemos que sacar 2*||, ahora el tope de la pila es 4 y E el lado izquierdo de la produccin 2, meter A que es E y el 8 obtenido en la interseccin 4,E, paso 10:

    Verificando en la tabla tenemos (S6), como [S,a] = [8,+] = desplazar, entonces

    se mete a(+) y despus a # (6) (el nuevo estado) en la pila, avanzar al siguiente smbolo, paso 11:

    Verificando en la tabla tenemos (S5), como [S,a] = [6,id] = desplazar,

    entonces se mete a(id) y despus a # (5) (el nuevo estado) en la pila, avanzar al siguiente smbolo, paso 12:

    Verificando en la tabla tenemos (R6), como [S,a] = [5,)] = reducir A , = 1

    tenemos que sacar 2*||, ahora el tope de la pila es 6 y F el lado izquierdo de la produccin 6, meter A que es F y el 3 obtenido en la interseccin 6,F, paso 13:

    Verificando en la tabla tenemos (R4), como [S,a] = [3,)] = reducir A , =

    1 tenemos que sacar 2*||, ahora el tope de la pila es 6 y T el lado izquierdo de la produccin 4, meter A que es T y el 9 obtenido en la interseccin 6,T, paso 14:

    Verificando en la tabla tenemos (R1), como [S,a] = [9,)] = reducir A , =

    3 tenemos que sacar 2*||, ahora el tope de la pila es 4 y E el lado izquierdo de la produccin 1, meter A que es E y el 8 obtenido en la interseccin 4,E, paso 15:

    Verificando en la tabla tenemos (S11), como [S,a] = [8,)] = desplazar,

    entonces se mete a()) y despus a # (11) (el nuevo estado) en la pila, avanzar al siguiente smbolo, paso 16:

    Verificando en la tabla tenemos (R5), como [S,a] = [11,$] = reducir A ,

    = 3 tenemos que sacar 2*||, ahora el tope de la pila es 7 y F el lado izquierdo de la produccin 5, meter A que es F y el 10 obtenido en la interseccin 7,F, paso 17:

    Verificando en la tabla tenemos (R3), como [S,a] = [10,$] = reducir A ,

    = 3 tenemos que sacar 2*||, ahora el tope de la pila es 0 y T el lado izquierdo de la produccin 3, meter A que es T y el 2 obtenido en la interseccin 0,T, paso 18:

    Verificando en la tabla tenemos (R2), como [S,a] = [2,$] = reducir A , = 1

    tenemos que sacar 2*||, ahora el tope de la pila es 0 y E el lado izquierdo de la produccin 2, meter A que es E y el 1 obtenido en la interseccin 0,E, paso 19:

    Pila Entrada Accin S a

  • 54

    (1) 0 id*(id+id)$ S5 0 id

    (2) 0 id 5 *(id+id)$ R6 5 *

    (3) 0 F 3 *(id+id)$ R4 3 *

    (4) 0 T 2 *(id+id)$ S7 2 *

    (5) 0 T 2 * 7 (id+id)$ S4 7 (

    (6) 0 T 2 * 7 ( 4 id+id)$ S5 4 id

    (7) 0 T 2 * 7 ( 4 id 5 +id)$ R6 5 +

    (8) 0 T 2 * 7 ( 4 F 3 +id)$ R4 3 +

    (9) 0 T 2 * 7 ( 4 T 2 +id)$ R2 2 +

    (10) 0 T 2 * 7 ( 4 E 8 +id)$ S6 8 +

    (11) 0 T 2 * 7 ( 4 E 8 + 6 )$ S5 6 id

    (12) 0 T 2 * 7 ( 4 E 8 + 6 id 5 )$ R6 5 )

    (13) 0 T 2 * 7 ( 4 E 8 + 6 F 3 )$ R4 3 )

    (14) 0 T 2 * 7 ( 4 E 8 + 6 T 9 )$ R1 9 )

    (15) 0 T 2 * 7 ( 4 E 8 )$ S11 8 )

    (16) 0 T 2 * 7 ( 4 E 8 ) 11 $ R5 11 )

    (17) 0 T 2 * 7 F 10 $ R3 10 $

    (18) 0 T 2 $ R2 2 $

    (19) 0 E 1 $ 1 $

    Verificando en la tabla tenemos (Aceptar), por lo tanto la cadena ha sido

    completamente aceptada

    Matrices de Transicin. Una matriz de transicin es una matriz o tabla M, cuyos renglones

    representan las "cabezas" (cadenas de smbolos, las cuales terminan en un smbolo terminal) de los lados derechos de las reglas de las gramticas, las cuales pueden aparecer en la pila, y cuyas columnas representan los smbolos terminales, incluyendo el delimitador $. Los elementos de la matriz sern nmeros o direcciones de subrutinas.

    La Tabla muestra la estructura de una matriz de transicin para la siguiente gramtica (parcialmente llena). Gramtica:

    ::= ::= IF THEN ::= := ::= + | ::= id

    $ IF THEN := + id

    $ 1 1

    IF

  • 55

    IF THEN

    :=

    +

    id Tabla parcialmente llena para la gramatica dada.

    El analizador sintctico utiliza la tpica pila S y la variable para el smbolo

    entrante R. Aunque la estructura de la pila tiene una pequea diferencia; en lugar de slo smbolos, se permitir que cadenas de smbolos aparezcan en la pila. Las cadenas que aparezcan aqu sern cabezas (las cuales terminan en un smbolo terminal) de las partes derechas de las reglas. Por ejemplo, si la pila convencional en algn momento contiene:

    $ IF THEN IF THEN :=

    La pila podra verse como:

    := IF THEN IF THEN $

    Note que todo lo que se hace es mantener juntos todos esos smbolos; los

    cuales sabemos, debern ser reducidos al mismo tiempo. Tambin se utilizar una variable U, sta estar vaca o contendr el smbolo el cual la ltima frase ha sido reducida. As, si la cadena parcial analizada hasta el momento es:

    $ IF THEN IF THEN := Entonces la pila se vera como arriba y estara en U. El analizador sintctico usa la matriz como sigue. En cada paso el elemento

    en la cima de la pila corresponde a algn rengln de la matriz, debido a que ambas representan la cabeza (terminando en un smbolo terminal) de alguna parte derecha. El smbolo terminal entrante determina una columna de la matriz. Estas dos juntas determinan un elemento de la matriz el cual es el nmero de subrutina a ejecutar. Esta subrutina ejecuta la reduccin necesaria o mete en la pila a R y obtiene el siguiente smbolo de entrada.

    Realizacin del Anlisis de Matriz de Transicin.

    Para llevar a cabo el anlisis sintctico y al mismo tiempo construir la matriz,

    se har uso de una pila S que en cuestin a su estructura es algo diferente a las ya conocidas, ya que en estas podemos almacenar no nicamente smbolos sino tambin cadenas de smbolos, stas cadenas sern las cabezas que definimos como renglones de la matriz y tambin se hace uso de una variable (R) que especificar el smbolo o los smbolos que puedan entrar a la pila.

    Ejemplo: Podemos tener en X momento esta expresin dentro de la pila:

  • 56

    $ IF THEN IF THEN := La pila podra verse como:

    := IF THEN IF THEN $

    Tambin se hace uso de una variable U, la cual estar vaca o contendr el

    smbolo de la ltima frase reducida. En cada paso el elemento que se encuentre en la cima de la pila

    corresponder a algn rengln de la matriz, el smbolo terminal R determinar la columna de la matriz y los elementos pertenecientes a la matriz sern los nmeros de subrutinas a ejecutar, las subrutinas tendrn la tarea de meter a R en la pila o de llevar a cabo una reduccin.

    Ejemplo:

    Cuando iniciamos el anlisis $ esta en la pila y la variable U est vaca, de

    acuerdo a la gramtica que usamos en este ejemplo, el smbolo entrante debe ser IF e id debido a que estas inician partes derechas, por lo que colocaremos el nmero 1 (que corresponde a la primera subrutina) en el rengln $ que es el elemento en la cima de la pila y en las columnas IF e id, despus realizaremos la subrutina.

    $

    U = R =

    $ IF THEN := + id

    $ 1 1

    IF

    IF THEN

    :=

    +

    id Subrutina 1: IF U " " then ERROR;

    i := i + 1 ; S(i) = R ; SIGCOMPLEX.

    La funcin SIGCOMPLEX coloca el siguiente smbolo de la cadena de

    entrada en R.

    id IF $

    U = R =

  • 57

    Ahora haremos un recorrido en la matriz para ver o indicar en que otras posiciones en la matriz se puede realizar la subrutina 1, para esto se debe de analizar que posible smbolo terminal de la columna podra seguirle al elemento terminal del rengln.

    En el rengln IF basndonos en la regla 2, le sigue al smbolo IF y como vemos en la regla 4 := y en la regla 5 := id ; por lo tanto id puede ser un smbolo que le siga a IF por lo tanto colocamos en nmero 1 en la fila IF columna id.

    En el rengln IF THEN, basndonos en la regla 2, le sigue al smbolo THEN y como vemos en la misma regla 2 := IF THEN ; por lo tanto IF puede ser un smbolo que le sigue a THEN y colocamos tambin el nmero 1 de la subrutina en la fila IF THEN columna IF; tambin vemos en la regla 3 que := := y en la regla 5 := id por lo tanto tambin id puede ser un smbolo que le siga a THEN y tambin colocamos el nmero 1 en la misma fila pero en la columna id.

    Valindose de estas reglas la matriz al terminar este paso queda:

    $ IF THEN := + id

    $ 1 1

    IF 1

    IF THEN

    1 1

    := 1

    + 1

    id como vemos ahora en la cima de la pila se encuentra el smbolo id, por lo que

    iremos al rengln id de la matriz y analizaremos que smbolo (de las columnas) puede ser vlido en R, es decir, que smbolo podra seguirle a id y vemos que los smbolos $, THEN, := + son vlidos, esto es porque se puede tener una expresin como la siguiente:

    IF id THEN id:= id + id $ por lo tanto la matriz queda:

    $ IF THEN := + id

    $ 1 1

    IF 1

    IF THEN

    1 1

    := 1

    + 1

    id 2 2 2 2 2 Subrutina 2: IF U " " then ERROR;

    i: = i - 1; U = ''.

    Aqu se hace una reduccin y la pila queda:

  • 58

    IF $

    U = ' ' R =

    Ahora en la cima de la pila se encuentra el smbolo IF por lo que iremos al

    rengln IF de la matriz y analizaremos que smbolo (de las columnas) puede ser vlido en R, es decir que smbolo podra seguir a IF pero tomando e cuenta que tenemos a en U. Vemos que en el rengln IF la nica que satisface tal condicin es el smbolo + , as como tambin en el rengln :=.

    Por lo tanto la matriz quedar: $ IF THEN := + id

    $ 1 1

    IF 3 1

    IF THEN

    1 1

    := 3 1

    + 1

    id 2 2 2 2 2 Subrutina 3: IF U '' and U ''then ERROR;

    i := i + 1 ; S(i) = ''+ SIGCOMPLEX.

    '+' IF $

    U = ' ' R =

    Ahora nos posicionamos en la fila + de la matriz y analizaremos que smbolo (de las columnas) puede ser vlido en R, es decir que smbolo podra seguir a + tomando en cuenta tambin a que esta en U y vemos que los smbolos $, THEN + son vlidos, porque se puede tener una expresin como la siguiente:

    IF + THEN := ++ $ + Por lo tanto la matriz quedar:

    $ IF THEN := + id

    $ 1 1

    IF 3 1

    IF THEN

    1 1

    := 3 1

    + 4 4 4 1

    id 2 2 2 2 2 Subrutina 4: IF U "" then ERROR; i := i - 1 ; U = ''

  • 59

    '+'

    IF $

    U = ' ' := '' R =

    Se hizo aqu otra reduccin. Se siguen los mismos procedimientos, aunque cabe aclarar que en la

    subrutina 5, se hace una parada.

    Subrutina 5: IF U '' and U '' then ERROR; STOP de tal forma que as quedara la tabla:

    $ IF THEN := + id

    $ 5 1 1

    IF 3 1

    IF THEN

    1 1

    := 3 1

    + 4 4 4 1

    id 2 2 2 2 2 La matriz completa y las subrutinas para la gramtica de ejemplo se muestran a

    continuacin:

    $ IF THEN := + id

    $ 5 1 0 6 0 1

    IF 0 0 9 0 3 1

    IF THEN

    7 1 0 6 0 1

    := 8 0 0 0 3 1

    + 4 0 4 0 4 1

    id 2 0 2 2 2 0

    6: if U ' then ERROR; U := '';

    i := i + 1; S (i) = ' :=', SIGCOMPLEX.

    7: if U '' then ERROR; i := i - 1;

    U :=''.

    8: if U '' and U '' then ERROR;

    i := i - 1; U:= '';

    9: if U '' and U '' then ERROR;

  • 60

    S (i) := 'IF THEN'; U := '';

    SIGCOMPLEX.

    0: ERROR; STOP.

  • 61