SlideShare una empresa de Scribd logo
1 de 48
Descargar para leer sin conexión
INTRODUCCIÓN
    Para empezar el estudio de Compiladores conozcamos algo a cerca de su historia.

•   1958, Strong y otros proponen una solución al problema de que un compilador fuera portable, y
    esta era dividir al compilador en dos fases “front end” (analiza el programa fuente) y “back end”
    (genera código objeto para la máquina objeto).

•   El puente de unión era un lenguaje intermedio denominado UNCOL (no funcionó)
•   1959, Rabin y Scott proponen el empleo de AFD y AFN para el reconocimiento lexicográfico de
    los lenguajes

•   Aparece BNF (Backus-1960, Naur-1963, Knuth-1964) como una guía para el desarrollo del
    análisis sintáctico

•   1959, Sheridan describe un método de parsing de FORTRAN para introducir paréntesis en una
    expresión

•   1975, aparece LEX generador automático de analizadores léxicos a partir de expresiones
    regulares bajo UNIX

•   A mitad de los 70’s Johnson crea YACC para UNIX (generador de analizadores sintácticos)


•   El último lenguaje de programación de amplia aceptación es JAVA (es interpretado)


    Para escribir un compilador necesitamos: - Algoritmos
                                                - Lenguajes de Programación
                                                - Lenguajes Formales
                                                - Arquitectura del Computador
                                                - Ingeniería de Software

    Programas que el compilador necesita para obtener un programa ejecutable
                  •    Preprocesador
                  •    Ligador
                  •    Cargador                                                                         1
                  •    Depurador
                  •    Ensamblador

                     Elaborado por: Beatriz Pasaca|                                Noveno “A”
Conceptos Básicos que hay tener bien claro:

  Traductor. Cualquier programa que toma como entrada un texto escrito en un lenguaje
  llamado fuente y da como salida un programa equivalente en otro lenguaje, el lenguaje
  objeto.
  Si el lenguaje fuente de un lenguaje de programación de alto nivel y el objeto un lenguaje de
  bajo nivel (ensamblador o código de máquina), al traductor se le denomina compilador.

  Ensamblador. Es un programa traductor cuyo lenguaje fuente es el lenguaje ensamblador.

  Intérprete. Es un programa que no genera un programa equivalente, sino que toma una
  sentencia del programa fuente en un lenguaje de alto nivel y la traduce al código equivalente
  y al mismo tiempo lo ejecuta.
  En un principio debido a la escasez de memoria se utilizaban más los intérpretes, ahora se
  usan más los compiladores (a excepción de JAVA)

Conceptos básicos

Ventajas de compilar vs a interpretar

           o Se compila una vez, se ejecuta n veces
           o En ciclos, la compilación genera código equivalente, interpretándolo se traduce
             tantas veces una línea como veces se repite el ciclo
           o El compilador tiene un visión global del programa

Ventajas del intérprete vs el compilador

           o   Un intérprete necesita menos memoria que un compilador
           o   Permiten una mayor interactividad con el código en tiempo de desarrollo

Más Diferencias entre Traductor y un Compilador

Traductor: - Análisis Léxico                 Compilador: - Análisis Léxico
             - Análisis Sintáctico                       - Análisis Sintáctico
             - Análisis Semántico                         - Análisis Semántico
                                                          - Generación de código intermedio
                                                          - Código maquina
                                                          - Fase de optimizacion
                 Equivalencias

                                                                                                  2
                                                                 Gcódigo máquina




                 Elaborado por: Beatriz Pasaca|                               Noveno “A”
•   Un compilador es un programa informático que traduce un programa escrito en un lenguaje de
    programación fuente a otro lenguaje de programación, generando un programa equivalente que
    la máquina será capaz de interpretar. Usualmente el segundo lenguaje es código máquina,
    pero también puede ser simplemente texto. Este proceso permite generar una lista de los
    posibles errores que tenga el programa fuente.


•   Un compilador es un programa que lee un programa escrito en un lenguaje, el lenguaje fuente,
    y lo traduce a un programa equivalente en otro lenguaje, el lenguaje objeto. Como parte
    importante de éste proceso de traducción, el compilador informa a su usuario de la presencia
    de errores en el programa fuente.


•   Compilador también define como aquel traductor que tiene como entrada una sentencia en
    lenguaje formal y como salida tiene un fichero ejecutable, es decir, realiza una traducción de un
    código de alto nivel a código máquina (también se entiende por compilador aquel programa que
    proporciona un fichero objeto en lugar del ejecutable final).




                                        Funcionamiento del compilador



    Hay miles de lenguajes fuente, desde los lenguajes de programación tradicionales, hasta los
    lenguajes especializados que han surgido virtualmente en todas las áreas de aplicación de la
    información.
                                                                                                        3




                     Elaborado por: Beatriz Pasaca|                                Noveno “A”
Lenguajes objeto son igualmente variados; un lenguaje objeto puede ser otro lenguaje
de programación o el lenguaje de máquina de cualquier computador entre un
microprocesador y un supercomputador.

Estructura de un compilador




                                                                                       4

                                    Estructura de un compilador.


               Elaborado por: Beatriz Pasaca|                        Noveno “A”
-Análisis Léxico, Rastreador o Scanner: Descomposición programa fuente en componentes
léxicos. En esta etapa se lee el archivo de texto que contiene el código fuente y las cadenas se
van agrupando en componentes léxicos o tokens.


Estos componentes léxicos son los operadores, identificadores y palabras reservadas del
lenguaje. Por lo tanto, transforma en flujo de caracteres en un flujo de objetos tokens,
ignorando los comentarios y los espacios en blanco y tabulaciones. Esta primera fase es capaz
de detectar errores de tipo léxico.


Por ejemplo, si en lugar de poner if pusiéramos ifi, el analizador léxico no usaría el token
predefinido IF para esa secuencia de caracteres, sino que entendería que es un identificador
cualquiera (como pudiera ser el nombre de una variable).


- Análisis Sintáctico o Parser: Agrupa componentes léxicos en frases gramaticales. Esta
etapa se encarga de verificar que el documento tiene una disposición sintáctica correcta,
agrupando el código en frases gramaticales con sentido. En otras palabras, que el flujo de
tokens tenga el orden correcto.


Esta etapa detecta errores sintácticos. Siguiendo el ejemplo anterior, si hubiésemos puesto ifi
en lugar de if, esta etapa detectaría que la estructura de un bloque if no es así, detectando así
el error en el código fuente. A la siguiente fase le manda árboles de sintaxis abstracta.


Por ejemplo, un árbol cuyo nodo raíz es PROGRAMA, que se compone de una lista de clases.
Cada una de estas serian arboles que describen los distintos atributos y métodos de la misma,
y así sucesivamente. Esta fase no puede detectar los errores.


- Análisis Semántico: Comprobación de validez semántica. Esta es una de las fases más
complejas del proceso de compilación. Tiene que realizar varias tareas: la resolución de
nombres, el tipo de las expresiones y la evaluación L/R. La resolución de nombres consiste en
comprobar que cada identificador que usemos (ya sea una variable local, parámetro, atributo o
                                                                                                    5
método) ha sido previamente declarado y además, si es visible desde el ámbito actual.



                 Elaborado por: Beatriz Pasaca|                                  Noveno “A”
En cuanto a los tipos, hay que comprobar que en las expresiones donde intervengan 2
identificadores (asignación, suma, producto, concatenación, etc.) comprobar que ambos
identificadores aceptan dicha operación, que son de tipos compatibles. La evaluación L/R
consiste en que para cada asignación, cada componente puede aparecer o no en esa posición.
Por ejemplo, el resultado de una serie de operaciones no puede aparecer a la izquierda, solo a
la derecha, ya que no se puede asignar un valor al resultado de una serie de operaciones.



Tabla de símbolos: Una función esencial de un compilador es registrar los
identificadores de usuario (nombres de variables, de funciones, de tipos, etc.) utilizados
en el programa fuente y reunir información sobre los distintos atributos de cada
identificador. Estos atributos pueden proporcionar información sobre la memoria
asignada a un identificador, la dirección de memoria en que se almacenará en tiempo
de ejecución, su tipo, su ámbito (la parte del programa donde es visible), etc. Pues
bien, la tabla de símbolos es una estructura de datos que posee información sobre los
identificadores definidos por el usuario, ya sean constantes, variables, tipos u otros.
Dado que puede contener información de diversa índole, debe hacerse de forma que
su estructura no sea uniforme, esto es, no se guarda la misma información sobre una
variable del programa que sobre un tipo definido por el usuario. Hace funciones de
diccionario de datos y su estructura puede ser una tabla hash, un árbol binario de
búsqueda, etc., con tal de que las operaciones de acceso sean lo bastante eficientes.




                              Esquema por etapas definitivo del traductor


Tanto la etapa de análisis como la de síntesis acceden a esta estructura, por lo que se halla    6
muy acoplada al resto de fases del compilador. Por ello conviene dotar a la tabla de símbolos
de una interfaz lo suficientemente genérica como para permitir el cambio de las estructuras

                Elaborado por: Beatriz Pasaca|                               Noveno “A”
internas de almacenamiento sin que estas fases deban ser retocadas. Esto es así porque suele
ser usual hacer un primer prototipo de un compilador con una tabla de símbolos fácil de
construir, y cuando el compilador ya ha sido finalizado, entonces se procede a sustituir la tabla
de símbolos por otra más eficiente en función de las necesidades que hayan ido surgiendo. El
esquema general definitivo de un traductor se detalla en la figura anterior.

                                    TIPOS DE COMPILADORES

Existen varias categorías de compiladores entre los más conocidos tenemos:

   •   Compiladores cruzados: generan código para un sistema distinto del que están
       funcionando.
   •   Compiladores optimizadores: realizan cambios en el código para mejorar su
       eficiencia, pero manteniendo la funcionalidad del programa original.
   •   Compiladores de una sola pasada: generan el código máquina a partir de una única
       lectura del código fuente.
   •   Compiladores de varias pasadas: necesitan leer el código fuente varias veces antes
       de poder producir el código máquina.
   •   Compiladores JIT (Just In Time): forman parte de un intérprete (traductor que realiza la
       operación de compilación paso a paso), y compilan partes del código según se
       necesitan.

Partes de un compilador

Normalmente los compiladores están divididos en dos partes:


       Front End: es la parte que analiza el código fuente, comprueba su validez, genera el
       árbol de derivación y rellena los valores de la tabla de símbolos. Esta parte suele ser
       independiente de la plataforma o sistema para el cual se vaya a compilar.
       Back End: es la parte que genera el código máquina, específico de una plataforma, a
       partir de los resultados de la fase de análisis, realizada por el Front End.


Esta división permite que el mismo Back End se utilice para generar el código máquina de            7
varios lenguajes de programación distintos y que el mismo Front End que sirve para analizar el


                  Elaborado por: Beatriz Pasaca|                                      Noveno “A”
código fuente de un lenguaje de programación concreto sirva para generar código máquina en
varias plataformas distintas.

El código que genera el Back End normalmente no se puede ejecutar directamente, sino que
necesita ser enlazado por un programa enlazador (linker).

Arquitectura Real De Compiladores E Intérpretes

La arquitectura real de compiladores e intérpretes es la siguiente:




                                                                                             8




                 Elaborado por: Beatriz Pasaca|                           Noveno “A”
ANALIZADOR LÉXICO

Definición: El analizador léxico (scanner), lee un texto fuente y lo transforma en una secuencia
ordenada de elementos léxicamente válidos. Un caracter o conjunto de estos que constituya un
componente léxico se llama lexema (token). Como componentes léxicos consideramos:
palabras reservadas, separadores, operadores, identificadores, constantes y signos de
puntuación.


Funciones del analizador léxico




                    La fase de análisis léxico se halla bajo el control del análisis sintáctico.

Normalmente se implementa como una función de éste componentes léxicos que utiliza el
analizador sintáctico para hacer el análisis. Esta interacción suele aplicarse convirtiendo al
analizador léxico en una subrutina o corrutina del analizador sintáctico. Recibida la orden
“Dame el siguiente componente léxico”del analizador sintáctico, el léxico lee los caracteres de
entrada hasta que pueda identificar el siguiente componente léxico, el cual devuelve al
sintáctico según el formato convenido (figura anterior).


Analizador léxico lee la secuencia de caracteres del programa fuente, carácter a carácter, y los
agrupa para formar unidades con significado propio, los componentes léxicos (tokens en
ingles). Estos componentes léxicos representan:


•   Palabras reservadas: if, while, do.
•   Identificadores: asociados a variables, nombres de funciones, tipos definidos por el usuario,               9
    etiquetas. Por ejemplo: posición, velocidad, tiempo.
•   Operadores: = * + - / == > < & ! = .

                  Elaborado por: Beatriz Pasaca|                                                   Noveno “A”
•   Símbolos especiales: ; ( ) [ ] f g.
•   Constantes numéricas: literales que representan valores enteros, en coma flotante, etc.,
    982, 0xF678, -83.2E+2,…
•   Constantes de caracteres: literales que representan cadenas concretas de caracteres, “hola
    mundo",...


El analizador léxico opera bajo petición del analizador sintáctico devolviendo un componente
léxico conforme el analizador sintáctico lo va necesitando para avanzar en la gramática. Los
componentes léxicos son los símbolos terminales de la gramática.


Otras funciones:


    •   Manejo del fichero de entrada del programa fuente: abrirlo, leer sus caracteres, cerrarlo
        y gestionar posibles errores de lectura.
    •   Eliminar comentarios, espacios en blanco, tabuladores y saltos de línea (caracteres no
        validos para formar un token).
    •   Inclusión de ficheros: # include ...
    •   La expansión de macros y funciones inline: # define ...
    •   Contabilizar el número de líneas y columnas para emitir mensajes de error.
    •   Reconocimiento y ejecución de las directivas de compilación (por ejemplo, para depurar
        u optimizar el código fuente).
    •   Rechazar un carácter o conjunto de estos que no concuerden con patrones
        especificados
    •   Entendamos como patrón una expresión regular que se define en el lenguaje.
    •   Ignorar comentarios, espacios en blanco y tabuladores.
    •   Gestionar errores, contando los saltos de línea y asociando los mensajes de error con el
        número de la línea del archivo fuente donde se producen.
    •   Guardar tokens junto con su atributo en una tabla de símbolos. Este atributo es
        información adicional relevante, habitualmente con relación a los identificadores.

                                                                                                    10
Componentes Toquen, Patrones, Lexemas
        Token: “nombre “que se da a cada componente léxico.


                   Elaborado por: Beatriz Pasaca|                               Noveno “A”
Patrón: es una regla que genera la secuencia de caracteres que puede representar a
       un determinado componente léxico (una expresión regular).
       Lexema: cadena de caracteres que concuerda con un patrón que describe un
       componente léxico. Un componente léxico puede tener uno o infinitos lexemas.
           Además
       o   Un token se corresponde con un patrón
       o   Un token se puede corresponder con muchos lexemas
       o   Tokens más habituales:
       o   Palabras reservadas
       o   Identificadores
       o   Operadores
       o   Constantes
       o   Símbolos de puntuación: ; , . :
       o   Símbolos especiales: ( ) [ ]
       o   Pero, a la vez que el propio token, el scanner puede (debe) devolver más
           información
       o   Si es un token CONSTANTE, su valor
       o   Si es un identificador, el string correspondiente
       o   Si es un símbolo de puntuación, cuál
       o   Esta información, se devuelve mediante “atributos”. Pero aún puede hacer algo
           más:
       o   Puede detectar algunos (pocos) errores léxicos
       No hay concordancia con ningún patrón
       •   Puede llevar a cabo algunas recuperaciones de errores
       o   Filtrado de caracteres “extraños”
       o   Completar algún patrón
       o   Reemplazar algún carácter


Los componentes léxicos se suelen definir como un tipo enumerado. Se codifican como
enteros. También se suele almacenar la cadena de caracteres que se acaba de reconocer (el
lexema), que se usara posteriormente para el análisis semántico.                            11




                  Elaborado por: Beatriz Pasaca|                           Noveno “A”
Es importante conocer el lexema (para construir la tabla de símbolos). Los componentes
léxicos se representan mediante una estructura registro con tipo de token y lexema.


Especificación de los componentes léxicos: expresiones regulares.


Los componentes léxicos se especifican haciendo uso de expresiones regulares. Además de
las tres operaciones básicas: concatenación, repetición (*) y alternativas (j) vamos a usar los
siguientes meta símbolos:


Una o más repeticiones +


   •   r+ indica una o más repeticiones de r
   •   (0j1)+ = (0j1) (0j1)*


Cualquier carácter.


   •   .*b.* indica cualquier cadena que contiene una letra b


Un rango de caracteres [ ] (clase)


   •   [a-z] indica cualquier carácter entre la a y z minúsculas
   •   [a-zA-Z] indica cualquier letra del abecedario minúscula o mayúscula
   •   [0-9] indica cualquier digito de 0 a 9
   •   [abc] indica ajbj


Cualquier carácter excepto un conjunto dado


   •   ~ (ajb) indica cualquier carácter que no sea una a o b


Opcionalidad ?
                                                                                                  12

r? indica que la expresión r puede aparecer o no. En el caso de que aparezca solo lo haría una
vez.
                 Elaborado por: Beatriz Pasaca|                               Noveno “A”
Aspectos prácticos en la implementación de un analizador léxico


Principio de máxima longitud


Se da prioridad al componente léxico de máxima longitud.
Por ejemplo: <> se interpreta como el operador “distinto de", en vez de “menor que" y “mayor
que".



Palabras reservadas versus identificadores


Un lenguaje de programación puede tener del orden de 50 palabras reservadas. Para evitar
tener un AFD demasiado grande las palabras reservadas se reconocen como identificadores
(una palabra reservada también es una letra seguida de mas letras) y se comprueba antes de
decidir el tipo de token si se trata de una palabra reservada o de un identificador consultando
una tabla previamente inicializada con las palabras reservadas. Este método es recomendable
cuando el número de palabras reservadas es grande.


Entrada de los identificadores en la Tabla de Símbolos


En lenguajes sencillos con solo variables globales y declaraciones, es normal implementar el
scanner para que introduzca los identificadores en la Tabla de Símbolos conforme los va
reconociendo, si es que no han sido ya introducidos. Después, el analizador sintáctico se
encarga de introducir información adicional sobre su tipo, etc. conforme la va obteniendo
durante el análisis sintáctico.

Si se trata de un lenguaje estructurado, el scanner no introduce los identificadores en la Tabla
de Símbolos, porque en este tipo de lenguajes, los identificadores pueden tener diferentes
significados según su contexto (como una variable, como una función, como un campo de una
estructura). Es el análisis sintáctico, cuando ya ha recogido información sobre su ámbito,
cuando introduce los identificadores en la Tabla de Símbolos.                                      13


Gestión del búfer de entrada

                  Elaborado por: Beatriz Pasaca|                               Noveno “A”
El proceso de lectura de los caracteres de la entrada y formar los componentes léxicos es lo
más costoso en tiempo en el proceso de traducción. Es importante implementarlo
eficientemente.
Se utiliza un búfer dividido en dos mitades de tamaño N caracteres, donde N es un bloque de
disco (1024, 4096). Se leen N caracteres de la entrada en cada mitad del búfer con una única
orden de lectura. Se mantienen dos apuntadores. Uno marca el
inicio del lexema y el otro el carácter actual que se mueve hasta encontrar una subcadena que
corresponde con un patrón. Una vez reconocido un componente léxico ambos apuntadores se
colocan en la misma posición y justo detrás del lexema reconocido.


