Your SlideShare is downloading. ×
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Materia unidad compiladores
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Materia unidad compiladores

3,961

Published on

Recopilacion de la materia de compiladores dictada por el Ing. Luis Chamba

Recopilacion de la materia de compiladores dictada por el Ing. Luis Chamba

Published in: Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
3,961
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
203
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 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ásicosVentajas 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 programaVentajas 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 desarrolloMás Diferencias entre Traductor y un CompiladorTraductor: - 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 lenguajede programación o el lenguaje de máquina de cualquier computador entre unmicroprocesador 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 componentesléxicos. En esta etapa se lee el archivo de texto que contiene el código fuente y las cadenas sevan agrupando en componentes léxicos o tokens.Estos componentes léxicos son los operadores, identificadores y palabras reservadas dellenguaje. 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 capazde 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 tokenpredefinido IF para esa secuencia de caracteres, sino que entendería que es un identificadorcualquiera (como pudiera ser el nombre de una variable).- Análisis Sintáctico o Parser: Agrupa componentes léxicos en frases gramaticales. Estaetapa 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 detokens tenga el orden correcto.Esta etapa detecta errores sintácticos. Siguiendo el ejemplo anterior, si hubiésemos puesto ifien 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áscomplejas del proceso de compilación. Tiene que realizar varias tareas: la resolución denombres, el tipo de las expresiones y la evaluación L/R. La resolución de nombres consiste encomprobar que cada identificador que usemos (ya sea una variable local, parámetro, atributo o 5mé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 2identificadores (asignación, suma, producto, concatenación, etc.) comprobar que ambosidentificadores aceptan dicha operación, que son de tipos compatibles. La evaluación L/Rconsiste 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 ala 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 losidentificadores de usuario (nombres de variables, de funciones, de tipos, etc.) utilizadosen el programa fuente y reunir información sobre los distintos atributos de cadaidentificador. Estos atributos pueden proporcionar información sobre la memoriaasignada a un identificador, la dirección de memoria en que se almacenará en tiempode ejecución, su tipo, su ámbito (la parte del programa donde es visible), etc. Puesbien, la tabla de símbolos es una estructura de datos que posee información sobre losidentificadores definidos por el usuario, ya sean constantes, variables, tipos u otros.Dado que puede contener información de diversa índole, debe hacerse de forma quesu estructura no sea uniforme, esto es, no se guarda la misma información sobre unavariable del programa que sobre un tipo definido por el usuario. Hace funciones dediccionario de datos y su estructura puede ser una tabla hash, un árbol binario debúsqueda, etc., con tal de que las operaciones de acceso sean lo bastante eficientes. Esquema por etapas definitivo del traductorTanto la etapa de análisis como la de síntesis acceden a esta estructura, por lo que se halla 6muy acoplada al resto de fases del compilador. Por ello conviene dotar a la tabla de símbolosde 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 sueleser usual hacer un primer prototipo de un compilador con una tabla de símbolos fácil deconstruir, y cuando el compilador ya ha sido finalizado, entonces se procede a sustituir la tablade símbolos por otra más eficiente en función de las necesidades que hayan ido surgiendo. Elesquema general definitivo de un traductor se detalla en la figura anterior. TIPOS DE COMPILADORESExisten 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 compiladorNormalmente 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 7varios 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 envarias plataformas distintas.El código que genera el Back End normalmente no se puede ejecutar directamente, sino quenecesita ser enlazado por un programa enlazador (linker).Arquitectura Real De Compiladores E IntérpretesLa arquitectura real de compiladores e intérpretes es la siguiente: 8 Elaborado por: Beatriz Pasaca| Noveno “A”
  • 9. ANALIZADOR LÉXICODefinición: El analizador léxico (scanner), lee un texto fuente y lo transforma en una secuenciaordenada de elementos léxicamente válidos. Un caracter o conjunto de estos que constituya uncomponente léxico se llama lexema (token). Como componentes léxicos consideramos:palabras reservadas, separadores, operadores, identificadores, constantes y signos depuntuació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 elanalizador sintáctico para hacer el análisis. Esta interacción suele aplicarse convirtiendo alanalizador 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 deentrada hasta que pueda identificar el siguiente componente léxico, el cual devuelve alsintá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 losagrupa para formar unidades con significado propio, los componentes léxicos (tokens eningles). 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 componenteléxico conforme el analizador sintáctico lo va necesitando para avanzar en la gramática. Loscomponentes 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. 10Componentes 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ácterLos componentes léxicos se suelen definir como un tipo enumerado. Se codifican comoenteros. También se suele almacenar la cadena de caracteres que se acaba de reconocer (ellexema), 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 componenteslé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 delas tres operaciones básicas: concatenación, repetición (*) y alternativas (j) vamos a usar lossiguientes 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 bUn 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 ajbjCualquier carácter excepto un conjunto dado • ~ (ajb) indica cualquier carácter que no sea una a o bOpcionalidad ? 12r? indica que la expresión r puede aparecer o no. En el caso de que aparezca solo lo haría unavez. Elaborado por: Beatriz Pasaca| Noveno “A”
  • 13. Aspectos prácticos en la implementación de un analizador léxicoPrincipio de máxima longitudSe 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 “mayorque".Palabras reservadas versus identificadoresUn lenguaje de programación puede tener del orden de 50 palabras reservadas. Para evitartener 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 dedecidir el tipo de token si se trata de una palabra reservada o de un identificador consultandouna tabla previamente inicializada con las palabras reservadas. Este método es recomendablecuando el número de palabras reservadas es grande.Entrada de los identificadores en la Tabla de SímbolosEn lenguajes sencillos con solo variables globales y declaraciones, es normal implementar elscanner para que introduzca los identificadores en la Tabla de Símbolos conforme los vareconociendo, si es que no han sido ya introducidos. Después, el analizador sintáctico seencarga de introducir información adicional sobre su tipo, etc. conforme la va obteniendodurante el análisis sintáctico.Si se trata de un lenguaje estructurado, el scanner no introduce los identificadores en la Tablade Símbolos, porque en este tipo de lenguajes, los identificadores pueden tener diferentessignificados según su contexto (como una variable, como una función, como un campo de unaestructura). 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. 13Gestió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 lomás costoso en tiempo en el proceso de traducción. Es importante implementarloeficientemente.Se utiliza un búfer dividido en dos mitades de tamaño N caracteres, donde N es un bloque dedisco (1024, 4096). Se leen N caracteres de la entrada en cada mitad del búfer con una únicaorden de lectura. Se mantienen dos apuntadores. Uno marca elinicio del lexema y el otro el carácter actual que se mueve hasta encontrar una subcadena quecorresponde con un patrón. Una vez reconocido un componente léxico ambos apuntadores secolocan en la misma posición y justo detrás del lexema reconocido.Tratamiento de errores léxicosLos errores léxicos se detectan cuando el analizador léxico intenta reconocer componentesléxicos y la cadena de caracteres de la entrada no encaja con ningún patrón. Son situacionesen las que usa un carácter invalido (@, $,",>,...), que no pertenece al vocabulario del lenguajede 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 lageneración de un error de sintaxis que sería detectado más tarde por el analizador sintácticocuando el analizador léxico devuelve un componente léxico que el analizador sintáctico noespera en esa posición. 14Los métodos de recuperación de errores léxicos se basan bien en saltarse caracteres en laentrada 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óncorrespondiente al último estado final visitado con el lexema formado hasta que salimos de él; elresto 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 seesperaba, 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ÁCTICODefinición: Es la fase del analizador que se encarga de chequear la secuencia de tokens querepresenta al texto de entrada, en base a una gramática dada. En caso de que el programa deentrada sea válido, suministra el árbol sintáctico que lo reconoce en base a una representacióncomputacional. Este árbol es el punto de partida de la fase posterior de la etapa de análisis: elanalizador semántico.Para obtener en lógica el rigor y precisión deseados, se introduce un lenguaje formal. Éste esun lenguaje artificial, con unas reglas gramaticales explícitas que indican qué sucesiones designos del alfabeto son fórmulas y unas reglas semánticas también explícitas, que determinancuando una fórmula es verdadera bajo una determinada interpretación. Éste lenguaje, pues, seutiliza 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 yLenguajes Formales. El análisis sintáctico es la base del Demostrador de Teoremas, ya que lepermite analizar los componentes léxicos y sintácticos que forman una fórmula para despuéspoderla evaluar, o no en caso de error, correctamente.Visión General: Todo lenguaje de programación obedece a unas reglas que describen laestructura sintáctica de los programas bien formados que acepta. Se puede describir la sintaxisde las construcciones de los lenguajes de programación por medio de gramáticas de contextolibre.Las gramáticas formales ofrecen ventajas significativas a los diseñadores de lenguajes y a losdesarrolladores 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 fasesevolucionan a medida que el sintáctico va reconociendo la secuencia de entrada por lo que, amenudo, 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ácticoEl analizador obtiene una cadena de componentes léxicos del analizador léxico, como semuestra en la siguiente figura, y comprueba si la cadena puede ser generada por la gramáticadel lenguaje fuente. El analizador sintáctico informará de cualquier error de sintaxis de manerainteligente. También debería recuperarse de los errores que ocurren frecuentemente parapoder 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 compiladorManejo 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áticasUna Gramática es la definición de un lenguaje. Lenguaje es la colección (finita o no) depalabras de un alfabeto (representado por å ), por ejemplo, cualquier subconjunto de å *(conjunto de todas las posibles palabras definidas sobre un alfabeto). El alfabeto del lenguaje Lde la lógica proposicional contiene dos tipos de signos: los conectores y las letrasproposicionales. Se utilizarán: ¬, v, Ù , ® , « como conectores y p, q, r, s, t, ... como letrasproposicionales. 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 reglasextraen 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. 18S: 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 aplicanrepetidamente 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 parteizquierda de la regla y sustituirla por la parte derecha correspondienteArboles de AmbigüedadSupongamos que tenemos la gramática:con las siguientes producciones 19La 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 dosprimeros id con el tercero. Podemos representar esto de forma compacta mediante un _árbolcomo el siguiente:Esto es lo que se conoce como _árbol de análisis o de derivación. Intuitivamente, lo quehacemos 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 conX1; 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. Porejemplo, 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áticasLa 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. 21Nótese que el conjunto de gramáticas correspondiente a los lenguajes recursivos no es unmiembro de la jerarquía. Elaborado por: Beatriz Pasaca| Noveno “A”
  • 22. Tipos de GramáticasCada lenguaje regular es a su vez libre del contexto, asimismo un lenguaje libre del contexto estambié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 noestán en niveles anteriores.Las gramáticas de tipo 2 o Libres de contexto, son las mas útiles para lenguajes deprogramación, en la actualidad son la manera estándar de representar la estructura de loslenguajes desprogramación.Gramáticas independientes del contextoLa gramática independiente del contexto consta de terminales, no terminales, un símbolo inicialy 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 escrituragramatical para especificar lenguajes de programación.En esta notación se deben seguir las siguientes convenciones:No terminales: Paréntesis angulares <>Terminal: Cadenas de caracteresEl 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 aabbbSe puede concluir que la gramática anteriormente definida no es ambigua, ya que a pesar de tenerderivaciones 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 25Ambigüedad: La presencia de dos derivaciones por la izquierda distintos se corresponde con laexistencia de dos árboles de derivación distintos por lo tanto una gramática ambigua se caracteriza portener 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 | A2. 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 | 13. 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→i3. 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→b1. 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|t1. 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 → bB1. 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 → ccc3. 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→d2. 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ácticoEl 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 archivosrequeridos y de inclusión tienen que ser sintácticamente completos ahora. Ya no es permitidala 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 bloqueswitch en un archivo, y tener el final del ciclo, sentencias else, endif, case o break en un archivodiferente.Aun es perfectamente legal incluir código adicional al interior de ciclos u otras estructuras decontrol, ú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 maneradebe 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 devolvervalores desde un archivo requerido devolver un valor desde un archivo de inclusión es posibleaun.Un analizador sintáctico, tal y como se ha enfocado en esta librería es una clase que recibe losiguiente: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 atributosnecesarios.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 lasfunciones de síntesis proporcionadas). El resultado habitual es un árbol sintáctico construido demanera ascendente. Cada nodo de ese árbol es del tipo genérico que se le pasa comopará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 árbolsintáctico o de derivación que tiene como raíz el axioma de la gramática, y como nodosterminales la sucesión ordenada de símbolos que componen la cadena analizada. 34En caso de no existir este árbol sintáctico, la cadena no pertenecerá al lenguaje, y el analizadorsintá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 descendiendoutilizando las derivaciones izquierdas, hasta llegar a construir la cadena analizada. Análisis ascendente: Se va construyendo el árbol desde sus nodos terminales. Es decir, seconstruye desde los símbolos de la cadena hasta llegar al axioma de la gramática. En estecaso, se emplean normalmente las derivaciones más a la derecha hasta la localización de laraí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 grandesinconvenientes: 35Primero, 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. Esdecir todas las clausuras del tipo: A -> B C D A -> E F G ...... A ->X Y ZSi no existen dos clausuras con idéntica parte izquierda que pueden empezar con un mismosí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 comoejemplo la siguiente gramática: Ejercicio resuelto en clases:S -> if E then S | while E do S | I := EI -> * I | id AA -> Ɛ | [E]E -> I | cteREGLAS PARA DETERMINAR LOS PRIMEROS1. 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 37PRIMERO(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 puedenllegar a aparecer detrás de (A) en alguna forma sentencial. En el caso del símbolo inicialy de aquellos que pueden aparecer al inicial de una forma sentencial, además incluimos elfin 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 conjuntovací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 noterminal (A) los primeros de los β tales que α(A) β constituye la parte derecha de algunaregla. 38 Elaborado por: Beatriz Pasaca| Noveno “A”
  • 39. 3. Recorremos ordenadamente las reglas aplicando la ecuación (3). Para ello, por cadaregla (A) α(B) β con β anulable, añadimos los siguientes de (A) a los de (B) Este pasotendremos que repetirlo hasta que no cambie ninguno de los conjuntos de siguientes enun recorrido completo de las reglas.Vamos a aplicar el algoritmo a nuestro ejemplo. En primer lugar, inicializamos lossiguientes 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í 39Con 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 porterminado el proceso.SLR:La mayor inconveniencia de los analizadores LL1 es el conjunto bastante limitado de loslenguajes LL1. Un conjunto bastante más amplio, que incluye casi todos los lenguajes deprogramació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 lotanto no podemos hablar de tautología.Un algoritmo para construir SLR, orientado a “ejecutarse” a mano se encuentra descrito en elapartado 2.¿Qué hace? 40En 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 desarrolloEtapas: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 laproducció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 unavista general al definir como vamos a realizar el analizador sintáctico. ANALIZADOR SEMÁNTICO.Introducción. 41Es aquel que se ocupa de analizar si la sentencia de caracteres tiene algún significado. Sepueden 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álisissintá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ácticopara comprobar restricciones de tipo y otras limitaciones semánticas y preparar la generaciónde código. El instrumento más utilizado para conseguirlo es la gramática de atributos.Gramáticas semánticasUna gramática semántica es una gramática libre de contexto en la cual la elección de símbolosno terminales y de reglas de producción son regidos tanto por funciones sintácticas comosemánticas. Muchos símbolos no terminales representan elementos semánticos; esto es, quesu posición depende también del tema que se este tratando. Una gramática semántica puedeser usada por un sistema de análisis gramatical de la misma forma en que pudiera ser usadauna 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. 42Se puede observar que las gramáticas semánticas pueden ser útiles para producir interfaces desubconjuntos 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 puedentener asociados atributos y las producciones pueden tener asociadas reglas de evaluaciónde 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 atributosAtributos 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 HeredadosEjemplo:Gramática de Atributos Sintetizadosexp exp + term | exp – term | termterm term * factor | factorfactor (exp) | numeroSe pide obtener la gramática con atributos, dada la expresión: (34-3)*42 y expresar lasemá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) *numeroLuego de ello podemos construir el árbol de análisis gramatical para (34-3)*42, mostrandocálculos del atributo val. 44 Elaborado por: Beatriz Pasaca| Noveno “A”
  • 45. Árbol de análisis gramaticalNótese que el atributo principal de una exp o term o factor es su valor numérico (val) elcual va ha formar parte de las ecuaciones para las reglas semánticas que se muestran acontinuació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.valEjemplo de Gramática con atributos heredadosRealizar 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 yLenguajes, 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”

×