Tratamiento de errores léxicos

Los errores léxicos se detectan cuando el analizador léxico intenta reconocer componentes
léxicos y la cadena de caracteres de la entrada no encaja con ningún patrón. Son situaciones
en las que usa un carácter invalido (@, $,",>,...), que no pertenece al vocabulario del lenguaje
de programación, al escribir mal un identificador, palabra reservada u operador.
Errores léxicos típicos son:


•   Nombre ilegales de identificadores: un nombre contiene caracteres inválidos.

•   Números incorrectos: un numero contiene caracteres inválidos o no está formado
    correctamente, por ejemplo 3,14 en vez de 3.14 o 0.3.14.

•   Errores de ortografía en palabras reservadas: caracteres omitidos, adicionales o
    cambiados de sitio, por ejemplo la palabra hwile en vez de while.

•   Fin de archivo: se detecta un fin de archivo a la mitad de un componente léxico.

En general, la recuperación de errores léxicos es sencilla y siempre se traduce en la
generación de un error de sintaxis que sería detectado más tarde por el analizador sintáctico
cuando el analizador léxico devuelve un componente léxico que el analizador sintáctico no
espera en esa posición.
                                                                                                   14

Los métodos de recuperación de errores léxicos se basan bien en saltarse caracteres en la
entrada hasta que un patrón se ha podido reconocer.
                  Elaborado por: Beatriz Pasaca|                               Noveno “A”
Una buena estrategia para la recuperación de errores léxicos:


Si en el momento de detectar el error ya hemos pasado por algún estado final ejecutamos la acción
correspondiente al último estado final visitado con el lexema formado hasta que salimos de él; el
resto de caracteres leídos se devuelven al flujo de entrada y se vuelve al estado inicial.
Si no hemos pasado por ningún estado final, advertimos que el carácter encontrado no se
esperaba, lo eliminamos y proseguimos con el análisis.


   Por ejemplo, ante la entrada 73:a:


      •   Devolvemos el componente léxico entero con lexema 73;
      •   Devolvemos al búfer de entrada los caracteres :a y
      •   Volvemos al estado inicial.


   En la siguiente llamada al analizador léxico se producirá un nuevo error, en este caso
   descartamos el carácter leído (el punto) y seguimos con el análisis. En la siguiente llamada
   detectamos el identificador a.


   Si se sabe que el siguiente componente léxico es una palabra reservada (en la gramática
   esperamos una palabra reservada) es posible corregir la palabra mal escrita. Por ejemplo, si se
   ha escrito hwile en vez de while o fi en vez de if, intercambiando caracteres adyacentes.



   Implementación de Analizadores léxicos

   1. Usar un generador automático de analizadores léxicos (LEX)

      Ventaja: comodidad y rapidez en el desarrollo

      Desventaja: ineficiencia del analizador resultante y mantenimiento complicado

   2. Escribir el AL en un lenguaje de alto nivel

      Ventaja: más eficiente                                                                         15

      Desventaja: hay que hacerlo todo

                     Elaborado por: Beatriz Pasaca|                                  Noveno “A”
3. Hacerlo en lenguaje ensamblador

   Ventaja: máxima eficiencia

   Desventaja: muy complicado de desarrollar

                                  ANALIZADOR SINTÁCTICO

Definición: Es la fase del analizador que se encarga de chequear la secuencia de tokens que
representa al texto de entrada, en base a una gramática dada. En caso de que el programa de
entrada sea válido, suministra el árbol sintáctico que lo reconoce en base a una representación
computacional. Este árbol es el punto de partida de la fase posterior de la etapa de análisis: el
analizador semántico.

Para obtener en lógica el rigor y precisión deseados, se introduce un lenguaje formal. Éste es
un lenguaje artificial, con unas reglas gramaticales explícitas que indican qué sucesiones de
signos del alfabeto son fórmulas y unas reglas semánticas también explícitas, que determinan
cuando una fórmula es verdadera bajo una determinada interpretación. Éste lenguaje, pues, se
utiliza como vehículo para el razonamiento.


El análisis sintáctico es una aplicación que resulta del estudio de la Teoría de Autómatas y
Lenguajes Formales. El análisis sintáctico es la base del Demostrador de Teoremas, ya que le
permite analizar los componentes léxicos y sintácticos que forman una fórmula para después
poderla evaluar, o no en caso de error, correctamente.

Visión General: Todo lenguaje de programación obedece a unas reglas que describen la
estructura sintáctica de los programas bien formados que acepta. Se puede describir la sintaxis
de las construcciones de los lenguajes de programación por medio de gramáticas de contexto
libre.

Las gramáticas formales ofrecen ventajas significativas a los diseñadores de lenguajes y a los
desarrolladores de compiladores:

   •     Las gramáticas son especificaciones sintácticas y precisas de lenguajes de
                                                                                                    16
         programación.
   •     A partir de una gramática se puede generar automáticamente un analizador sintáctico.

                 Elaborado por: Beatriz Pasaca|                                Noveno “A”
•     El proceso de generación automática anterior puede llevar a descubrir ambigüedades.
   •     Una gramática proporciona una estructura a un lenguaje de programación, siendo más
         fácil generar código y detectar errores.
   •     Es más fácil ampliar/modificar el lenguaje si está descrito con una gramática.


El analizador sintáctico dirige el proceso de compilación, de manera que el resto de fases
evolucionan a medida que el sintáctico va reconociendo la secuencia de entrada por lo que, a
menudo, el árbol ni siquiera se genera realmente.


En la práctica, el analizador sintáctico también:


   •   Incorpora acciones semánticas en las que colocar el resto de fases del compilador
       (excepto el analizador léxico): desde el análisis semántico hasta la generación de
       código.
   •   Informa de la naturaleza de los errores sintácticos que encuentra e intenta recuperarse
       de ellos para continuar la compilación.
   •   Controla el flujo de tokens reconocidos por parte del analizador léxico.


El papel de Analizador sintáctico


El analizador obtiene una cadena de componentes léxicos del analizador léxico, como se
muestra en la siguiente figura, y comprueba si la cadena puede ser generada por la gramática
del lenguaje fuente. El analizador sintáctico informará de cualquier error de sintaxis de manera
inteligente. También debería recuperarse de los errores que ocurren frecuentemente para
poder continuar procesando el resto de su entrada.




                                                                                                   17




                 Elaborado por: Beatriz Pasaca|                                   Noveno “A”
Posición del Analizador sintáctico en el modelo del compilador



Manejo de errores sintácticos


  •   Los errores en la programación pueden ser de los siguientes tipos:
  •   Léxicos, producidos al escribir mal un identificador, una palabra clave o un operador.
  •   Sintácticos, por una expresión aritmética o paréntesis no equilibrados.
  •   Semánticos, como un operador aplicado a un operando incompatible.
  •   Lógicos, puede ser una llamada infinitamente recursiva.
  •   De corrección, cuando el programa no hace lo que el programador realmente deseaba.

                                              Gramáticas

Una Gramática es la definición de un lenguaje. Lenguaje es la colección (finita o no) de
palabras de un alfabeto (representado por å ), por ejemplo, cualquier subconjunto de å *
(conjunto de todas las posibles palabras definidas sobre un alfabeto). El alfabeto del lenguaje L
de la lógica proposicional contiene dos tipos de signos: los conectores y las letras
proposicionales. Se utilizarán: ¬, v, Ù , ® , « como conectores y p, q, r, s, t, ... como letras
proposicionales. Se utilizarán también los paréntesis como signos impropios.


Las fórmulas de L se construyen siguiendo unas sencillas reglas de formación. Dichas reglas
extraen del conjunto de filas de signos del alfabeto aquellas a las que llamamos fórmulas.

La definición de Gramática formal viene dada por la:

Cuádrupla G= ( å t, å n, S, P).

Donde:

å t: es el alfabeto de símbolos Terminales.

å n: es el alfabeto de símbolos No Terminales.
                                                                                                     18
S: es el axioma o símbolo inicial de la gramática.

P: es conjunto finito de producciones xAy::=z / x,y,z eå * Aeån.
                 Elaborado por: Beatriz Pasaca|                                         Noveno “A”
Permite, por tanto, la especificación formal de las reglas de generación de los programas.


Derivaciones: El funcionamiento de las gramáticas se basa en el concepto de derivación.
Comenzando por una cadena formada                 únicamente por el símbolo inicial, se aplican
repetidamente las reglas de P hasta llegar a una cadena formada únicamente por terminales.
Aplicar una regla consiste simplemente en encontrar, dentro de la cadena actual, la parte
izquierda de la regla y sustituirla por la parte derecha correspondiente




Arboles de Ambigüedad
Supongamos que tenemos la gramática:



con las siguientes producciones




                                                                                                  19
La sentencia id*id+id, tiene distintas derivaciones:



                 Elaborado por: Beatriz Pasaca|                                Noveno “A”
Sin embargo, en cierto sentido, todas estas derivaciones representan una misma estructura".
De alguna manera nos transmiten la idea de que se está sumando el producto de los dos
primeros id con el tercero. Podemos representar esto de forma compacta mediante un _árbol
como el siguiente:




Esto es lo que se conoce como _árbol de análisis o de derivación. Intuitivamente, lo que
hacemos es representar en paralelo" las reglas necesarias para derivar la cadena de entrada.
La raíz es el símbolo inicial de la gramática y cada nodo interior representa una producción:
está etiquetado con un no terminal (A) y sus hijos de izquierda a derecha están etiquetados con
X1; X2; : : : ;Xn de modo que (A)    X1X2 : : :Xn es una regla de la gramática.

Puede suceder que una misma cadena tenga asociado más de un _árbol de derivación. Por
ejemplo, la cadena anterior tiene asociados dos _arboles, cada uno con un significado distinto:




                                                                                                  20




                 Elaborado por: Beatriz Pasaca|                                   Noveno “A”
Decimos que una sentencia es ambigua (con respecto a una gramática) si tiene más de un
árbol sintáctico.


Clasificación de las gramáticas

La Jerarquía de Chomsky consta de cuatro niveles:

   •   Gramáticas de tipo 0 (sin restricciones), que incluye a todas las gramáticas formales.
       Estas gramáticas generan todos los lenguajes capaces de ser reconocidos por una
       máquina de Turing. Los lenguajes son conocidos como lenguajes recursivamente
       enumerables. Nótese que esta categoría es diferente de la de los lenguajes recursivos,
       cuya decisión puede ser realizada por una máquina de Turing que se detenga.
   •   Gramáticas de tipo 1 (gramáticas sensibles al contexto) generan los lenguajes sensibles

       al contexto. Estas gramáticas tienen reglas de la forma                       con A un no
       terminal y α, β y γ cadenas de terminales y no terminales. Las cadenas α y β pueden
       ser vacías, pero γ no puede serlo. La regla            está permitida si S no aparece en la
       parte derecha de ninguna regla. Los lenguajes descritos por estas gramáticas son
       exactamente todos aquellos lenguajes reconocidos por una máquina de Turing no
       determinista cuya cinta de memoria está acotada por un cierto número entero de veces
       sobre la longitud de entrada.
   •   Gramáticas de tipo 2 (gramáticas libres del contexto) generan los lenguajes
       independientes del contexto. Las reglas son de la forma             con A un no terminal y
       γ una cadena de terminales y no terminales. Estos lenguajes son aquellos que pueden
       ser reconocidos por un autómata con pila.
   •   Gramáticas de tipo 3 (gramáticas regulares) generan los lenguajes regulares. Estas
       gramáticas se restringen a aquellas reglas que tienen en la parte izquierda un no
       terminal, y en la parte derecha un solo terminal, posiblemente seguido de un no
       terminal. La regla            también está permitida si S no aparece en la parte derecha de
       ninguna regla. Estos lenguajes son aquellos que pueden ser aceptados por un autómata
       finito. También esta familia de lenguajes pueden ser obtenidas por medio de
       expresiones regulares.
                                                                                                     21

Nótese que el conjunto de gramáticas correspondiente a los lenguajes recursivos no es un
miembro de la jerarquía.

                    Elaborado por: Beatriz Pasaca|                               Noveno “A”
Tipos de Gramáticas


Cada lenguaje regular es a su vez libre del contexto, asimismo un lenguaje libre del contexto es
también dependiente del contexto, éste es recursivo y a su vez, recursivamente enumerable.
Las inclusiones son, sin embargo, propias, es decir, existen en cada nivel lenguajes que no
están en niveles anteriores.

Las gramáticas      de tipo 2 o Libres de contexto, son las mas útiles para lenguajes de
programación, en la actualidad son la manera estándar de representar la estructura de los
lenguajes desprogramación.


Gramáticas independientes del contexto


La gramática independiente del contexto consta de terminales, no terminales, un símbolo inicial
y producciones.


 1. Los terminales son los símbolos básicos con que se forman las cadenas.
 2.   Los no terminales son variables sintácticas que denotan conjuntos de cadenas. Los no
      terminales definen conjuntos de cadenas que ayudan a definir el lenguaje generado por la
      gramática.
 3. En una gramática, un no terminal es considerado como el símbolo inicial, y el conjunto de
      cadenas que representan es el lenguaje definido por la gramática.
 4. Las producciones de una gramática especifican cómo se pueden combinar los terminales
      y los no terminales para formar cadenas. Cada             producción consta de un terminal,
                                                                                                    22
      seguido por algún símbolo y seguida por una cadena de no terminales y terminales.


Notación BNF
                   Elaborado por: Beatriz Pasaca|                                Noveno “A”
Utilizada para representar las gramáticas independientes de contexto, que es una escritura
gramatical para especificar lenguajes de programación.
En esta notación se deben seguir las siguientes convenciones:

No terminales: Paréntesis angulares          <>
Terminal: Cadenas de caracteres
El símbolo : := se lee “se define como”, ó se ”reescribe como”, se utiliza en lugar de la flecha.
Varias producciones de tipo:
<A> : := <B1>
<A> : := <B2>
…
<A> : := <Bn>
se pueden escribir como:<A> : := <B1> | < B2> |…| <B n>



                GRAMÁTICAS REGULARES                   GRAMÁTICAS INDEPENDIENTES
                                                            DEL CONTEXTO

•   En el lado derecho existe un nodo terminal          •   Poseen variables A, B, C
    seguido de un no terminal, o un solo terminal, y    •   Poseen cadenas de caracteres.
    en el lado izquierdo existe un nodo no terminal.    •   Genera lenguaje de tipo 2 o
•   Poseen constantes a, b, c.                              lenguaje       independiente       de
•   Genera lenguaje de tipo 3 o lenguaje regular.           contexto.
•   Su importancia reside en que los lenguajes          •   No tiene restricciones con respecto
    generados por ellas son exactamente aquellos            a sus reglas de escritura, su lado
    que reconocen los autómatas finitos.                    izquierdo de cada regla sea un no
•   Existe exactamente un no terminal                       terminal: S →aMa.
•   La parte de la cadena no generada siempre           •   Se utilizan cuando un autómata
    aparece al final.                                       finito     no     reconoce    ciertos
•   Proporciona un plantilla o patrón para las              lenguajes.
    cadenas de lenguajes.                               •   Se      escriben     frecuentemente
•   Si en cada regla α → β cumple:                          utilizando una notación conocida
                                                            con BNF (Backus-Naur).
    α ϵ Vn, y                                           •   Para determinar si están bien
                                                            escritas se utilizan los árboles de
                                                            análisis sintáctico.
    β ϵ Vt, p
                                                        •   Cualquier gramática libre de
                                                            contexto que no contenga la             23
    β ϵ (Vt * Vn)                                           cadena vacía puede ser generado:
                                                            L – {λ} ó L.
                                                        •   El no terminal puede ser uno o
                    Elaborado por: Beatriz Pasaca|                                  Noveno “A”
varios que puede tomar.
                                                                 •   Proporcionar un mecanismo simple
                                                                     y exacto para describir los métodos
- Gramáticas Lineales     - A::=α                                    por los cuales las frases (lenguaje
                                                                     natural) son construidas de
                        por la izquierda → - A::=Va                  bloques más pequeñas.
                                                                 •   Si cada regla: α→β cumple α ϵ Vn.
                                               - S::=λ           •   Cumple los requerimientos para
                                                                     ser una gramática tipo 1.
 Se clasifican en: - Gramáticas Lineales      - A::=a

                            por la derecha → - A::=aV

                                                    - S::=λ

 Cumple con los requerimientos para ser una
 gramática de tipo 2.

                        Diferencias entre Gramáticas Regulares y gramáticas Libes de contexto



                                       Ejercicios resueltos en clases:


 Sea la gramática:         S → AA
                           A → AAA | a | bA |Ab

 Determinar la cadena b2aba2ba → bbabaaba

 S →AA→ bAA → bbAA → bbaA → bbabA → bbabAAA → bbabaAA → bbabaAbA→ bbabaabA → babaaba


 Arboles de derivación

 Sea la gramática:         S → AB
                           A → aA | a
                           B → bB | b


 Determinar la cadena aabbb elaborar el árbol de derivación.

 S →AB→ aAB → aaB →aabB → aabbB → aabbb
 S → AB → aAbB → aabbB → aabbb                                                                               24
 S → AB → abB → AbbB → Abbb → aAbbb →aabbb



                     Elaborado por: Beatriz Pasaca|                                             Noveno “A”
Árbol de Derivación de la cadena aabbb


Se puede concluir que la gramática anteriormente definida no es ambigua, ya que a pesar de tener
derivaciones diferentes, posee un solo árbol de derivación.


   Sea la gramática: S → SbS | ScS | a , construir el árbol de derivación para la cadena abaca

   Derivaciones:
    1. S → SbS → abS → abScS → abaca
    2. S → SbS → SbScS → abaca
    3. S → ScS → SbScS → abaca




                                Árboles de Derivación para la cadena abaca
                                                                                                          25
Ambigüedad: La presencia de dos derivaciones por la izquierda distintos se corresponde con la
existencia de dos árboles de derivación distintos por lo tanto una gramática ambigua se caracteriza por
tener dos o más derivaciones por la izquierda para la misma cadena.

                  Elaborado por: Beatriz Pasaca|                                      Noveno “A”
Derivación por la izquierda

    1. S → ScS → SbScS → abScS → abacS → abaca

        El no terminal se expande siempre del extremo izquierdo.

   Derivación por la derecha

    2. S → ScS → SbSca → Sbaca → abaca

        El no terminal es el que se expande por la derecha.


       •   Toda derivación en una gramática regular, es a la vez una derivación por la izquierda y por la
           derecha sin tener en cuenta si tenemos una gramática regular por la derecha o por la izquierda.


                          Simplificación de Gramáticas Independientes de Contexto

   Para realizar la simplificación de estas gramáticas debemos hacer lo siguiente:


1. Eliminar las producciones en donde se encuentre contenida la palabra vacía (ε ó λ).

   Gramática:
      1. A → bAA | aC | B
      2. B → aSS | BC
      3. C→ CC | λ
      4. S → SS | C A

   Para ello reemplazamos la cadena vacía en todos los no terminales que la produzcan así:

       1. A → bAA | aC | B
          A → bAA | a λ | B | a λ
          A → bAA | a | B | a

       2. B → aSS | BC | B λ
          B → aSS | BC | B

       3. C→ CC | C λ
           C→ CC | C                                                                                         26

       4. S → SS |CA| λA
          S → SS | C A | A
                     Elaborado por: Beatriz Pasaca|                                      Noveno “A”
La gramática resultante será:
          A → bAA | a | B
          B → aSS | BC | B
          C→ CC | C
          S → SS | C A | A

2. Eliminar las producciones unitarias

   Se considera una producción unitaria cuando es de la forma B → B
   Identificamos las producciones unitarias y luego reemplazamos el nodo o no terminal unitario con la
   parte derecha de todas las producciones que produce así:
           A → bAA | a | B
           B → aSS | BC | B
           C→ CC | C
           S → SS | C A | A

   La gramática resultante será:

           A → bAA | a | aSS | BC
           B → aSS | BC
           C→ CC
           S → SS | C A | bAA | a | aSS | BC

 3. Eliminar no terminales no generativos

   Para esta gramática el no terminal no generativo es C ya que no produce terminal alguno, entonces
   eliminamos todas las producciones que lo contengan:
      A → bAA | a | aSS | BC
      B → aSS | BC
      C→ CC
      S → SS | C A | bAA | a | aSS | BC

   La gramática que nos queda es:

      A → bAA | a | aSS
      B → aSS
      C→ CC
                                                                                                         27
      S → SS | bAA | aSS | a

   4. Eliminar los símbolos no alcanzables

                     Elaborado por: Beatriz Pasaca|                                     Noveno “A”
Los símbolos no alcanzables son aquellos que no son producidos por algún axioma o no terminal,
        para nuestro ejercicio los símbolos no alcanzables son los no terminales B y C.


         A → bAA | a | aSS
         B → aSS
         C→ CC
         S → SS | bAA | aSS | a

        Entonces la gramática simplificada nos queda:
                                                     A → bAA | a | aSS
                                                     S → SS | bAA | aSS | a
        NOTA: Para una mejor eficiencia de la simplificación se deben aplicar todos los pasos
        anteriormente mencionado en orden.

                                            Ejercicios resueltos en clases:


                                                  G = ({0,1}, {A, A, B, C}, S, P)
                                                   P S → AB |0S1| A |CX
                                                          A → 0AB | λ
                                                           B → B1 | λ

1. Eliminar los no terminales inútiles                             2. Eliminar producciones vacías λ
   S → AB |0S1| A                                                   S → AB |0S1|A|B| λ
   A → 0AB | λ                                                      A → OAB |0A|OB| O
   B → B1 | λ                                                       B → B1 | 1

3. Eliminar producciones unitarias
   S → AB |0S1|OAB|OA|OB|O|B1|1| λ
           A → OAB |0A|OB| O
           B → B1 | 1

    G = ({i,+}, {Z, E, F, G, P, Q, S, T}, Z, P)
    P Z→E+T|T
                   E→E|S+F|T
         F → F | FP | P
                   P→G
         G → G | GG | F
                                                                                                               28
         T→T+i|i
        Q→E|E+F|T|S
         S→i

                          Elaborado por: Beatriz Pasaca|                                          Noveno “A”
1. Eliminar los no terminales inútiles                    2. Eliminar producciones vacías λ
         Z→ E + T                                                 Z→ E + T
        E→E|S+F|T                                                E→T
        F → F | FP | P                                            T→T+i|i

        P→G
        G → | GG | F
        T→T+i|i
        S→i

3. Eliminar producciones unitarias
         Z→T+T                            Z→T+T
        T →T+i|i            ó             E→T+i|i
         T→T+i|i

 1. FORMA NORMAL DE CHOMSKY

     Se aplica: A → BC                     No se puede aplicar cuando:
                A→a                          - Hay producciones vacías
              A, B, C ϵ V, a ϵ ∑              - Hay producciones unitarias

         EJERCICIO

     B → aBC
     E → aBEd

 1. Eliminar producciones vacías λ                               2. Reemplazamos en la gramática
    Da → a                                                             B → DaBC
    Dd → d                                                             E → DaBEDd

     Base (2) → Longitud de la parte derecha sea mayor que dos
     A → CBFH                   A → D1FH
                                D1 → CB
                                A → D1D2
                                D2 → FH

                                          Ejercicio resuelto en clases:
                                                                                                              29
     Dada la siguiente expresión regular, determinar el AFD, la gramática y el árbol de derivación para una
     cadena valida.

                         Elaborado por: Beatriz Pasaca|                                    Noveno “A”
Expresión regular → letra+_numero+letra+ | _letra*




    Gramática:
    <inicio> → _ <guion>
    <inicio> → l <letra>
    <guion> → l <letra> | n <numero>
    <letra> → n <numero> | l_<guion> | λ
    <numero> → l <letra>

•   Derivación de la cadena _a

    <inicio> → _<guion>                                           <inicio>
    <guion> → _a <letra>
    <letra> → _a λ                                       _                   <guion>
    <letra> → _a
                                                                         a        <letra>

                                                                                        λ

                                       Ejercicio resuelto en clases:
    Simplificar la gramática:
    S → A | Aa
    A→B
    B→C|b
    C → D | ab
    D→b
1. Unitario(S) → {S, A, B, C, D}             2. S → Aa | b | ab                  3. S → Aa | b | ab      30
   Unitario (A) → {A, B, C, D}                  A → b | ab                              A→ b | ab
   Unitario (B) → {B, C, D}                     C → ab | b
   Unitario (C) → {C, D}                       D→d

                       Elaborado por: Beatriz Pasaca|                                       Noveno “A”
Aplicar la forma normal de Chomsky en la siguiente gramática:

   S → bA | aB                     S → DbA | DaB
   A → bAA | aS |a                 A → DbD1 | DaS |Da
   B → aBB | bS | b                B →DaD2 | bS | b
                                   Da → a
                                   Db → b
                                   D1→ AA
                                   D2 → BB

   Simplificar las gramáticas dadas:

   Gramática 1:
   S → AB| Cb
   A → f | Al
   B → t | CF
   D→a|t

1. Términos no Generativos                   2. Términos no Alcanzables
   S → AB                                       S → AB
   A → f | Al                                   A → f | Al
   B→t                                           B→t
   D→a|t

   Gramática 2:
   S → aA| λ
   A → aA | bB | λ
   B → bB

1. Producciones vacías               2. Términos no Generativos           3 Términos no alcanzables
   S → aA| λ                            S → aA| λ                           S → aA| λ
   A → aA | bB | a                      A → aA | a                          A → aA | a
   B → bB                               B → bB


   Gramática 3:
   S → a| aA | B | E
   A → aB | λ
                                                                                                       31
   B → Aa
   E → bED
   D → ccc

                       Elaborado por: Beatriz Pasaca|                                     Noveno “A”
1. Producciones vacías                  2. Producciones unitarias
   S → a| aA | B | E                       S → a| aA | Aa |bED
   A → aB | a                              A → aB | a
   B → Aa | a                              B → Aa | a
   E → bED                                 E → bED
   D → ccc                                 D → ccc

3.    Términos no Generativos           4. Términos no alcanzables
     S → a | aA| Aa                       S → a |aA| Aa
     A → aB |a                            A → aB | a
     B → Aa | a                           B →Aa | a
     E → bED
     D → ccc

     Gramática 4:
     S → ABaC
     A → AB
     B → b |λ
     C→D|λ
     D→d

2. Producciones vacías            2. Producciones unitarias          3. Términos no alcanzables
   S → ABaC |AaC | ABa | Aa          S → ABaC |AaC | ABa | Aa            S→ABaC|AaC|ABa|Aa
   A → AB | A                        A → AB                              A→AB
   B →b                               B →b                               B→b
   C→D                                C→D                                C→d
   D→d                                D→d

     Análisis

     Es el proceso que permite determinar si una cadena puede ser generada por una gramática. En
     nuestro caso es el proceso que permite determinar si una fórmula está bien generada o no.
     Este proceso es fundamental en el Demostrador de Teoremas ya que una cadena que no sea
     una fórmula no servirá para realizar los razonamientos o pruebas. Por tanto es importante
     definir precisamente un analizador para esta tarea.

                                                                                                    32
     Desde el punto de vista formal un analizador es un Autómata equivalente a una gramática, que
     reconoce la estructura de una cadena de componentes léxicos.

                      Elaborado por: Beatriz Pasaca|                                  Noveno “A”
Objetivos del analizador sintáctico (AS)

El AS es la parte principal de un compilador. Las funciones principales de AS son:


    •   Comprobar si el programa es sintácticamente correcto.
    •   Generar las estructuras de datos (árboles sintácticos u otras estructuras) que
        representan el programa y sirven para el analizador semántico y el generador de
        código.
    •   En el caso de compilación dirigida por sintaxis -- llamar al analizador semántico y al
        generador de código.

        Otras:


•   Reaccionar frente a los errores e intentar acotar la propagación de los errores (intentar
    evitar que un error produzca muchos mensajes de error).
•   Hacer los siguientes pasos del compilador más independientes de la sintaxis del lenguaje.

Comportamiento del analizador sintáctico


El proceso de análisis sintáctico y la ejecución son ahora dos pasos completamente separados,
no se procederá a la ejecución del código de cualquier archivo hasta que éste en su totalidad,
así como todo el código requerido se haya analizado completa y satisfactoriamente.


Uno de los nuevos requisitos introducidos con esta separación es que todos los archivos
requeridos y de inclusión tienen que ser sintácticamente completos ahora. Ya no es permitida
la separación de diferentes segmentos de una estructura de control a través de varios archivos.
Esto quiere decir que ahora no puede iniciar un ciclo for o while, una sentencia if o un bloque
switch en un archivo, y tener el final del ciclo, sentencias else, endif, case o break en un archivo
diferente.

Aun es perfectamente legal incluir código adicional al interior de ciclos u otras estructuras de
control, únicamente las palabras claves de control y los corchetes correspondientes {___}
tienen que estar en la misma unidad de compilación (archivo o cadena procesada por eval ()).           33




                  Elaborado por: Beatriz Pasaca|                                  Noveno “A”
Esto no debe generar una repercusión significativa ya que separar el código de esta manera
debe ser considerado como muy mal estilo, en cualquier caso.

Algo más que ya no es posible, aunque es rara veces visto en código PHP 3, es devolver
valores desde un archivo requerido devolver un valor desde un archivo de inclusión es posible
aun.

Un analizador sintáctico, tal y como se ha enfocado en esta librería es una clase que recibe lo
siguiente:

1. Una clase donde se almacenarán los atributos de cada símbolo.

2. Una gramática libre de contexto donde el símbolo de inicio solo produce una variable.

3. Una función de síntesis para cada producción, encargada de sintetizar los atributos
necesarios.

4. Para cada producción una opcional regla para deshacer ambigüedades.

5. Una instancia de una clase de léxico que derive de la clase abstracta de léxico básico.

6. Una opcional función de error para manejarlos y recuperarse en la medida de lo posible.

El analizador ira leyendo del léxico y aplicando las reducciones necesarias (llamando a las
funciones de síntesis proporcionadas). El resultado habitual es un árbol sintáctico construido de
manera ascendente. Cada nodo de ese árbol es del tipo genérico que se le pasa como
parámetro al parser mencionado en la lista anterior.


Función del análisis sintáctico.

Analizar sintácticamente una tira o cadena de tokens no es más que encontrar para ella el árbol
sintáctico o de derivación que tiene como raíz el axioma de la gramática, y como nodos
terminales la sucesión ordenada de símbolos que componen la cadena analizada.
                                                                                                     34
En caso de no existir este árbol sintáctico, la cadena no pertenecerá al lenguaje, y el analizador
sintáctico ha de emitir el correspondiente mensaje de error.

                 Elaborado por: Beatriz Pasaca|                                 Noveno “A”
Existen dos formas de analizar sintácticamente una cadena:

    Análisis descendente: Partiendo del axioma inicial de la gramática se va descendiendo
utilizando las derivaciones izquierdas, hasta llegar a construir la cadena analizada.


    Análisis ascendente: Se va construyendo el árbol desde sus nodos terminales. Es decir, se
construye desde los símbolos de la cadena hasta llegar al axioma de la gramática. En este
caso, se emplean normalmente las derivaciones más a la derecha hasta la localización de la
raíz.


Los principales métodos de análisis sintáctico son:


Análisis descendente:


•   Análisis descendente con retroceso.
•   Análisis de gramáticas LL.


Análisis ascendente:


•   Análisis ascendente con retroceso.
•   Análisis de gramáticas de precedencia simple.
•    Análisis de gramáticas de precedencia generalizada.
•   Análisis de gramáticas por el método mixto.
•   Análisis de gramáticas de precedencia de operador.
•   Análisis de gramáticas LR.


Los análisis con retroceso se basan en la prueba sistemática de todas las alternativas posibles,
dando marcha atrás tan pronto como se detecte que el camino seguido es erróneo.

Pueden usarse para cualquier gramática de contexto libre, aunque tienen tres grandes
inconvenientes:
                                                                                                   35
Primero, emplean mucho más tiempo para el análisis que los demás analizadores,
dependiendo éste incluso de la ordenación de las reglas gramaticales.


                  Elaborado por: Beatriz Pasaca|                                 Noveno “A”
Segundo, no dan un buen diagnóstico de los errores que encuentran; Tercero, complican la
    generación de código cuando ésta se realiza al par que el análisis sintáctico.


    Los métodos más eficientes de análisis (tanto ascendente como descendente) no funcionan
    para todas las gramáticas de contexto libre, sino sólo para las gramáticas que cumplen unas
    determinadas condiciones.


    Afortunadamente, en la mayoría de los casos, pueden encontrase para los lenguajes de
    programación gramáticas de tipo LL o LR que los generen.


    Para representar el árbol sintáctico que conduce hasta una cadena se asigna a cada regla de
    la gramática un número. Se define el parse como la secuencia ordenada de números (de
    reglas) aplicadas para construir dicho árbol.


    Hay dos tipos de parse, que son:


•   El parse-izquierdo: Son los números de las reglas de derivación izquierda utilizadas para
    generar la cadena a partir del axioma, por tanto correspondiente a un análisis descendente.


•   El parse-derecho: Son los números de las reglas de derivación derecha utilizadas para
    generar la cadena a partir del axioma, en orden inverso. El tomar el orden inverso viene
    condicionado por ser el análisis ascendente el que normalmente utiliza las reglas de derivación
    derecha, con lo que el orden en el que aparecen al realizar el análisis es invertido.


    Simultáneamente a la fase de análisis sintáctico, además de reconocer las secuencias de
    tokens, y analizar su estructura, pueden realizarse una serie de tareas adicionales, como:


       •   Recopilar información de los distintos tokens y almacenarla en la tabla de símbolos.
       •   Realizar algún tipo de análisis semántico, tal como la comprobación de tipos.
       •   Generar código intermedio.
       •   Avisar de los errores que se detecten.
                                                                                                      36

    Análisis Sintáctico (LL1):


                     Elaborado por: Beatriz Pasaca|                                  Noveno “A”
Definición: Aquel en el que se agrupan todas las clausuras con idéntica parte izquierda. Es
decir todas las clausuras del tipo:
       A -> B C D
       A -> E F G
       ......
       A ->X Y Z
Si no existen dos clausuras con idéntica parte izquierda que pueden empezar con un mismo
símbolo terminal, y no existe recursividad a la izquierda, el lenguaje es LL1.


Para Aplicar el Algoritmo LL (1) se procede de la siguiente forma:
  1. Se debe eliminar de la gramática recursividad por la izquierda (en caso de que la tuviera).
  2. Realizar factorización a la izquierda en caso de que la gramática lo requiera.
  3. Determinar el conjunto de primeros y siguientes.
  4. Construir la tabla de Análisis LL(1).
  5. Validar una cadena.


Para comprender cada uno de los pasos del algoritmo descrito anteriormente tomaremos como
ejemplo la siguiente gramática:
                                  Ejercicio resuelto en clases:

S -> if E then S | while E do S | I := E

I -> * I | id A

A -> Ɛ | [E]

E -> I | cte

REGLAS PARA DETERMINAR LOS PRIMEROS
1. Si X es terminal, entonces PRIMERO(X) es {X}.


2. Si X -> £ es una producción, entonces agregar £ al PRIMERO(X).


3. Si X es no terminal y X -> Y1 Y2 ... Yk es una producción,            entonces agregar µ en     37

PRIMERO(X) si para algún i, µ está en PRIMERO(Yi), y £ está en todos los
  PRIMERO(Y1),...,PRIMERO(Yi-1).

                  Elaborado por: Beatriz Pasaca|                                 Noveno “A”
PRIMERO( S ) = { if, while } U P( I )            =>{ if, while,*id }

PRIMERO( I ) = { *, id }                         => { *,id }

PRIMERO( A ) = { Ɛ, [ }                          => { Ɛ,[ }

PRIMERO( E ) = { cte } U P( I )                  => {*, id , cte }


Reglas para obtener el conjunto de los siguientes:
La idea es que los siguientes de un no terminal (A) son aquellos terminales que pueden
llegar a aparecer detrás de (A) en alguna forma sentencial. En el caso del símbolo inicial
y de aquellos que pueden aparecer al inicial de una forma sentencial, además incluimos el
fin de la entrada.
Para encontrar los siguientes de cada no terminal, podemos emplear las siguientes ecuaciones:




1. Como inicialización, asociamos a todos los no terminales distintos del inicial el conjunto
vacío y al símbolo inicial le asociamos el conjunto f ($), para que se cumpla la ecuación
(1).


2. Para cumplir con la ecuación (2), añadimos al conjunto de siguientes de cada no
terminal (A) los primeros de los β tales que α(A) β constituye la parte derecha de alguna
regla.
                                                                                                38




                     Elaborado por: Beatriz Pasaca|                              Noveno “A”
3. Recorremos ordenadamente las reglas aplicando la ecuación (3). Para ello, por cada
regla (A)   α(B) β con β anulable, añadimos los siguientes de (A) a los de (B) Este paso
tendremos que repetirlo hasta que no cambie ninguno de los conjuntos de siguientes en
un recorrido completo de las reglas.




Vamos a aplicar el algoritmo a nuestro ejemplo. En primer lugar, inicializamos los
siguientes al conjunto vacio salvo para el símbolo inicial:




Después, añadimos los símbolos que aparecen inmediatamente después de cada no terminal:




Ahora aplicamos ordenadamente la ecuación (3) hasta que no haya modificaciones. Así




                                                                                           39
Con la regla (E) (I), aumentamos los siguientes de (I):


                 Elaborado por: Beatriz Pasaca|                             Noveno “A”
A partir de (I) id(A), aumentamos los siguientes de (A):




Si volvemos a repasar las reglas, vemos que los siguientes no varían, así que podemos dar por
terminado el proceso.


SLR:
La mayor inconveniencia de los analizadores LL1 es el conjunto bastante limitado de los
lenguajes LL1. Un conjunto bastante más amplio, que incluye casi todos los lenguajes de
programación, es el SLR.


Definición: Un lenguaje de tipo SLR si existe un analizador SLR que permita analizarlo.


Comentario: Al igual que el analizador SLR, éste se construye siguiendo un algoritmo, por lo
tanto no podemos hablar de tautología.


Un algoritmo para construir SLR, orientado a “ejecutarse” a mano se encuentra descrito en el
apartado 2.


¿Qué hace?

                                                                                                40
En general, un analizador sintáctico es un autómata a pila. El analizador sintáctico:
Inicializa el compilador y AS en particular.

                 Elaborado por: Beatriz Pasaca|                                  Noveno “A”
•    Para cada símbolo de entrada llama al analizador morfológico y el AM proporciona el
     siguiente símbolo de entrada.
•    Analizando el símbolo, la pila y el estado del autómata, el AS produce las estructuras
     necesarias para la siguiente etapa y en el caso de compilación dirigida por la sintaxis --
     invoca llamadas directas al analizador semántico y al generador de código.
•    Escribe mensajes de errores y trata de limitar el efecto de estos errores.

Elección de algoritmos. Consideración de las diferencias, ventajas y desventajas.

Plan de desarrollo


Etapas:

1. Elegir el tipo del analizador sintáctico.

2. Trasformar el lenguaje al tipo correspondiente. Calcular las tablas correspondientes.

3.   Escribir el programa del analizador sintáctico sin acciones ni producción de código.

4.   Añadir al analizador atributos y acciones (en la parte del analizador sintáctico solo la
producción de la salida, tal como se explica en los requisitos de prueba).

5.    Añadir al analizador generador de código.

Propiamente hablando, sólo el segundo y el tercer punto forman el analizador sintáctico por sí.
El resto es analizador semántico y el generador de código. En todos los modos se requiere una
vista general al definir como vamos a realizar el analizador sintáctico.




                                   ANALIZADOR SEMÁNTICO.

Introducción.
                                                                                                  41
Es aquel que se ocupa de analizar si la sentencia de caracteres tiene algún significado. Se
pueden encontrar sentencias que son sintácticamente correctas pero que no se pueden

                  Elaborado por: Beatriz Pasaca|                                  Noveno “A”
ejecutar porque carecen de sentido. El análisis semántico se hace a la par que el análisis
sintáctico introduciendo en éste unas rutinas semánticas.


El análisis semántico utiliza como entrada el árbol sintáctico detectado por el análisis sintáctico
para comprobar restricciones de tipo y otras limitaciones semánticas y preparar la generación
de código. El instrumento más utilizado para conseguirlo es la gramática de atributos.

Gramáticas semánticas


Una gramática semántica es una gramática libre de contexto en la cual la elección de símbolos
no terminales y de reglas de producción son regidos tanto por funciones sintácticas como
semánticas. Muchos símbolos no terminales representan elementos semánticos; esto es, que
su posición depende también del tema que se este tratando. Una gramática semántica puede
ser usada por un sistema de análisis gramatical de la misma forma en que pudiera ser usada
una gramática estrictamente sintáctica. Las principales ventajas son las siguientes:


        •   Cuando el análisis gramatical esta completo, el resultado puede ser usado
            inmediatamente sin otra etapa de proceso que pudiera ser requerida si una
            interpretación semántica no hubiese sido realizada durante el análisis.
        •   Muchas ambigüedades que pueden surgir durante un análisis gramatical
            estrictamente sintáctico son evitadas al tomar en cuenta criterios semánticos
            durante el análisis.

            Sin embargo, existen también algunas desventajas en el uso de gramáticas
            semánticas.


        •   El número de reglas requeridas pueden llegar a ser demasiado grande ya que
            faltaría muchas generalizaciones sintácticas.


        •   Debido a lo anterior, el análisis gramatical puede ser muy lento y ocupar mucho
            espacio en memoria.

                                                                                                      42
Se puede observar que las gramáticas semánticas pueden ser útiles para producir interfaces de
subconjuntos de lenguaje natural.


                 Elaborado por: Beatriz Pasaca|                                  Noveno “A”
Gramática con atributos.


Una gramática con atributos es una gramática de contexto libre cuyos símbolos pueden
tener asociados atributos y las producciones pueden tener asociadas reglas de evaluación
de los atributos.

   •   Cada símbolo puede tener asociado un número finito de atributos.

   •   Cada producción puede tener asociada un número finito de reglas de evaluación
        de los atributos.

   •   Los valores de los atributos deberán estar asociados con un dominio de valores.


   •   Por lo general las gramáticas con atributos se escriben en forma tabular, con cada
        regla Gramatical enumerada con el conjunto de ecuaciones de atributo o reglas
        semánticas asociadas con esa regla de manera siguiente:



            Regla Gramatical                     Regla Asociada


            Regla 1                              Ecuaciones de atributo asociadas

            …                                    ….

            Regla n                              Ecuaciones de atributo asociadas
                             Representación de las gramáticas con atributos




Atributos Heredados y Atributos Sintetizados


                Atributos Sintetizados                        Atributos Heredados


       Si b está asociado con el símbolo no                   Si b está asociado con el          43
       terminal A                                             símbolo no terminal α



                    Elaborado por: Beatriz Pasaca|                                  Noveno “A”
Evaluación: Las reglas de evaluación de                      Evaluación: La Evaluación de
         los atributos sintetizados se realizan                       un atributo heredado depende
         cuando se aplican reducciones en el                          de los atributos asociados con
         análisis sintáctico.                                         los símbolos precedentes en la
                                                                      derivación.

         Requisitos para la evaluación:                               Requisitos para la evaluación:

             Las reglas de evaluación de los                             Realizar     un         análisis
             atributos deben definirse en función                        descendente.
             de los atributos asociados con los
             atributos gramaticales a la derecha.

             Realizar un análisis ascendente



                           Diferencias entre Atributos Sintetizados y Atributos Heredados

Ejemplo:

Gramática de Atributos Sintetizados


exp       exp + term | exp – term | term
term       term * factor | factor
factor      (exp) | numero

Se pide obtener la gramática con atributos, dada la expresión: (34-3)*42 y expresar la
semántica de su valor en un árbol de análisis gramatical.

Empezamos obteniendo la derivación por la izquierda para la expresión dada:

exp      term    term * factor     factor * factor    (exp) * facto     (exp – term ) * factor
         (term – term ) * factor     (factor – term) * factor   (numero – term ) * factor
         (numero –factor) * factor      (numero –numero) * factor         ( numero –numero) *numero


Luego de ello podemos construir el árbol de análisis gramatical para (34-3)*42, mostrando
cálculos del atributo val.
                                                                                                              44




                      Elaborado por: Beatriz Pasaca|                                             Noveno “A”
Árbol de análisis gramatical


Nótese que el atributo principal de una exp o term o factor es su valor numérico (val) el
cual va ha formar parte de las ecuaciones para las reglas semánticas que se muestran a
continuación:




                                                                                            45




                Elaborado por: Beatriz Pasaca|                               Noveno “A”
Regla Gramatical                 Regla Semántica


               exp1     exp2 + term         exp1. val= exp2.val + term.val
               exp1     exp2 – term         exp1.val = exp2.val – term.val
               exp      term                exp.val = term.val
               term1     term2 * factor     term1.val = term2.val * factor.val

               term     factor              term.val = factor.val
               factor    (exp)              factor.val = (exp) .val
               factor    numero             factor.val = numero.val

Ejemplo de Gramática con atributos heredados


Realizar un análisis descendente, dada la siguiente gramática y las reglas de evaluación.




                                                                                              46




                 Elaborado por: Beatriz Pasaca|                                  Noveno “A”
BIBLIOGRAFÍA

        FUENTES PRIMARIAS:

•   ALFONSECA M. Manuel, ”Compiladores e Interpretes”. Editorial PEARSON
    EDUCACION 2006.
•   ALFRED V, Aho; RAVI, Sethi; JFFREY D, Ullman “Compiladores Principios, técnicas
    y herramientas”. Addison-Wesley. Iberoamericana 1990.
•   KELLEY, Dean. “Teoria de Automatas y Lenguajes Formales”. Editorial PRENTICE
    HALL 1995.
•   KENET LOUDEN Construcción de Compiladores Principios y Práctica._ UNED 2004.

        FUENTES SECUNDARIAS:

    •    AHO, Alfred y ULLMAN, Jeffrey.2005, Compiladores Principios, Técnicas y
         Herramientas, Edición Electrónica
    •    ANTONIO,      Reyes Oscar; POSADAS, Martínez Wendi; RODRÍGUEZ, Alemán
         Magdalena; ROSAS, Gómez Lizzeth Del Carmen; ROSAS, Hernández José
         Alberto. LENGUAJES Y AUTÓMATAS CS51.              [en linea]. Colombia Bogota,
         [http://mx.geocities.com/amigos2365/anteproyecto.html], [Consulta: 15 Octubre
         2008].
    •    BONILLA,Oscar.[http://74.125.45.104/search?q=cache:A9YLY0RcmuUJ:oscarbonil
         la.com/courses/compilrs/materials/06_Analisis_Sintactico.ppt+analizador+sint%C3
         %A1ctico&hl=es&ct=clnk&cd=11]
    •    Ceballos, Carmona Miguel Ángel. 2002. Compiladores. [en línea]. Irapuato, Gto,
         [http://www.monografias.com/trabajos11/compil/compil2.shtml]        ,[Consulta:   14
         Octubre 2008].
    •    GÁLVEZ ROJAS, Sergio Y MORA MATA, Miguel Ángel. .2005, Java a Tope:
         Traductores y Compiladores con Lex/Yacc, JFlex/Cup y JavaCC, Edición
         Electrónica

•Universidad        de       Huelva,        Procesadores                de           lenguaje,
http://www.uhu.es/470004004/docs/tema4_ejercicios.pdf                                            47




                  Elaborado por: Beatriz Pasaca|                                  Noveno “A”
•Universidad Nacional de Río Cuarto, Departamento de Computación, Autómatas y
Lenguajes, Practicó 6 - Parsing y Gramáticas LR 2009,
http://dc.exa.unrc.edu.ar/nuevodc/materias/automatas/reposit/1173382040/ayl_prac_6.pdf




                                                                                         48




                Elaborado por: Beatriz Pasaca|                             Noveno “A”

Más contenido relacionado

La actualidad más candente

Alfabetos-Lenguajes y Automatas 1
Alfabetos-Lenguajes y Automatas 1Alfabetos-Lenguajes y Automatas 1
Alfabetos-Lenguajes y Automatas 1Osiris Mirerus
 
Cuadro comparativo de softwares de de metodos numericos
Cuadro comparativo de softwares de de metodos numericosCuadro comparativo de softwares de de metodos numericos
Cuadro comparativo de softwares de de metodos numericosJuanCarlos210997
 
Algorithms Lecture 1: Introduction to Algorithms
Algorithms Lecture 1: Introduction to AlgorithmsAlgorithms Lecture 1: Introduction to Algorithms
Algorithms Lecture 1: Introduction to AlgorithmsMohamed Loey
 
Clasificasion de lenguajes
Clasificasion de lenguajesClasificasion de lenguajes
Clasificasion de lenguajesAlex Javier
 
Analisis Lexico
Analisis LexicoAnalisis Lexico
Analisis LexicoFARIDROJAS
 
1.4 software numerico
1.4 software numerico1.4 software numerico
1.4 software numericomorenito9001
 
Generador de codigo intermedio
Generador de codigo intermedioGenerador de codigo intermedio
Generador de codigo intermedioGuillermo
 
2.1 & 2.2 grammar introduction – types of grammar
2.1 & 2.2 grammar introduction – types of grammar2.1 & 2.2 grammar introduction – types of grammar
2.1 & 2.2 grammar introduction – types of grammarSampath Kumar S
 
DiseñO De Compilador
DiseñO De CompiladorDiseñO De Compilador
DiseñO De CompiladorBigbossH
 

La actualidad más candente (20)

Lenguajes no regulares
Lenguajes no regularesLenguajes no regulares
Lenguajes no regulares
 
Alfabetos-Lenguajes y Automatas 1
Alfabetos-Lenguajes y Automatas 1Alfabetos-Lenguajes y Automatas 1
Alfabetos-Lenguajes y Automatas 1
 
Cuadro comparativo de softwares de de metodos numericos
Cuadro comparativo de softwares de de metodos numericosCuadro comparativo de softwares de de metodos numericos
Cuadro comparativo de softwares de de metodos numericos
 
Latex slides
Latex slidesLatex slides
Latex slides
 
Yacc
YaccYacc
Yacc
 
Jerarquia de chomsky
Jerarquia de chomskyJerarquia de chomsky
Jerarquia de chomsky
 
Algorithms Lecture 1: Introduction to Algorithms
Algorithms Lecture 1: Introduction to AlgorithmsAlgorithms Lecture 1: Introduction to Algorithms
Algorithms Lecture 1: Introduction to Algorithms
 
Clasificasion de lenguajes
Clasificasion de lenguajesClasificasion de lenguajes
Clasificasion de lenguajes
 
Analisis Lexico
Analisis LexicoAnalisis Lexico
Analisis Lexico
 
Programación 1: cadenas en C
Programación 1: cadenas en CProgramación 1: cadenas en C
Programación 1: cadenas en C
 
Ejercicios
EjerciciosEjercicios
Ejercicios
 
1.4 software numerico
1.4 software numerico1.4 software numerico
1.4 software numerico
 
Generador de codigo intermedio
Generador de codigo intermedioGenerador de codigo intermedio
Generador de codigo intermedio
 
Grafos Y Digrafos
Grafos Y DigrafosGrafos Y Digrafos
Grafos Y Digrafos
 
Syntax analysis
Syntax analysisSyntax analysis
Syntax analysis
 
2.1 & 2.2 grammar introduction – types of grammar
2.1 & 2.2 grammar introduction – types of grammar2.1 & 2.2 grammar introduction – types of grammar
2.1 & 2.2 grammar introduction – types of grammar
 
Tutorial de CodeBlocks
Tutorial de CodeBlocksTutorial de CodeBlocks
Tutorial de CodeBlocks
 
Introducción a html 5
Introducción a html 5Introducción a html 5
Introducción a html 5
 
Syntax
SyntaxSyntax
Syntax
 
DiseñO De Compilador
DiseñO De CompiladorDiseñO De Compilador
DiseñO De Compilador
 

Destacado

Simplificación de gramáticas independientes de contexto
Simplificación de gramáticas independientes de contextoSimplificación de gramáticas independientes de contexto
Simplificación de gramáticas independientes de contextoEduardo Tello
 
1...1 noam chomsky (gramatica generativa, automata de pila, etc.)
1...1 noam chomsky (gramatica generativa, automata de pila, etc.)1...1 noam chomsky (gramatica generativa, automata de pila, etc.)
1...1 noam chomsky (gramatica generativa, automata de pila, etc.)Jacqui Venegas
 
ANALIZADOR SINTACTICO: INTRODUCION, CONCEPTOS, CARACTERISTICAS
ANALIZADOR SINTACTICO: INTRODUCION, CONCEPTOS, CARACTERISTICAS ANALIZADOR SINTACTICO: INTRODUCION, CONCEPTOS, CARACTERISTICAS
ANALIZADOR SINTACTICO: INTRODUCION, CONCEPTOS, CARACTERISTICAS Infomania pro
 
Tema 11 expresiones regulares en java por gio
Tema 11   expresiones regulares en java por gioTema 11   expresiones regulares en java por gio
Tema 11 expresiones regulares en java por gioRobert Wolf
 
Compiladores, interpretadores y lenguajes de bajo, medio y alto nivel
Compiladores, interpretadores y lenguajes de bajo, medio y alto nivelCompiladores, interpretadores y lenguajes de bajo, medio y alto nivel
Compiladores, interpretadores y lenguajes de bajo, medio y alto nivelEstefhany1
 
Analizador LÉxico
Analizador LÉxicoAnalizador LÉxico
Analizador LÉxicoFARIDROJAS
 
Teoria de automatas y lenguajes formales
Teoria de automatas y lenguajes formalesTeoria de automatas y lenguajes formales
Teoria de automatas y lenguajes formalesUniversidad del Valle
 
Introducción a Compiladores
Introducción a  CompiladoresIntroducción a  Compiladores
Introducción a CompiladoresLeopoldo Capa
 
Presentacion 2 - Maquinas de Estado Finito
Presentacion 2 - Maquinas de Estado FinitoPresentacion 2 - Maquinas de Estado Finito
Presentacion 2 - Maquinas de Estado Finitojunito86
 
Gramatica libre de contexto
Gramatica libre de contextoGramatica libre de contexto
Gramatica libre de contextoDaniel Molina
 
Análisis léxico y análisis sintáctico
Análisis léxico y análisis sintácticoAnálisis léxico y análisis sintáctico
Análisis léxico y análisis sintácticoangiepao1717
 

Destacado (20)

Tarea de ensamblador
Tarea de ensambladorTarea de ensamblador
Tarea de ensamblador
 
Simplificación de gramáticas independientes de contexto
Simplificación de gramáticas independientes de contextoSimplificación de gramáticas independientes de contexto
Simplificación de gramáticas independientes de contexto
 
1...1 noam chomsky (gramatica generativa, automata de pila, etc.)
1...1 noam chomsky (gramatica generativa, automata de pila, etc.)1...1 noam chomsky (gramatica generativa, automata de pila, etc.)
1...1 noam chomsky (gramatica generativa, automata de pila, etc.)
 
ANALIZADOR SINTACTICO: INTRODUCION, CONCEPTOS, CARACTERISTICAS
ANALIZADOR SINTACTICO: INTRODUCION, CONCEPTOS, CARACTERISTICAS ANALIZADOR SINTACTICO: INTRODUCION, CONCEPTOS, CARACTERISTICAS
ANALIZADOR SINTACTICO: INTRODUCION, CONCEPTOS, CARACTERISTICAS
 
Tema 11 expresiones regulares en java por gio
Tema 11   expresiones regulares en java por gioTema 11   expresiones regulares en java por gio
Tema 11 expresiones regulares en java por gio
 
Analizador léxico
Analizador léxicoAnalizador léxico
Analizador léxico
 
Claselexico
ClaselexicoClaselexico
Claselexico
 
Compiladores, interpretadores y lenguajes de bajo, medio y alto nivel
Compiladores, interpretadores y lenguajes de bajo, medio y alto nivelCompiladores, interpretadores y lenguajes de bajo, medio y alto nivel
Compiladores, interpretadores y lenguajes de bajo, medio y alto nivel
 
Analizador LÉxico
Analizador LÉxicoAnalizador LÉxico
Analizador LÉxico
 
Teoria de automatas y lenguajes formales
Teoria de automatas y lenguajes formalesTeoria de automatas y lenguajes formales
Teoria de automatas y lenguajes formales
 
Compiladores, Analisis Lexico, Tabla de Transiciones
Compiladores, Analisis Lexico, Tabla de TransicionesCompiladores, Analisis Lexico, Tabla de Transiciones
Compiladores, Analisis Lexico, Tabla de Transiciones
 
Analisis sintactico
Analisis sintacticoAnalisis sintactico
Analisis sintactico
 
Introducción a Compiladores
Introducción a  CompiladoresIntroducción a  Compiladores
Introducción a Compiladores
 
Presentacion 2 - Maquinas de Estado Finito
Presentacion 2 - Maquinas de Estado FinitoPresentacion 2 - Maquinas de Estado Finito
Presentacion 2 - Maquinas de Estado Finito
 
Gramatica libre de contexto
Gramatica libre de contextoGramatica libre de contexto
Gramatica libre de contexto
 
Componente sintáctico
Componente sintácticoComponente sintáctico
Componente sintáctico
 
Analisis sintactico
Analisis sintacticoAnalisis sintactico
Analisis sintactico
 
Máquinas de Estado
Máquinas de EstadoMáquinas de Estado
Máquinas de Estado
 
Compiladores, Analisis Lexico Conceptos
Compiladores, Analisis Lexico ConceptosCompiladores, Analisis Lexico Conceptos
Compiladores, Analisis Lexico Conceptos
 
Análisis léxico y análisis sintáctico
Análisis léxico y análisis sintácticoAnálisis léxico y análisis sintáctico
Análisis léxico y análisis sintáctico
 

Similar a Historia Compiladores

C:\documents and settings\clientea\mis documentos\compiladores
C:\documents and settings\clientea\mis documentos\compiladoresC:\documents and settings\clientea\mis documentos\compiladores
C:\documents and settings\clientea\mis documentos\compiladoresNancyandRegina317
 
Compilador Funcionamiento
Compilador FuncionamientoCompilador Funcionamiento
Compilador FuncionamientoKriz Kozlov
 
Grupo 1 proceso de lenguajes i
Grupo 1 proceso de lenguajes iGrupo 1 proceso de lenguajes i
Grupo 1 proceso de lenguajes iRossana Sosa
 
Actividad 3
Actividad 3Actividad 3
Actividad 3maryr_
 
Compiladores unidad1
Compiladores unidad1Compiladores unidad1
Compiladores unidad1X3025990
 
C:\fakepath\compiladores
C:\fakepath\compiladoresC:\fakepath\compiladores
C:\fakepath\compiladorespaulina8
 
Traductores de lenguajes de programación
Traductores de lenguajes de programaciónTraductores de lenguajes de programación
Traductores de lenguajes de programaciónDaniela Brignolo
 
C:\fakepath\el software libre
C:\fakepath\el software libreC:\fakepath\el software libre
C:\fakepath\el software libreDanielita Lopez
 
C:\fakepath\el software libre
C:\fakepath\el software libreC:\fakepath\el software libre
C:\fakepath\el software libreDanielita Lopez
 
C:\fakepath\el software libre
C:\fakepath\el software libreC:\fakepath\el software libre
C:\fakepath\el software libreDLACGP
 
C:\fakepath\el software libre
C:\fakepath\el software libreC:\fakepath\el software libre
C:\fakepath\el software libreDanielita Lopez
 
C:\fakepath\compilador
C:\fakepath\compiladorC:\fakepath\compilador
C:\fakepath\compiladorDLACGP
 
C:\fakepath\el software libre
C:\fakepath\el software libreC:\fakepath\el software libre
C:\fakepath\el software libreDanielita Lopez
 
Compiladores diapositivas
Compiladores diapositivasCompiladores diapositivas
Compiladores diapositivasjonathangrief
 

Similar a Historia Compiladores (20)

H:\compiladores
H:\compiladoresH:\compiladores
H:\compiladores
 
C:\documents and settings\clientea\mis documentos\compiladores
C:\documents and settings\clientea\mis documentos\compiladoresC:\documents and settings\clientea\mis documentos\compiladores
C:\documents and settings\clientea\mis documentos\compiladores
 
Compilador Funcionamiento
Compilador FuncionamientoCompilador Funcionamiento
Compilador Funcionamiento
 
Compiladores
CompiladoresCompiladores
Compiladores
 
Grupo 1 proceso de lenguajes i
Grupo 1 proceso de lenguajes iGrupo 1 proceso de lenguajes i
Grupo 1 proceso de lenguajes i
 
Actividad 3
Actividad 3Actividad 3
Actividad 3
 
Compiladores unidad1
Compiladores unidad1Compiladores unidad1
Compiladores unidad1
 
C:\fakepath\compiladores
C:\fakepath\compiladoresC:\fakepath\compiladores
C:\fakepath\compiladores
 
Resumencap1 carmen vargas_jeremycamacho
Resumencap1 carmen vargas_jeremycamachoResumencap1 carmen vargas_jeremycamacho
Resumencap1 carmen vargas_jeremycamacho
 
Compiladores iswi (parte 2)
Compiladores iswi (parte 2)Compiladores iswi (parte 2)
Compiladores iswi (parte 2)
 
Traductores de lenguajes de programación
Traductores de lenguajes de programaciónTraductores de lenguajes de programación
Traductores de lenguajes de programación
 
C:\fakepath\el software libre
C:\fakepath\el software libreC:\fakepath\el software libre
C:\fakepath\el software libre
 
C:\fakepath\el software libre
C:\fakepath\el software libreC:\fakepath\el software libre
C:\fakepath\el software libre
 
C:\fakepath\el software libre
C:\fakepath\el software libreC:\fakepath\el software libre
C:\fakepath\el software libre
 
C:\fakepath\el software libre
C:\fakepath\el software libreC:\fakepath\el software libre
C:\fakepath\el software libre
 
C:\fakepath\compilador
C:\fakepath\compiladorC:\fakepath\compilador
C:\fakepath\compilador
 
C:\fakepath\el software libre
C:\fakepath\el software libreC:\fakepath\el software libre
C:\fakepath\el software libre
 
Introduccion
IntroduccionIntroduccion
Introduccion
 
Compiladores diapositivas
Compiladores diapositivasCompiladores diapositivas
Compiladores diapositivas
 
Algoritmos1
Algoritmos1Algoritmos1
Algoritmos1
 

Último

programa dia de las madres 10 de mayo para evento
programa dia de las madres 10 de mayo  para eventoprograma dia de las madres 10 de mayo  para evento
programa dia de las madres 10 de mayo para eventoDiegoMtsS
 
Manual - ABAS II completo 263 hojas .pdf
Manual - ABAS II completo 263 hojas .pdfManual - ABAS II completo 263 hojas .pdf
Manual - ABAS II completo 263 hojas .pdfMaryRotonda1
 
Informatica Generalidades - Conceptos Básicos
Informatica Generalidades - Conceptos BásicosInformatica Generalidades - Conceptos Básicos
Informatica Generalidades - Conceptos BásicosCesarFernandez937857
 
Introducción:Los objetivos de Desarrollo Sostenible
Introducción:Los objetivos de Desarrollo SostenibleIntroducción:Los objetivos de Desarrollo Sostenible
Introducción:Los objetivos de Desarrollo SostenibleJonathanCovena1
 
la unidad de s sesion edussssssssssssssscacio fisca
la unidad de s sesion edussssssssssssssscacio fiscala unidad de s sesion edussssssssssssssscacio fisca
la unidad de s sesion edussssssssssssssscacio fiscaeliseo91
 
Historia y técnica del collage en el arte
Historia y técnica del collage en el arteHistoria y técnica del collage en el arte
Historia y técnica del collage en el arteRaquel Martín Contreras
 
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptx
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptxOLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptx
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptxjosetrinidadchavez
 
SINTAXIS DE LA ORACIÓN SIMPLE 2023-2024.pptx
SINTAXIS DE LA ORACIÓN SIMPLE 2023-2024.pptxSINTAXIS DE LA ORACIÓN SIMPLE 2023-2024.pptx
SINTAXIS DE LA ORACIÓN SIMPLE 2023-2024.pptxlclcarmen
 
Identificación de componentes Hardware del PC
Identificación de componentes Hardware del PCIdentificación de componentes Hardware del PC
Identificación de componentes Hardware del PCCesarFernandez937857
 
Herramientas de Inteligencia Artificial.pdf
Herramientas de Inteligencia Artificial.pdfHerramientas de Inteligencia Artificial.pdf
Herramientas de Inteligencia Artificial.pdfMARIAPAULAMAHECHAMOR
 
DECÁGOLO DEL GENERAL ELOY ALFARO DELGADO
DECÁGOLO DEL GENERAL ELOY ALFARO DELGADODECÁGOLO DEL GENERAL ELOY ALFARO DELGADO
DECÁGOLO DEL GENERAL ELOY ALFARO DELGADOJosé Luis Palma
 
RAIZ CUADRADA Y CUBICA PARA NIÑOS DE PRIMARIA
RAIZ CUADRADA Y CUBICA PARA NIÑOS DE PRIMARIARAIZ CUADRADA Y CUBICA PARA NIÑOS DE PRIMARIA
RAIZ CUADRADA Y CUBICA PARA NIÑOS DE PRIMARIACarlos Campaña Montenegro
 
texto argumentativo, ejemplos y ejercicios prácticos
texto argumentativo, ejemplos y ejercicios prácticostexto argumentativo, ejemplos y ejercicios prácticos
texto argumentativo, ejemplos y ejercicios prácticosisabeltrejoros
 
codigos HTML para blogs y paginas web Karina
codigos HTML para blogs y paginas web Karinacodigos HTML para blogs y paginas web Karina
codigos HTML para blogs y paginas web Karinavergarakarina022
 
Factores ecosistemas: interacciones, energia y dinamica
Factores ecosistemas: interacciones, energia y dinamicaFactores ecosistemas: interacciones, energia y dinamica
Factores ecosistemas: interacciones, energia y dinamicaFlor Idalia Espinoza Ortega
 
Unidad II Doctrina de la Iglesia 1 parte
Unidad II Doctrina de la Iglesia 1 parteUnidad II Doctrina de la Iglesia 1 parte
Unidad II Doctrina de la Iglesia 1 parteJuan Hernandez
 
CALENDARIZACION DE MAYO / RESPONSABILIDAD
CALENDARIZACION DE MAYO / RESPONSABILIDADCALENDARIZACION DE MAYO / RESPONSABILIDAD
CALENDARIZACION DE MAYO / RESPONSABILIDADauxsoporte
 
Heinsohn Privacidad y Ciberseguridad para el sector educativo
Heinsohn Privacidad y Ciberseguridad para el sector educativoHeinsohn Privacidad y Ciberseguridad para el sector educativo
Heinsohn Privacidad y Ciberseguridad para el sector educativoFundación YOD YOD
 
30-de-abril-plebiscito-1902_240420_104511.pdf
30-de-abril-plebiscito-1902_240420_104511.pdf30-de-abril-plebiscito-1902_240420_104511.pdf
30-de-abril-plebiscito-1902_240420_104511.pdfgimenanahuel
 

Último (20)

programa dia de las madres 10 de mayo para evento
programa dia de las madres 10 de mayo  para eventoprograma dia de las madres 10 de mayo  para evento
programa dia de las madres 10 de mayo para evento
 
Manual - ABAS II completo 263 hojas .pdf
Manual - ABAS II completo 263 hojas .pdfManual - ABAS II completo 263 hojas .pdf
Manual - ABAS II completo 263 hojas .pdf
 
Informatica Generalidades - Conceptos Básicos
Informatica Generalidades - Conceptos BásicosInformatica Generalidades - Conceptos Básicos
Informatica Generalidades - Conceptos Básicos
 
Introducción:Los objetivos de Desarrollo Sostenible
Introducción:Los objetivos de Desarrollo SostenibleIntroducción:Los objetivos de Desarrollo Sostenible
Introducción:Los objetivos de Desarrollo Sostenible
 
la unidad de s sesion edussssssssssssssscacio fisca
la unidad de s sesion edussssssssssssssscacio fiscala unidad de s sesion edussssssssssssssscacio fisca
la unidad de s sesion edussssssssssssssscacio fisca
 
Historia y técnica del collage en el arte
Historia y técnica del collage en el arteHistoria y técnica del collage en el arte
Historia y técnica del collage en el arte
 
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptx
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptxOLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptx
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptx
 
SINTAXIS DE LA ORACIÓN SIMPLE 2023-2024.pptx
SINTAXIS DE LA ORACIÓN SIMPLE 2023-2024.pptxSINTAXIS DE LA ORACIÓN SIMPLE 2023-2024.pptx
SINTAXIS DE LA ORACIÓN SIMPLE 2023-2024.pptx
 
Identificación de componentes Hardware del PC
Identificación de componentes Hardware del PCIdentificación de componentes Hardware del PC
Identificación de componentes Hardware del PC
 
Herramientas de Inteligencia Artificial.pdf
Herramientas de Inteligencia Artificial.pdfHerramientas de Inteligencia Artificial.pdf
Herramientas de Inteligencia Artificial.pdf
 
DECÁGOLO DEL GENERAL ELOY ALFARO DELGADO
DECÁGOLO DEL GENERAL ELOY ALFARO DELGADODECÁGOLO DEL GENERAL ELOY ALFARO DELGADO
DECÁGOLO DEL GENERAL ELOY ALFARO DELGADO
 
RAIZ CUADRADA Y CUBICA PARA NIÑOS DE PRIMARIA
RAIZ CUADRADA Y CUBICA PARA NIÑOS DE PRIMARIARAIZ CUADRADA Y CUBICA PARA NIÑOS DE PRIMARIA
RAIZ CUADRADA Y CUBICA PARA NIÑOS DE PRIMARIA
 
Unidad 4 | Teorías de las Comunicación | MCDI
Unidad 4 | Teorías de las Comunicación | MCDIUnidad 4 | Teorías de las Comunicación | MCDI
Unidad 4 | Teorías de las Comunicación | MCDI
 
texto argumentativo, ejemplos y ejercicios prácticos
texto argumentativo, ejemplos y ejercicios prácticostexto argumentativo, ejemplos y ejercicios prácticos
texto argumentativo, ejemplos y ejercicios prácticos
 
codigos HTML para blogs y paginas web Karina
codigos HTML para blogs y paginas web Karinacodigos HTML para blogs y paginas web Karina
codigos HTML para blogs y paginas web Karina
 
Factores ecosistemas: interacciones, energia y dinamica
Factores ecosistemas: interacciones, energia y dinamicaFactores ecosistemas: interacciones, energia y dinamica
Factores ecosistemas: interacciones, energia y dinamica
 
Unidad II Doctrina de la Iglesia 1 parte
Unidad II Doctrina de la Iglesia 1 parteUnidad II Doctrina de la Iglesia 1 parte
Unidad II Doctrina de la Iglesia 1 parte
 
CALENDARIZACION DE MAYO / RESPONSABILIDAD
CALENDARIZACION DE MAYO / RESPONSABILIDADCALENDARIZACION DE MAYO / RESPONSABILIDAD
CALENDARIZACION DE MAYO / RESPONSABILIDAD
 
Heinsohn Privacidad y Ciberseguridad para el sector educativo
Heinsohn Privacidad y Ciberseguridad para el sector educativoHeinsohn Privacidad y Ciberseguridad para el sector educativo
Heinsohn Privacidad y Ciberseguridad para el sector educativo
 
30-de-abril-plebiscito-1902_240420_104511.pdf
30-de-abril-plebiscito-1902_240420_104511.pdf30-de-abril-plebiscito-1902_240420_104511.pdf
30-de-abril-plebiscito-1902_240420_104511.pdf
 

Historia Compiladores

  • 1. INTRODUCCIÓN Para empezar el estudio de Compiladores conozcamos algo a cerca de su historia. • 1958, Strong y otros proponen una solución al problema de que un compilador fuera portable, y esta era dividir al compilador en dos fases “front end” (analiza el programa fuente) y “back end” (genera código objeto para la máquina objeto). • El puente de unión era un lenguaje intermedio denominado UNCOL (no funcionó) • 1959, Rabin y Scott proponen el empleo de AFD y AFN para el reconocimiento lexicográfico de los lenguajes • Aparece BNF (Backus-1960, Naur-1963, Knuth-1964) como una guía para el desarrollo del análisis sintáctico • 1959, Sheridan describe un método de parsing de FORTRAN para introducir paréntesis en una expresión • 1975, aparece LEX generador automático de analizadores léxicos a partir de expresiones regulares bajo UNIX • A mitad de los 70’s Johnson crea YACC para UNIX (generador de analizadores sintácticos) • El último lenguaje de programación de amplia aceptación es JAVA (es interpretado) Para escribir un compilador necesitamos: - Algoritmos - Lenguajes de Programación - Lenguajes Formales - Arquitectura del Computador - Ingeniería de Software Programas que el compilador necesita para obtener un programa ejecutable • Preprocesador • Ligador • Cargador 1 • Depurador • Ensamblador Elaborado por: Beatriz Pasaca| Noveno “A”
  • 2. Conceptos Básicos que hay tener bien claro: Traductor. Cualquier programa que toma como entrada un texto escrito en un lenguaje llamado fuente y da como salida un programa equivalente en otro lenguaje, el lenguaje objeto. Si el lenguaje fuente de un lenguaje de programación de alto nivel y el objeto un lenguaje de bajo nivel (ensamblador o código de máquina), al traductor se le denomina compilador. Ensamblador. Es un programa traductor cuyo lenguaje fuente es el lenguaje ensamblador. Intérprete. Es un programa que no genera un programa equivalente, sino que toma una sentencia del programa fuente en un lenguaje de alto nivel y la traduce al código equivalente y al mismo tiempo lo ejecuta. En un principio debido a la escasez de memoria se utilizaban más los intérpretes, ahora se usan más los compiladores (a excepción de JAVA) Conceptos básicos Ventajas de compilar vs a interpretar o Se compila una vez, se ejecuta n veces o En ciclos, la compilación genera código equivalente, interpretándolo se traduce tantas veces una línea como veces se repite el ciclo o El compilador tiene un visión global del programa Ventajas del intérprete vs el compilador o Un intérprete necesita menos memoria que un compilador o Permiten una mayor interactividad con el código en tiempo de desarrollo Más Diferencias entre Traductor y un Compilador Traductor: - Análisis Léxico Compilador: - Análisis Léxico - Análisis Sintáctico - Análisis Sintáctico - Análisis Semántico - Análisis Semántico - Generación de código intermedio - Código maquina - Fase de optimizacion Equivalencias 2 Gcódigo máquina Elaborado por: Beatriz Pasaca| Noveno “A”
  • 3. Un compilador es un programa informático que traduce un programa escrito en un lenguaje de programación fuente a otro lenguaje de programación, generando un programa equivalente que la máquina será capaz de interpretar. Usualmente el segundo lenguaje es código máquina, pero también puede ser simplemente texto. Este proceso permite generar una lista de los posibles errores que tenga el programa fuente. • Un compilador es un programa que lee un programa escrito en un lenguaje, el lenguaje fuente, y lo traduce a un programa equivalente en otro lenguaje, el lenguaje objeto. Como parte importante de éste proceso de traducción, el compilador informa a su usuario de la presencia de errores en el programa fuente. • Compilador también define como aquel traductor que tiene como entrada una sentencia en lenguaje formal y como salida tiene un fichero ejecutable, es decir, realiza una traducción de un código de alto nivel a código máquina (también se entiende por compilador aquel programa que proporciona un fichero objeto en lugar del ejecutable final). Funcionamiento del compilador Hay miles de lenguajes fuente, desde los lenguajes de programación tradicionales, hasta los lenguajes especializados que han surgido virtualmente en todas las áreas de aplicación de la información. 3 Elaborado por: Beatriz Pasaca| Noveno “A”
  • 4. Lenguajes objeto son igualmente variados; un lenguaje objeto puede ser otro lenguaje de programación o el lenguaje de máquina de cualquier computador entre un microprocesador y un supercomputador. Estructura de un compilador 4 Estructura de un compilador. Elaborado por: Beatriz Pasaca| Noveno “A”
  • 5. -Análisis Léxico, Rastreador o Scanner: Descomposición programa fuente en componentes léxicos. En esta etapa se lee el archivo de texto que contiene el código fuente y las cadenas se van agrupando en componentes léxicos o tokens. Estos componentes léxicos son los operadores, identificadores y palabras reservadas del lenguaje. Por lo tanto, transforma en flujo de caracteres en un flujo de objetos tokens, ignorando los comentarios y los espacios en blanco y tabulaciones. Esta primera fase es capaz de detectar errores de tipo léxico. Por ejemplo, si en lugar de poner if pusiéramos ifi, el analizador léxico no usaría el token predefinido IF para esa secuencia de caracteres, sino que entendería que es un identificador cualquiera (como pudiera ser el nombre de una variable). - Análisis Sintáctico o Parser: Agrupa componentes léxicos en frases gramaticales. Esta etapa se encarga de verificar que el documento tiene una disposición sintáctica correcta, agrupando el código en frases gramaticales con sentido. En otras palabras, que el flujo de tokens tenga el orden correcto. Esta etapa detecta errores sintácticos. Siguiendo el ejemplo anterior, si hubiésemos puesto ifi en lugar de if, esta etapa detectaría que la estructura de un bloque if no es así, detectando así el error en el código fuente. A la siguiente fase le manda árboles de sintaxis abstracta. Por ejemplo, un árbol cuyo nodo raíz es PROGRAMA, que se compone de una lista de clases. Cada una de estas serian arboles que describen los distintos atributos y métodos de la misma, y así sucesivamente. Esta fase no puede detectar los errores. - Análisis Semántico: Comprobación de validez semántica. Esta es una de las fases más complejas del proceso de compilación. Tiene que realizar varias tareas: la resolución de nombres, el tipo de las expresiones y la evaluación L/R. La resolución de nombres consiste en comprobar que cada identificador que usemos (ya sea una variable local, parámetro, atributo o 5 método) ha sido previamente declarado y además, si es visible desde el ámbito actual. Elaborado por: Beatriz Pasaca| Noveno “A”
  • 6. En cuanto a los tipos, hay que comprobar que en las expresiones donde intervengan 2 identificadores (asignación, suma, producto, concatenación, etc.) comprobar que ambos identificadores aceptan dicha operación, que son de tipos compatibles. La evaluación L/R consiste en que para cada asignación, cada componente puede aparecer o no en esa posición. Por ejemplo, el resultado de una serie de operaciones no puede aparecer a la izquierda, solo a la derecha, ya que no se puede asignar un valor al resultado de una serie de operaciones. Tabla de símbolos: Una función esencial de un compilador es registrar los identificadores de usuario (nombres de variables, de funciones, de tipos, etc.) utilizados en el programa fuente y reunir información sobre los distintos atributos de cada identificador. Estos atributos pueden proporcionar información sobre la memoria asignada a un identificador, la dirección de memoria en que se almacenará en tiempo de ejecución, su tipo, su ámbito (la parte del programa donde es visible), etc. Pues bien, la tabla de símbolos es una estructura de datos que posee información sobre los identificadores definidos por el usuario, ya sean constantes, variables, tipos u otros. Dado que puede contener información de diversa índole, debe hacerse de forma que su estructura no sea uniforme, esto es, no se guarda la misma información sobre una variable del programa que sobre un tipo definido por el usuario. Hace funciones de diccionario de datos y su estructura puede ser una tabla hash, un árbol binario de búsqueda, etc., con tal de que las operaciones de acceso sean lo bastante eficientes. Esquema por etapas definitivo del traductor Tanto la etapa de análisis como la de síntesis acceden a esta estructura, por lo que se halla 6 muy acoplada al resto de fases del compilador. Por ello conviene dotar a la tabla de símbolos de una interfaz lo suficientemente genérica como para permitir el cambio de las estructuras Elaborado por: Beatriz Pasaca| Noveno “A”
  • 7. internas de almacenamiento sin que estas fases deban ser retocadas. Esto es así porque suele ser usual hacer un primer prototipo de un compilador con una tabla de símbolos fácil de construir, y cuando el compilador ya ha sido finalizado, entonces se procede a sustituir la tabla de símbolos por otra más eficiente en función de las necesidades que hayan ido surgiendo. El esquema general definitivo de un traductor se detalla en la figura anterior. TIPOS DE COMPILADORES Existen varias categorías de compiladores entre los más conocidos tenemos: • Compiladores cruzados: generan código para un sistema distinto del que están funcionando. • Compiladores optimizadores: realizan cambios en el código para mejorar su eficiencia, pero manteniendo la funcionalidad del programa original. • Compiladores de una sola pasada: generan el código máquina a partir de una única lectura del código fuente. • Compiladores de varias pasadas: necesitan leer el código fuente varias veces antes de poder producir el código máquina. • Compiladores JIT (Just In Time): forman parte de un intérprete (traductor que realiza la operación de compilación paso a paso), y compilan partes del código según se necesitan. Partes de un compilador Normalmente los compiladores están divididos en dos partes: Front End: es la parte que analiza el código fuente, comprueba su validez, genera el árbol de derivación y rellena los valores de la tabla de símbolos. Esta parte suele ser independiente de la plataforma o sistema para el cual se vaya a compilar. Back End: es la parte que genera el código máquina, específico de una plataforma, a partir de los resultados de la fase de análisis, realizada por el Front End. Esta división permite que el mismo Back End se utilice para generar el código máquina de 7 varios lenguajes de programación distintos y que el mismo Front End que sirve para analizar el Elaborado por: Beatriz Pasaca| Noveno “A”
  • 8. código fuente de un lenguaje de programación concreto sirva para generar código máquina en varias plataformas distintas. El código que genera el Back End normalmente no se puede ejecutar directamente, sino que necesita ser enlazado por un programa enlazador (linker). Arquitectura Real De Compiladores E Intérpretes La arquitectura real de compiladores e intérpretes es la siguiente: 8 Elaborado por: Beatriz Pasaca| Noveno “A”
  • 9. ANALIZADOR LÉXICO Definición: El analizador léxico (scanner), lee un texto fuente y lo transforma en una secuencia ordenada de elementos léxicamente válidos. Un caracter o conjunto de estos que constituya un componente léxico se llama lexema (token). Como componentes léxicos consideramos: palabras reservadas, separadores, operadores, identificadores, constantes y signos de puntuación. Funciones del analizador léxico La fase de análisis léxico se halla bajo el control del análisis sintáctico. Normalmente se implementa como una función de éste componentes léxicos que utiliza el analizador sintáctico para hacer el análisis. Esta interacción suele aplicarse convirtiendo al analizador léxico en una subrutina o corrutina del analizador sintáctico. Recibida la orden “Dame el siguiente componente léxico”del analizador sintáctico, el léxico lee los caracteres de entrada hasta que pueda identificar el siguiente componente léxico, el cual devuelve al sintáctico según el formato convenido (figura anterior). Analizador léxico lee la secuencia de caracteres del programa fuente, carácter a carácter, y los agrupa para formar unidades con significado propio, los componentes léxicos (tokens en ingles). Estos componentes léxicos representan: • Palabras reservadas: if, while, do. • Identificadores: asociados a variables, nombres de funciones, tipos definidos por el usuario, 9 etiquetas. Por ejemplo: posición, velocidad, tiempo. • Operadores: = * + - / == > < & ! = . Elaborado por: Beatriz Pasaca| Noveno “A”
  • 10. Símbolos especiales: ; ( ) [ ] f g. • Constantes numéricas: literales que representan valores enteros, en coma flotante, etc., 982, 0xF678, -83.2E+2,… • Constantes de caracteres: literales que representan cadenas concretas de caracteres, “hola mundo",... El analizador léxico opera bajo petición del analizador sintáctico devolviendo un componente léxico conforme el analizador sintáctico lo va necesitando para avanzar en la gramática. Los componentes léxicos son los símbolos terminales de la gramática. Otras funciones: • Manejo del fichero de entrada del programa fuente: abrirlo, leer sus caracteres, cerrarlo y gestionar posibles errores de lectura. • Eliminar comentarios, espacios en blanco, tabuladores y saltos de línea (caracteres no validos para formar un token). • Inclusión de ficheros: # include ... • La expansión de macros y funciones inline: # define ... • Contabilizar el número de líneas y columnas para emitir mensajes de error. • Reconocimiento y ejecución de las directivas de compilación (por ejemplo, para depurar u optimizar el código fuente). • Rechazar un carácter o conjunto de estos que no concuerden con patrones especificados • Entendamos como patrón una expresión regular que se define en el lenguaje. • Ignorar comentarios, espacios en blanco y tabuladores. • Gestionar errores, contando los saltos de línea y asociando los mensajes de error con el número de la línea del archivo fuente donde se producen. • Guardar tokens junto con su atributo en una tabla de símbolos. Este atributo es información adicional relevante, habitualmente con relación a los identificadores. 10 Componentes Toquen, Patrones, Lexemas Token: “nombre “que se da a cada componente léxico. Elaborado por: Beatriz Pasaca| Noveno “A”
  • 11. Patrón: es una regla que genera la secuencia de caracteres que puede representar a un determinado componente léxico (una expresión regular). Lexema: cadena de caracteres que concuerda con un patrón que describe un componente léxico. Un componente léxico puede tener uno o infinitos lexemas. Además o Un token se corresponde con un patrón o Un token se puede corresponder con muchos lexemas o Tokens más habituales: o Palabras reservadas o Identificadores o Operadores o Constantes o Símbolos de puntuación: ; , . : o Símbolos especiales: ( ) [ ] o Pero, a la vez que el propio token, el scanner puede (debe) devolver más información o Si es un token CONSTANTE, su valor o Si es un identificador, el string correspondiente o Si es un símbolo de puntuación, cuál o Esta información, se devuelve mediante “atributos”. Pero aún puede hacer algo más: o Puede detectar algunos (pocos) errores léxicos No hay concordancia con ningún patrón • Puede llevar a cabo algunas recuperaciones de errores o Filtrado de caracteres “extraños” o Completar algún patrón o Reemplazar algún carácter Los componentes léxicos se suelen definir como un tipo enumerado. Se codifican como enteros. También se suele almacenar la cadena de caracteres que se acaba de reconocer (el lexema), que se usara posteriormente para el análisis semántico. 11 Elaborado por: Beatriz Pasaca| Noveno “A”
  • 12. Es importante conocer el lexema (para construir la tabla de símbolos). Los componentes léxicos se representan mediante una estructura registro con tipo de token y lexema. Especificación de los componentes léxicos: expresiones regulares. Los componentes léxicos se especifican haciendo uso de expresiones regulares. Además de las tres operaciones básicas: concatenación, repetición (*) y alternativas (j) vamos a usar los siguientes meta símbolos: Una o más repeticiones + • r+ indica una o más repeticiones de r • (0j1)+ = (0j1) (0j1)* Cualquier carácter. • .*b.* indica cualquier cadena que contiene una letra b Un rango de caracteres [ ] (clase) • [a-z] indica cualquier carácter entre la a y z minúsculas • [a-zA-Z] indica cualquier letra del abecedario minúscula o mayúscula • [0-9] indica cualquier digito de 0 a 9 • [abc] indica ajbj Cualquier carácter excepto un conjunto dado • ~ (ajb) indica cualquier carácter que no sea una a o b Opcionalidad ? 12 r? indica que la expresión r puede aparecer o no. En el caso de que aparezca solo lo haría una vez. Elaborado por: Beatriz Pasaca| Noveno “A”
  • 13. Aspectos prácticos en la implementación de un analizador léxico Principio de máxima longitud Se da prioridad al componente léxico de máxima longitud. Por ejemplo: <> se interpreta como el operador “distinto de", en vez de “menor que" y “mayor que". Palabras reservadas versus identificadores Un lenguaje de programación puede tener del orden de 50 palabras reservadas. Para evitar tener un AFD demasiado grande las palabras reservadas se reconocen como identificadores (una palabra reservada también es una letra seguida de mas letras) y se comprueba antes de decidir el tipo de token si se trata de una palabra reservada o de un identificador consultando una tabla previamente inicializada con las palabras reservadas. Este método es recomendable cuando el número de palabras reservadas es grande. Entrada de los identificadores en la Tabla de Símbolos En lenguajes sencillos con solo variables globales y declaraciones, es normal implementar el scanner para que introduzca los identificadores en la Tabla de Símbolos conforme los va reconociendo, si es que no han sido ya introducidos. Después, el analizador sintáctico se encarga de introducir información adicional sobre su tipo, etc. conforme la va obteniendo durante el análisis sintáctico. Si se trata de un lenguaje estructurado, el scanner no introduce los identificadores en la Tabla de Símbolos, porque en este tipo de lenguajes, los identificadores pueden tener diferentes significados según su contexto (como una variable, como una función, como un campo de una estructura). Es el análisis sintáctico, cuando ya ha recogido información sobre su ámbito, cuando introduce los identificadores en la Tabla de Símbolos. 13 Gestión del búfer de entrada Elaborado por: Beatriz Pasaca| Noveno “A”
  • 14. El proceso de lectura de los caracteres de la entrada y formar los componentes léxicos es lo más costoso en tiempo en el proceso de traducción. Es importante implementarlo eficientemente. Se utiliza un búfer dividido en dos mitades de tamaño N caracteres, donde N es un bloque de disco (1024, 4096). Se leen N caracteres de la entrada en cada mitad del búfer con una única orden de lectura. Se mantienen dos apuntadores. Uno marca el inicio del lexema y el otro el carácter actual que se mueve hasta encontrar una subcadena que corresponde con un patrón. Una vez reconocido un componente léxico ambos apuntadores se colocan en la misma posición y justo detrás del lexema reconocido. Tratamiento de errores léxicos Los errores léxicos se detectan cuando el analizador léxico intenta reconocer componentes léxicos y la cadena de caracteres de la entrada no encaja con ningún patrón. Son situaciones en las que usa un carácter invalido (@, $,",>,...), que no pertenece al vocabulario del lenguaje de programación, al escribir mal un identificador, palabra reservada u operador. Errores léxicos típicos son: • Nombre ilegales de identificadores: un nombre contiene caracteres inválidos. • Números incorrectos: un numero contiene caracteres inválidos o no está formado correctamente, por ejemplo 3,14 en vez de 3.14 o 0.3.14. • Errores de ortografía en palabras reservadas: caracteres omitidos, adicionales o cambiados de sitio, por ejemplo la palabra hwile en vez de while. • Fin de archivo: se detecta un fin de archivo a la mitad de un componente léxico. En general, la recuperación de errores léxicos es sencilla y siempre se traduce en la generación de un error de sintaxis que sería detectado más tarde por el analizador sintáctico cuando el analizador léxico devuelve un componente léxico que el analizador sintáctico no espera en esa posición. 14 Los métodos de recuperación de errores léxicos se basan bien en saltarse caracteres en la entrada hasta que un patrón se ha podido reconocer. Elaborado por: Beatriz Pasaca| Noveno “A”
  • 15. Una buena estrategia para la recuperación de errores léxicos: Si en el momento de detectar el error ya hemos pasado por algún estado final ejecutamos la acción correspondiente al último estado final visitado con el lexema formado hasta que salimos de él; el resto de caracteres leídos se devuelven al flujo de entrada y se vuelve al estado inicial. Si no hemos pasado por ningún estado final, advertimos que el carácter encontrado no se esperaba, lo eliminamos y proseguimos con el análisis. Por ejemplo, ante la entrada 73:a: • Devolvemos el componente léxico entero con lexema 73; • Devolvemos al búfer de entrada los caracteres :a y • Volvemos al estado inicial. En la siguiente llamada al analizador léxico se producirá un nuevo error, en este caso descartamos el carácter leído (el punto) y seguimos con el análisis. En la siguiente llamada detectamos el identificador a. Si se sabe que el siguiente componente léxico es una palabra reservada (en la gramática esperamos una palabra reservada) es posible corregir la palabra mal escrita. Por ejemplo, si se ha escrito hwile en vez de while o fi en vez de if, intercambiando caracteres adyacentes. Implementación de Analizadores léxicos 1. Usar un generador automático de analizadores léxicos (LEX) Ventaja: comodidad y rapidez en el desarrollo Desventaja: ineficiencia del analizador resultante y mantenimiento complicado 2. Escribir el AL en un lenguaje de alto nivel Ventaja: más eficiente 15 Desventaja: hay que hacerlo todo Elaborado por: Beatriz Pasaca| Noveno “A”
  • 16. 3. Hacerlo en lenguaje ensamblador Ventaja: máxima eficiencia Desventaja: muy complicado de desarrollar ANALIZADOR SINTÁCTICO Definición: Es la fase del analizador que se encarga de chequear la secuencia de tokens que representa al texto de entrada, en base a una gramática dada. En caso de que el programa de entrada sea válido, suministra el árbol sintáctico que lo reconoce en base a una representación computacional. Este árbol es el punto de partida de la fase posterior de la etapa de análisis: el analizador semántico. Para obtener en lógica el rigor y precisión deseados, se introduce un lenguaje formal. Éste es un lenguaje artificial, con unas reglas gramaticales explícitas que indican qué sucesiones de signos del alfabeto son fórmulas y unas reglas semánticas también explícitas, que determinan cuando una fórmula es verdadera bajo una determinada interpretación. Éste lenguaje, pues, se utiliza como vehículo para el razonamiento. El análisis sintáctico es una aplicación que resulta del estudio de la Teoría de Autómatas y Lenguajes Formales. El análisis sintáctico es la base del Demostrador de Teoremas, ya que le permite analizar los componentes léxicos y sintácticos que forman una fórmula para después poderla evaluar, o no en caso de error, correctamente. Visión General: Todo lenguaje de programación obedece a unas reglas que describen la estructura sintáctica de los programas bien formados que acepta. Se puede describir la sintaxis de las construcciones de los lenguajes de programación por medio de gramáticas de contexto libre. Las gramáticas formales ofrecen ventajas significativas a los diseñadores de lenguajes y a los desarrolladores de compiladores: • Las gramáticas son especificaciones sintácticas y precisas de lenguajes de 16 programación. • A partir de una gramática se puede generar automáticamente un analizador sintáctico. Elaborado por: Beatriz Pasaca| Noveno “A”
  • 17. El proceso de generación automática anterior puede llevar a descubrir ambigüedades. • Una gramática proporciona una estructura a un lenguaje de programación, siendo más fácil generar código y detectar errores. • Es más fácil ampliar/modificar el lenguaje si está descrito con una gramática. El analizador sintáctico dirige el proceso de compilación, de manera que el resto de fases evolucionan a medida que el sintáctico va reconociendo la secuencia de entrada por lo que, a menudo, el árbol ni siquiera se genera realmente. En la práctica, el analizador sintáctico también: • Incorpora acciones semánticas en las que colocar el resto de fases del compilador (excepto el analizador léxico): desde el análisis semántico hasta la generación de código. • Informa de la naturaleza de los errores sintácticos que encuentra e intenta recuperarse de ellos para continuar la compilación. • Controla el flujo de tokens reconocidos por parte del analizador léxico. El papel de Analizador sintáctico El analizador obtiene una cadena de componentes léxicos del analizador léxico, como se muestra en la siguiente figura, y comprueba si la cadena puede ser generada por la gramática del lenguaje fuente. El analizador sintáctico informará de cualquier error de sintaxis de manera inteligente. También debería recuperarse de los errores que ocurren frecuentemente para poder continuar procesando el resto de su entrada. 17 Elaborado por: Beatriz Pasaca| Noveno “A”
  • 18. Posición del Analizador sintáctico en el modelo del compilador Manejo de errores sintácticos • Los errores en la programación pueden ser de los siguientes tipos: • Léxicos, producidos al escribir mal un identificador, una palabra clave o un operador. • Sintácticos, por una expresión aritmética o paréntesis no equilibrados. • Semánticos, como un operador aplicado a un operando incompatible. • Lógicos, puede ser una llamada infinitamente recursiva. • De corrección, cuando el programa no hace lo que el programador realmente deseaba. Gramáticas Una Gramática es la definición de un lenguaje. Lenguaje es la colección (finita o no) de palabras de un alfabeto (representado por å ), por ejemplo, cualquier subconjunto de å * (conjunto de todas las posibles palabras definidas sobre un alfabeto). El alfabeto del lenguaje L de la lógica proposicional contiene dos tipos de signos: los conectores y las letras proposicionales. Se utilizarán: ¬, v, Ù , ® , « como conectores y p, q, r, s, t, ... como letras proposicionales. Se utilizarán también los paréntesis como signos impropios. Las fórmulas de L se construyen siguiendo unas sencillas reglas de formación. Dichas reglas extraen del conjunto de filas de signos del alfabeto aquellas a las que llamamos fórmulas. La definición de Gramática formal viene dada por la: Cuádrupla G= ( å t, å n, S, P). Donde: å t: es el alfabeto de símbolos Terminales. å n: es el alfabeto de símbolos No Terminales. 18 S: es el axioma o símbolo inicial de la gramática. P: es conjunto finito de producciones xAy::=z / x,y,z eå * Aeån. Elaborado por: Beatriz Pasaca| Noveno “A”
  • 19. Permite, por tanto, la especificación formal de las reglas de generación de los programas. Derivaciones: El funcionamiento de las gramáticas se basa en el concepto de derivación. Comenzando por una cadena formada únicamente por el símbolo inicial, se aplican repetidamente las reglas de P hasta llegar a una cadena formada únicamente por terminales. Aplicar una regla consiste simplemente en encontrar, dentro de la cadena actual, la parte izquierda de la regla y sustituirla por la parte derecha correspondiente Arboles de Ambigüedad Supongamos que tenemos la gramática: con las siguientes producciones 19 La sentencia id*id+id, tiene distintas derivaciones: Elaborado por: Beatriz Pasaca| Noveno “A”
  • 20. Sin embargo, en cierto sentido, todas estas derivaciones representan una misma estructura". De alguna manera nos transmiten la idea de que se está sumando el producto de los dos primeros id con el tercero. Podemos representar esto de forma compacta mediante un _árbol como el siguiente: Esto es lo que se conoce como _árbol de análisis o de derivación. Intuitivamente, lo que hacemos es representar en paralelo" las reglas necesarias para derivar la cadena de entrada. La raíz es el símbolo inicial de la gramática y cada nodo interior representa una producción: está etiquetado con un no terminal (A) y sus hijos de izquierda a derecha están etiquetados con X1; X2; : : : ;Xn de modo que (A) X1X2 : : :Xn es una regla de la gramática. Puede suceder que una misma cadena tenga asociado más de un _árbol de derivación. Por ejemplo, la cadena anterior tiene asociados dos _arboles, cada uno con un significado distinto: 20 Elaborado por: Beatriz Pasaca| Noveno “A”
  • 21. Decimos que una sentencia es ambigua (con respecto a una gramática) si tiene más de un árbol sintáctico. Clasificación de las gramáticas La Jerarquía de Chomsky consta de cuatro niveles: • Gramáticas de tipo 0 (sin restricciones), que incluye a todas las gramáticas formales. Estas gramáticas generan todos los lenguajes capaces de ser reconocidos por una máquina de Turing. Los lenguajes son conocidos como lenguajes recursivamente enumerables. Nótese que esta categoría es diferente de la de los lenguajes recursivos, cuya decisión puede ser realizada por una máquina de Turing que se detenga. • Gramáticas de tipo 1 (gramáticas sensibles al contexto) generan los lenguajes sensibles al contexto. Estas gramáticas tienen reglas de la forma con A un no terminal y α, β y γ cadenas de terminales y no terminales. Las cadenas α y β pueden ser vacías, pero γ no puede serlo. La regla está permitida si S no aparece en la parte derecha de ninguna regla. Los lenguajes descritos por estas gramáticas son exactamente todos aquellos lenguajes reconocidos por una máquina de Turing no determinista cuya cinta de memoria está acotada por un cierto número entero de veces sobre la longitud de entrada. • Gramáticas de tipo 2 (gramáticas libres del contexto) generan los lenguajes independientes del contexto. Las reglas son de la forma con A un no terminal y γ una cadena de terminales y no terminales. Estos lenguajes son aquellos que pueden ser reconocidos por un autómata con pila. • Gramáticas de tipo 3 (gramáticas regulares) generan los lenguajes regulares. Estas gramáticas se restringen a aquellas reglas que tienen en la parte izquierda un no terminal, y en la parte derecha un solo terminal, posiblemente seguido de un no terminal. La regla también está permitida si S no aparece en la parte derecha de ninguna regla. Estos lenguajes son aquellos que pueden ser aceptados por un autómata finito. También esta familia de lenguajes pueden ser obtenidas por medio de expresiones regulares. 21 Nótese que el conjunto de gramáticas correspondiente a los lenguajes recursivos no es un miembro de la jerarquía. Elaborado por: Beatriz Pasaca| Noveno “A”
  • 22. Tipos de Gramáticas Cada lenguaje regular es a su vez libre del contexto, asimismo un lenguaje libre del contexto es también dependiente del contexto, éste es recursivo y a su vez, recursivamente enumerable. Las inclusiones son, sin embargo, propias, es decir, existen en cada nivel lenguajes que no están en niveles anteriores. Las gramáticas de tipo 2 o Libres de contexto, son las mas útiles para lenguajes de programación, en la actualidad son la manera estándar de representar la estructura de los lenguajes desprogramación. Gramáticas independientes del contexto La gramática independiente del contexto consta de terminales, no terminales, un símbolo inicial y producciones. 1. Los terminales son los símbolos básicos con que se forman las cadenas. 2. Los no terminales son variables sintácticas que denotan conjuntos de cadenas. Los no terminales definen conjuntos de cadenas que ayudan a definir el lenguaje generado por la gramática. 3. En una gramática, un no terminal es considerado como el símbolo inicial, y el conjunto de cadenas que representan es el lenguaje definido por la gramática. 4. Las producciones de una gramática especifican cómo se pueden combinar los terminales y los no terminales para formar cadenas. Cada producción consta de un terminal, 22 seguido por algún símbolo y seguida por una cadena de no terminales y terminales. Notación BNF Elaborado por: Beatriz Pasaca| Noveno “A”
  • 23. Utilizada para representar las gramáticas independientes de contexto, que es una escritura gramatical para especificar lenguajes de programación. En esta notación se deben seguir las siguientes convenciones: No terminales: Paréntesis angulares <> Terminal: Cadenas de caracteres El símbolo : := se lee “se define como”, ó se ”reescribe como”, se utiliza en lugar de la flecha. Varias producciones de tipo: <A> : := <B1> <A> : := <B2> … <A> : := <Bn> se pueden escribir como:<A> : := <B1> | < B2> |…| <B n> GRAMÁTICAS REGULARES GRAMÁTICAS INDEPENDIENTES DEL CONTEXTO • En el lado derecho existe un nodo terminal • Poseen variables A, B, C seguido de un no terminal, o un solo terminal, y • Poseen cadenas de caracteres. en el lado izquierdo existe un nodo no terminal. • Genera lenguaje de tipo 2 o • Poseen constantes a, b, c. lenguaje independiente de • Genera lenguaje de tipo 3 o lenguaje regular. contexto. • Su importancia reside en que los lenguajes • No tiene restricciones con respecto generados por ellas son exactamente aquellos a sus reglas de escritura, su lado que reconocen los autómatas finitos. izquierdo de cada regla sea un no • Existe exactamente un no terminal terminal: S →aMa. • La parte de la cadena no generada siempre • Se utilizan cuando un autómata aparece al final. finito no reconoce ciertos • Proporciona un plantilla o patrón para las lenguajes. cadenas de lenguajes. • Se escriben frecuentemente • Si en cada regla α → β cumple: utilizando una notación conocida con BNF (Backus-Naur). α ϵ Vn, y • Para determinar si están bien escritas se utilizan los árboles de análisis sintáctico. β ϵ Vt, p • Cualquier gramática libre de contexto que no contenga la 23 β ϵ (Vt * Vn) cadena vacía puede ser generado: L – {λ} ó L. • El no terminal puede ser uno o Elaborado por: Beatriz Pasaca| Noveno “A”
  • 24. varios que puede tomar. • Proporcionar un mecanismo simple y exacto para describir los métodos - Gramáticas Lineales - A::=α por los cuales las frases (lenguaje natural) son construidas de por la izquierda → - A::=Va bloques más pequeñas. • Si cada regla: α→β cumple α ϵ Vn. - S::=λ • Cumple los requerimientos para ser una gramática tipo 1. Se clasifican en: - Gramáticas Lineales - A::=a por la derecha → - A::=aV - S::=λ Cumple con los requerimientos para ser una gramática de tipo 2. Diferencias entre Gramáticas Regulares y gramáticas Libes de contexto Ejercicios resueltos en clases: Sea la gramática: S → AA A → AAA | a | bA |Ab Determinar la cadena b2aba2ba → bbabaaba S →AA→ bAA → bbAA → bbaA → bbabA → bbabAAA → bbabaAA → bbabaAbA→ bbabaabA → babaaba Arboles de derivación Sea la gramática: S → AB A → aA | a B → bB | b Determinar la cadena aabbb elaborar el árbol de derivación. S →AB→ aAB → aaB →aabB → aabbB → aabbb S → AB → aAbB → aabbB → aabbb 24 S → AB → abB → AbbB → Abbb → aAbbb →aabbb Elaborado por: Beatriz Pasaca| Noveno “A”
  • 25. Árbol de Derivación de la cadena aabbb Se puede concluir que la gramática anteriormente definida no es ambigua, ya que a pesar de tener derivaciones diferentes, posee un solo árbol de derivación. Sea la gramática: S → SbS | ScS | a , construir el árbol de derivación para la cadena abaca Derivaciones: 1. S → SbS → abS → abScS → abaca 2. S → SbS → SbScS → abaca 3. S → ScS → SbScS → abaca Árboles de Derivación para la cadena abaca 25 Ambigüedad: La presencia de dos derivaciones por la izquierda distintos se corresponde con la existencia de dos árboles de derivación distintos por lo tanto una gramática ambigua se caracteriza por tener dos o más derivaciones por la izquierda para la misma cadena. Elaborado por: Beatriz Pasaca| Noveno “A”
  • 26. Derivación por la izquierda 1. S → ScS → SbScS → abScS → abacS → abaca El no terminal se expande siempre del extremo izquierdo. Derivación por la derecha 2. S → ScS → SbSca → Sbaca → abaca El no terminal es el que se expande por la derecha. • Toda derivación en una gramática regular, es a la vez una derivación por la izquierda y por la derecha sin tener en cuenta si tenemos una gramática regular por la derecha o por la izquierda. Simplificación de Gramáticas Independientes de Contexto Para realizar la simplificación de estas gramáticas debemos hacer lo siguiente: 1. Eliminar las producciones en donde se encuentre contenida la palabra vacía (ε ó λ). Gramática: 1. A → bAA | aC | B 2. B → aSS | BC 3. C→ CC | λ 4. S → SS | C A Para ello reemplazamos la cadena vacía en todos los no terminales que la produzcan así: 1. A → bAA | aC | B A → bAA | a λ | B | a λ A → bAA | a | B | a 2. B → aSS | BC | B λ B → aSS | BC | B 3. C→ CC | C λ C→ CC | C 26 4. S → SS |CA| λA S → SS | C A | A Elaborado por: Beatriz Pasaca| Noveno “A”
  • 27. La gramática resultante será: A → bAA | a | B B → aSS | BC | B C→ CC | C S → SS | C A | A 2. Eliminar las producciones unitarias Se considera una producción unitaria cuando es de la forma B → B Identificamos las producciones unitarias y luego reemplazamos el nodo o no terminal unitario con la parte derecha de todas las producciones que produce así: A → bAA | a | B B → aSS | BC | B C→ CC | C S → SS | C A | A La gramática resultante será: A → bAA | a | aSS | BC B → aSS | BC C→ CC S → SS | C A | bAA | a | aSS | BC 3. Eliminar no terminales no generativos Para esta gramática el no terminal no generativo es C ya que no produce terminal alguno, entonces eliminamos todas las producciones que lo contengan: A → bAA | a | aSS | BC B → aSS | BC C→ CC S → SS | C A | bAA | a | aSS | BC La gramática que nos queda es: A → bAA | a | aSS B → aSS C→ CC 27 S → SS | bAA | aSS | a 4. Eliminar los símbolos no alcanzables Elaborado por: Beatriz Pasaca| Noveno “A”
  • 28. Los símbolos no alcanzables son aquellos que no son producidos por algún axioma o no terminal, para nuestro ejercicio los símbolos no alcanzables son los no terminales B y C. A → bAA | a | aSS B → aSS C→ CC S → SS | bAA | aSS | a Entonces la gramática simplificada nos queda: A → bAA | a | aSS S → SS | bAA | aSS | a NOTA: Para una mejor eficiencia de la simplificación se deben aplicar todos los pasos anteriormente mencionado en orden. Ejercicios resueltos en clases: G = ({0,1}, {A, A, B, C}, S, P) P S → AB |0S1| A |CX A → 0AB | λ B → B1 | λ 1. Eliminar los no terminales inútiles 2. Eliminar producciones vacías λ S → AB |0S1| A S → AB |0S1|A|B| λ A → 0AB | λ A → OAB |0A|OB| O B → B1 | λ B → B1 | 1 3. Eliminar producciones unitarias S → AB |0S1|OAB|OA|OB|O|B1|1| λ A → OAB |0A|OB| O B → B1 | 1 G = ({i,+}, {Z, E, F, G, P, Q, S, T}, Z, P) P Z→E+T|T E→E|S+F|T F → F | FP | P P→G G → G | GG | F 28 T→T+i|i Q→E|E+F|T|S S→i Elaborado por: Beatriz Pasaca| Noveno “A”
  • 29. 1. Eliminar los no terminales inútiles 2. Eliminar producciones vacías λ Z→ E + T Z→ E + T E→E|S+F|T E→T F → F | FP | P T→T+i|i P→G G → | GG | F T→T+i|i S→i 3. Eliminar producciones unitarias Z→T+T Z→T+T T →T+i|i ó E→T+i|i T→T+i|i 1. FORMA NORMAL DE CHOMSKY Se aplica: A → BC No se puede aplicar cuando: A→a - Hay producciones vacías A, B, C ϵ V, a ϵ ∑ - Hay producciones unitarias EJERCICIO B → aBC E → aBEd 1. Eliminar producciones vacías λ 2. Reemplazamos en la gramática Da → a B → DaBC Dd → d E → DaBEDd Base (2) → Longitud de la parte derecha sea mayor que dos A → CBFH A → D1FH D1 → CB A → D1D2 D2 → FH Ejercicio resuelto en clases: 29 Dada la siguiente expresión regular, determinar el AFD, la gramática y el árbol de derivación para una cadena valida. Elaborado por: Beatriz Pasaca| Noveno “A”
  • 30. Expresión regular → letra+_numero+letra+ | _letra* Gramática: <inicio> → _ <guion> <inicio> → l <letra> <guion> → l <letra> | n <numero> <letra> → n <numero> | l_<guion> | λ <numero> → l <letra> • Derivación de la cadena _a <inicio> → _<guion> <inicio> <guion> → _a <letra> <letra> → _a λ _ <guion> <letra> → _a a <letra> λ Ejercicio resuelto en clases: Simplificar la gramática: S → A | Aa A→B B→C|b C → D | ab D→b 1. Unitario(S) → {S, A, B, C, D} 2. S → Aa | b | ab 3. S → Aa | b | ab 30 Unitario (A) → {A, B, C, D} A → b | ab A→ b | ab Unitario (B) → {B, C, D} C → ab | b Unitario (C) → {C, D} D→d Elaborado por: Beatriz Pasaca| Noveno “A”
  • 31. Aplicar la forma normal de Chomsky en la siguiente gramática: S → bA | aB S → DbA | DaB A → bAA | aS |a A → DbD1 | DaS |Da B → aBB | bS | b B →DaD2 | bS | b Da → a Db → b D1→ AA D2 → BB Simplificar las gramáticas dadas: Gramática 1: S → AB| Cb A → f | Al B → t | CF D→a|t 1. Términos no Generativos 2. Términos no Alcanzables S → AB S → AB A → f | Al A → f | Al B→t B→t D→a|t Gramática 2: S → aA| λ A → aA | bB | λ B → bB 1. Producciones vacías 2. Términos no Generativos 3 Términos no alcanzables S → aA| λ S → aA| λ S → aA| λ A → aA | bB | a A → aA | a A → aA | a B → bB B → bB Gramática 3: S → a| aA | B | E A → aB | λ 31 B → Aa E → bED D → ccc Elaborado por: Beatriz Pasaca| Noveno “A”
  • 32. 1. Producciones vacías 2. Producciones unitarias S → a| aA | B | E S → a| aA | Aa |bED A → aB | a A → aB | a B → Aa | a B → Aa | a E → bED E → bED D → ccc D → ccc 3. Términos no Generativos 4. Términos no alcanzables S → a | aA| Aa S → a |aA| Aa A → aB |a A → aB | a B → Aa | a B →Aa | a E → bED D → ccc Gramática 4: S → ABaC A → AB B → b |λ C→D|λ D→d 2. Producciones vacías 2. Producciones unitarias 3. Términos no alcanzables S → ABaC |AaC | ABa | Aa S → ABaC |AaC | ABa | Aa S→ABaC|AaC|ABa|Aa A → AB | A A → AB A→AB B →b B →b B→b C→D C→D C→d D→d D→d Análisis Es el proceso que permite determinar si una cadena puede ser generada por una gramática. En nuestro caso es el proceso que permite determinar si una fórmula está bien generada o no. Este proceso es fundamental en el Demostrador de Teoremas ya que una cadena que no sea una fórmula no servirá para realizar los razonamientos o pruebas. Por tanto es importante definir precisamente un analizador para esta tarea. 32 Desde el punto de vista formal un analizador es un Autómata equivalente a una gramática, que reconoce la estructura de una cadena de componentes léxicos. Elaborado por: Beatriz Pasaca| Noveno “A”
  • 33. Objetivos del analizador sintáctico (AS) El AS es la parte principal de un compilador. Las funciones principales de AS son: • Comprobar si el programa es sintácticamente correcto. • Generar las estructuras de datos (árboles sintácticos u otras estructuras) que representan el programa y sirven para el analizador semántico y el generador de código. • En el caso de compilación dirigida por sintaxis -- llamar al analizador semántico y al generador de código. Otras: • Reaccionar frente a los errores e intentar acotar la propagación de los errores (intentar evitar que un error produzca muchos mensajes de error). • Hacer los siguientes pasos del compilador más independientes de la sintaxis del lenguaje. Comportamiento del analizador sintáctico El proceso de análisis sintáctico y la ejecución son ahora dos pasos completamente separados, no se procederá a la ejecución del código de cualquier archivo hasta que éste en su totalidad, así como todo el código requerido se haya analizado completa y satisfactoriamente. Uno de los nuevos requisitos introducidos con esta separación es que todos los archivos requeridos y de inclusión tienen que ser sintácticamente completos ahora. Ya no es permitida la separación de diferentes segmentos de una estructura de control a través de varios archivos. Esto quiere decir que ahora no puede iniciar un ciclo for o while, una sentencia if o un bloque switch en un archivo, y tener el final del ciclo, sentencias else, endif, case o break en un archivo diferente. Aun es perfectamente legal incluir código adicional al interior de ciclos u otras estructuras de control, únicamente las palabras claves de control y los corchetes correspondientes {___} tienen que estar en la misma unidad de compilación (archivo o cadena procesada por eval ()). 33 Elaborado por: Beatriz Pasaca| Noveno “A”
  • 34. Esto no debe generar una repercusión significativa ya que separar el código de esta manera debe ser considerado como muy mal estilo, en cualquier caso. Algo más que ya no es posible, aunque es rara veces visto en código PHP 3, es devolver valores desde un archivo requerido devolver un valor desde un archivo de inclusión es posible aun. Un analizador sintáctico, tal y como se ha enfocado en esta librería es una clase que recibe lo siguiente: 1. Una clase donde se almacenarán los atributos de cada símbolo. 2. Una gramática libre de contexto donde el símbolo de inicio solo produce una variable. 3. Una función de síntesis para cada producción, encargada de sintetizar los atributos necesarios. 4. Para cada producción una opcional regla para deshacer ambigüedades. 5. Una instancia de una clase de léxico que derive de la clase abstracta de léxico básico. 6. Una opcional función de error para manejarlos y recuperarse en la medida de lo posible. El analizador ira leyendo del léxico y aplicando las reducciones necesarias (llamando a las funciones de síntesis proporcionadas). El resultado habitual es un árbol sintáctico construido de manera ascendente. Cada nodo de ese árbol es del tipo genérico que se le pasa como parámetro al parser mencionado en la lista anterior. Función del análisis sintáctico. Analizar sintácticamente una tira o cadena de tokens no es más que encontrar para ella el árbol sintáctico o de derivación que tiene como raíz el axioma de la gramática, y como nodos terminales la sucesión ordenada de símbolos que componen la cadena analizada. 34 En caso de no existir este árbol sintáctico, la cadena no pertenecerá al lenguaje, y el analizador sintáctico ha de emitir el correspondiente mensaje de error. Elaborado por: Beatriz Pasaca| Noveno “A”
  • 35. Existen dos formas de analizar sintácticamente una cadena: Análisis descendente: Partiendo del axioma inicial de la gramática se va descendiendo utilizando las derivaciones izquierdas, hasta llegar a construir la cadena analizada. Análisis ascendente: Se va construyendo el árbol desde sus nodos terminales. Es decir, se construye desde los símbolos de la cadena hasta llegar al axioma de la gramática. En este caso, se emplean normalmente las derivaciones más a la derecha hasta la localización de la raíz. Los principales métodos de análisis sintáctico son: Análisis descendente: • Análisis descendente con retroceso. • Análisis de gramáticas LL. Análisis ascendente: • Análisis ascendente con retroceso. • Análisis de gramáticas de precedencia simple. • Análisis de gramáticas de precedencia generalizada. • Análisis de gramáticas por el método mixto. • Análisis de gramáticas de precedencia de operador. • Análisis de gramáticas LR. Los análisis con retroceso se basan en la prueba sistemática de todas las alternativas posibles, dando marcha atrás tan pronto como se detecte que el camino seguido es erróneo. Pueden usarse para cualquier gramática de contexto libre, aunque tienen tres grandes inconvenientes: 35 Primero, emplean mucho más tiempo para el análisis que los demás analizadores, dependiendo éste incluso de la ordenación de las reglas gramaticales. Elaborado por: Beatriz Pasaca| Noveno “A”
  • 36. Segundo, no dan un buen diagnóstico de los errores que encuentran; Tercero, complican la generación de código cuando ésta se realiza al par que el análisis sintáctico. Los métodos más eficientes de análisis (tanto ascendente como descendente) no funcionan para todas las gramáticas de contexto libre, sino sólo para las gramáticas que cumplen unas determinadas condiciones. Afortunadamente, en la mayoría de los casos, pueden encontrase para los lenguajes de programación gramáticas de tipo LL o LR que los generen. Para representar el árbol sintáctico que conduce hasta una cadena se asigna a cada regla de la gramática un número. Se define el parse como la secuencia ordenada de números (de reglas) aplicadas para construir dicho árbol. Hay dos tipos de parse, que son: • El parse-izquierdo: Son los números de las reglas de derivación izquierda utilizadas para generar la cadena a partir del axioma, por tanto correspondiente a un análisis descendente. • El parse-derecho: Son los números de las reglas de derivación derecha utilizadas para generar la cadena a partir del axioma, en orden inverso. El tomar el orden inverso viene condicionado por ser el análisis ascendente el que normalmente utiliza las reglas de derivación derecha, con lo que el orden en el que aparecen al realizar el análisis es invertido. Simultáneamente a la fase de análisis sintáctico, además de reconocer las secuencias de tokens, y analizar su estructura, pueden realizarse una serie de tareas adicionales, como: • Recopilar información de los distintos tokens y almacenarla en la tabla de símbolos. • Realizar algún tipo de análisis semántico, tal como la comprobación de tipos. • Generar código intermedio. • Avisar de los errores que se detecten. 36 Análisis Sintáctico (LL1): Elaborado por: Beatriz Pasaca| Noveno “A”
  • 37. Definición: Aquel en el que se agrupan todas las clausuras con idéntica parte izquierda. Es decir todas las clausuras del tipo: A -> B C D A -> E F G ...... A ->X Y Z Si no existen dos clausuras con idéntica parte izquierda que pueden empezar con un mismo símbolo terminal, y no existe recursividad a la izquierda, el lenguaje es LL1. Para Aplicar el Algoritmo LL (1) se procede de la siguiente forma: 1. Se debe eliminar de la gramática recursividad por la izquierda (en caso de que la tuviera). 2. Realizar factorización a la izquierda en caso de que la gramática lo requiera. 3. Determinar el conjunto de primeros y siguientes. 4. Construir la tabla de Análisis LL(1). 5. Validar una cadena. Para comprender cada uno de los pasos del algoritmo descrito anteriormente tomaremos como ejemplo la siguiente gramática: Ejercicio resuelto en clases: S -> if E then S | while E do S | I := E I -> * I | id A A -> Ɛ | [E] E -> I | cte REGLAS PARA DETERMINAR LOS PRIMEROS 1. Si X es terminal, entonces PRIMERO(X) es {X}. 2. Si X -> £ es una producción, entonces agregar £ al PRIMERO(X). 3. Si X es no terminal y X -> Y1 Y2 ... Yk es una producción, entonces agregar µ en 37 PRIMERO(X) si para algún i, µ está en PRIMERO(Yi), y £ está en todos los PRIMERO(Y1),...,PRIMERO(Yi-1). Elaborado por: Beatriz Pasaca| Noveno “A”
  • 38. PRIMERO( S ) = { if, while } U P( I ) =>{ if, while,*id } PRIMERO( I ) = { *, id } => { *,id } PRIMERO( A ) = { Ɛ, [ } => { Ɛ,[ } PRIMERO( E ) = { cte } U P( I ) => {*, id , cte } Reglas para obtener el conjunto de los siguientes: La idea es que los siguientes de un no terminal (A) son aquellos terminales que pueden llegar a aparecer detrás de (A) en alguna forma sentencial. En el caso del símbolo inicial y de aquellos que pueden aparecer al inicial de una forma sentencial, además incluimos el fin de la entrada. Para encontrar los siguientes de cada no terminal, podemos emplear las siguientes ecuaciones: 1. Como inicialización, asociamos a todos los no terminales distintos del inicial el conjunto vacío y al símbolo inicial le asociamos el conjunto f ($), para que se cumpla la ecuación (1). 2. Para cumplir con la ecuación (2), añadimos al conjunto de siguientes de cada no terminal (A) los primeros de los β tales que α(A) β constituye la parte derecha de alguna regla. 38 Elaborado por: Beatriz Pasaca| Noveno “A”
  • 39. 3. Recorremos ordenadamente las reglas aplicando la ecuación (3). Para ello, por cada regla (A) α(B) β con β anulable, añadimos los siguientes de (A) a los de (B) Este paso tendremos que repetirlo hasta que no cambie ninguno de los conjuntos de siguientes en un recorrido completo de las reglas. Vamos a aplicar el algoritmo a nuestro ejemplo. En primer lugar, inicializamos los siguientes al conjunto vacio salvo para el símbolo inicial: Después, añadimos los símbolos que aparecen inmediatamente después de cada no terminal: Ahora aplicamos ordenadamente la ecuación (3) hasta que no haya modificaciones. Así 39 Con la regla (E) (I), aumentamos los siguientes de (I): Elaborado por: Beatriz Pasaca| Noveno “A”
  • 40. A partir de (I) id(A), aumentamos los siguientes de (A): Si volvemos a repasar las reglas, vemos que los siguientes no varían, así que podemos dar por terminado el proceso. SLR: La mayor inconveniencia de los analizadores LL1 es el conjunto bastante limitado de los lenguajes LL1. Un conjunto bastante más amplio, que incluye casi todos los lenguajes de programación, es el SLR. Definición: Un lenguaje de tipo SLR si existe un analizador SLR que permita analizarlo. Comentario: Al igual que el analizador SLR, éste se construye siguiendo un algoritmo, por lo tanto no podemos hablar de tautología. Un algoritmo para construir SLR, orientado a “ejecutarse” a mano se encuentra descrito en el apartado 2. ¿Qué hace? 40 En general, un analizador sintáctico es un autómata a pila. El analizador sintáctico: Inicializa el compilador y AS en particular. Elaborado por: Beatriz Pasaca| Noveno “A”
  • 41. Para cada símbolo de entrada llama al analizador morfológico y el AM proporciona el siguiente símbolo de entrada. • Analizando el símbolo, la pila y el estado del autómata, el AS produce las estructuras necesarias para la siguiente etapa y en el caso de compilación dirigida por la sintaxis -- invoca llamadas directas al analizador semántico y al generador de código. • Escribe mensajes de errores y trata de limitar el efecto de estos errores. Elección de algoritmos. Consideración de las diferencias, ventajas y desventajas. Plan de desarrollo Etapas: 1. Elegir el tipo del analizador sintáctico. 2. Trasformar el lenguaje al tipo correspondiente. Calcular las tablas correspondientes. 3. Escribir el programa del analizador sintáctico sin acciones ni producción de código. 4. Añadir al analizador atributos y acciones (en la parte del analizador sintáctico solo la producción de la salida, tal como se explica en los requisitos de prueba). 5. Añadir al analizador generador de código. Propiamente hablando, sólo el segundo y el tercer punto forman el analizador sintáctico por sí. El resto es analizador semántico y el generador de código. En todos los modos se requiere una vista general al definir como vamos a realizar el analizador sintáctico. ANALIZADOR SEMÁNTICO. Introducción. 41 Es aquel que se ocupa de analizar si la sentencia de caracteres tiene algún significado. Se pueden encontrar sentencias que son sintácticamente correctas pero que no se pueden Elaborado por: Beatriz Pasaca| Noveno “A”
  • 42. ejecutar porque carecen de sentido. El análisis semántico se hace a la par que el análisis sintáctico introduciendo en éste unas rutinas semánticas. El análisis semántico utiliza como entrada el árbol sintáctico detectado por el análisis sintáctico para comprobar restricciones de tipo y otras limitaciones semánticas y preparar la generación de código. El instrumento más utilizado para conseguirlo es la gramática de atributos. Gramáticas semánticas Una gramática semántica es una gramática libre de contexto en la cual la elección de símbolos no terminales y de reglas de producción son regidos tanto por funciones sintácticas como semánticas. Muchos símbolos no terminales representan elementos semánticos; esto es, que su posición depende también del tema que se este tratando. Una gramática semántica puede ser usada por un sistema de análisis gramatical de la misma forma en que pudiera ser usada una gramática estrictamente sintáctica. Las principales ventajas son las siguientes: • Cuando el análisis gramatical esta completo, el resultado puede ser usado inmediatamente sin otra etapa de proceso que pudiera ser requerida si una interpretación semántica no hubiese sido realizada durante el análisis. • Muchas ambigüedades que pueden surgir durante un análisis gramatical estrictamente sintáctico son evitadas al tomar en cuenta criterios semánticos durante el análisis. Sin embargo, existen también algunas desventajas en el uso de gramáticas semánticas. • El número de reglas requeridas pueden llegar a ser demasiado grande ya que faltaría muchas generalizaciones sintácticas. • Debido a lo anterior, el análisis gramatical puede ser muy lento y ocupar mucho espacio en memoria. 42 Se puede observar que las gramáticas semánticas pueden ser útiles para producir interfaces de subconjuntos de lenguaje natural. Elaborado por: Beatriz Pasaca| Noveno “A”
  • 43. Gramática con atributos. Una gramática con atributos es una gramática de contexto libre cuyos símbolos pueden tener asociados atributos y las producciones pueden tener asociadas reglas de evaluación de los atributos. • Cada símbolo puede tener asociado un número finito de atributos. • Cada producción puede tener asociada un número finito de reglas de evaluación de los atributos. • Los valores de los atributos deberán estar asociados con un dominio de valores. • Por lo general las gramáticas con atributos se escriben en forma tabular, con cada regla Gramatical enumerada con el conjunto de ecuaciones de atributo o reglas semánticas asociadas con esa regla de manera siguiente: Regla Gramatical Regla Asociada Regla 1 Ecuaciones de atributo asociadas … …. Regla n Ecuaciones de atributo asociadas Representación de las gramáticas con atributos Atributos Heredados y Atributos Sintetizados Atributos Sintetizados Atributos Heredados Si b está asociado con el símbolo no Si b está asociado con el 43 terminal A símbolo no terminal α Elaborado por: Beatriz Pasaca| Noveno “A”
  • 44. Evaluación: Las reglas de evaluación de Evaluación: La Evaluación de los atributos sintetizados se realizan un atributo heredado depende cuando se aplican reducciones en el de los atributos asociados con análisis sintáctico. los símbolos precedentes en la derivación. Requisitos para la evaluación: Requisitos para la evaluación: Las reglas de evaluación de los Realizar un análisis atributos deben definirse en función descendente. de los atributos asociados con los atributos gramaticales a la derecha. Realizar un análisis ascendente Diferencias entre Atributos Sintetizados y Atributos Heredados Ejemplo: Gramática de Atributos Sintetizados exp exp + term | exp – term | term term term * factor | factor factor (exp) | numero Se pide obtener la gramática con atributos, dada la expresión: (34-3)*42 y expresar la semántica de su valor en un árbol de análisis gramatical. Empezamos obteniendo la derivación por la izquierda para la expresión dada: exp term term * factor factor * factor (exp) * facto (exp – term ) * factor (term – term ) * factor (factor – term) * factor (numero – term ) * factor (numero –factor) * factor (numero –numero) * factor ( numero –numero) *numero Luego de ello podemos construir el árbol de análisis gramatical para (34-3)*42, mostrando cálculos del atributo val. 44 Elaborado por: Beatriz Pasaca| Noveno “A”
  • 45. Árbol de análisis gramatical Nótese que el atributo principal de una exp o term o factor es su valor numérico (val) el cual va ha formar parte de las ecuaciones para las reglas semánticas que se muestran a continuación: 45 Elaborado por: Beatriz Pasaca| Noveno “A”
  • 46. Regla Gramatical Regla Semántica exp1 exp2 + term exp1. val= exp2.val + term.val exp1 exp2 – term exp1.val = exp2.val – term.val exp term exp.val = term.val term1 term2 * factor term1.val = term2.val * factor.val term factor term.val = factor.val factor (exp) factor.val = (exp) .val factor numero factor.val = numero.val Ejemplo de Gramática con atributos heredados Realizar un análisis descendente, dada la siguiente gramática y las reglas de evaluación. 46 Elaborado por: Beatriz Pasaca| Noveno “A”
  • 47. BIBLIOGRAFÍA FUENTES PRIMARIAS: • ALFONSECA M. Manuel, ”Compiladores e Interpretes”. Editorial PEARSON EDUCACION 2006. • ALFRED V, Aho; RAVI, Sethi; JFFREY D, Ullman “Compiladores Principios, técnicas y herramientas”. Addison-Wesley. Iberoamericana 1990. • KELLEY, Dean. “Teoria de Automatas y Lenguajes Formales”. Editorial PRENTICE HALL 1995. • KENET LOUDEN Construcción de Compiladores Principios y Práctica._ UNED 2004. FUENTES SECUNDARIAS: • AHO, Alfred y ULLMAN, Jeffrey.2005, Compiladores Principios, Técnicas y Herramientas, Edición Electrónica • ANTONIO, Reyes Oscar; POSADAS, Martínez Wendi; RODRÍGUEZ, Alemán Magdalena; ROSAS, Gómez Lizzeth Del Carmen; ROSAS, Hernández José Alberto. LENGUAJES Y AUTÓMATAS CS51. [en linea]. Colombia Bogota, [http://mx.geocities.com/amigos2365/anteproyecto.html], [Consulta: 15 Octubre 2008]. • BONILLA,Oscar.[http://74.125.45.104/search?q=cache:A9YLY0RcmuUJ:oscarbonil la.com/courses/compilrs/materials/06_Analisis_Sintactico.ppt+analizador+sint%C3 %A1ctico&hl=es&ct=clnk&cd=11] • Ceballos, Carmona Miguel Ángel. 2002. Compiladores. [en línea]. Irapuato, Gto, [http://www.monografias.com/trabajos11/compil/compil2.shtml] ,[Consulta: 14 Octubre 2008]. • GÁLVEZ ROJAS, Sergio Y MORA MATA, Miguel Ángel. .2005, Java a Tope: Traductores y Compiladores con Lex/Yacc, JFlex/Cup y JavaCC, Edición Electrónica •Universidad de Huelva, Procesadores de lenguaje, http://www.uhu.es/470004004/docs/tema4_ejercicios.pdf 47 Elaborado por: Beatriz Pasaca| Noveno “A”
  • 48. •Universidad Nacional de Río Cuarto, Departamento de Computación, Autómatas y Lenguajes, Practicó 6 - Parsing y Gramáticas LR 2009, http://dc.exa.unrc.edu.ar/nuevodc/materias/automatas/reposit/1173382040/ayl_prac_6.pdf 48 Elaborado por: Beatriz Pasaca| Noveno “A”