Compiladores e intérpretes Análisis Sintáctico VI

Slides:



Advertisements
Presentaciones similares
Ejemplo Práctico de un Compilador Pequeño
Advertisements

Compiladores e intérpretes Análisis Sintáctico II
Compiladores e intérpretes Generación de código intermedio II
Compiladores e intérpretes
Compiladores e intérpretes Análisis Sintáctico III
ESTRUCTURA DE DATOS Unidad 04 Árboles BINARIOS.
La maquina de Turing La máquina de Turing es una caja negra (tan simple como una máquina de escribir y tan compleja como un ser humano) capaz no sólo de.
MATRIZ DE CHEQUEO DE PARIDAD
Analizadores Sintácticos Descendentes Predictivos
Investigación de Operaciones II
UNIVERSIDAD NACIONAL AUTÓNOMA DE MÉXICO FACULTAD DE INGENIERIA DIVISIÓN DE INGENIERÍA ELÉCTRICA COMPUTACIÓN PARA INGENIEROS NOTA IMPORTANTE: Para complementar.
Traducción dirigida por la Sintaxis
Método de Ford-Fulkerson
ANALISIS SINTACTICO DESCENDENTE
Teoría de lenguajes y compiladores
Unidad aritmético-lógica
Algebra Booleana y Compuertas Lógicas
Tema 3. Optimización de Código
ANALISIS SINTACTICO El análisis gramatical es la tarea de determinar la sintaxis, o estructura, de un programa. Por esta razón también se le conoce como.
Teoría de lenguajes y compiladores
APLICACIONES DE PILAS Estructuras de Datos.
Analizador Sintáctico Descendente
2- SIMPLEX.
Algoritmos para calcular el Conjunto Primero y el Conjunto Siguiente
Programación de sistemas
TRADUCTOR DE UN PROGRAMA
Estructura de Datos Lineales
M.C. Meliza Contreras González
Análisis sintáctico LR: SLR (LR simple)
Teoría de lenguajes y compiladores
Autómatas de Pila Teoría del Autómata.
Ejemplo de aplicación de las ANN
ANALISIS SINTACTICO Parte I
Diseño y análisis de algoritmos
Clasificación de Gramáticas y Manejo de Errores
FORMA INTERNA DE REPRESENTAR
Material de apoyo Unidad 4 Estructura de datos
Teoría de lenguajes y compiladores
Procesadores de Lenguajes
Todo traductor esta basado en una gramática para el lenguaje fuente. Todo traductor esta basado en una gramática para el lenguaje fuente. Una gramática.
Teoría de lenguajes y compiladores Analizadores lexicográficos
Compiladores e intérpretes Análisis Sintáctico III
Agustín J. González ELO320: Estructura de Datos y Algoritmos
Unidad aritmético-lógica
Programación de Sistemas
Compiladores e intérpretes
Análisis Léxico Área Software de Base.
Estructura de Datos M.C. José Andrés Vázquez Flores FCC/BUAP
1 Compilación, pereza y expresiones let(rec) 2 Compilando un programa Describiremos un compilador para la máquina minimal usando un conjunto de esquemas.
Parte I. Estructuras de Datos.
Agustín J. González ELO320: Estructura de Datos y Algoritmos
Programación de Sistemas FEI – 2008
Unidad 1. Introducción a los Compiladores.
DIAGRAMA DE FLECHAS O RUTA CRITICA
Términos algoritmo diseñar algoritmo implementar algoritmo
UNIVERSIDAD LATINA (UNILA)
LE, EI, Profesor Ramón Castro Liceaga UNIVERSIDAD LATINA (UNILA) TRADUCTORES Y ANALIZADOR LEXICOGRÁFICO.
Teoría de lenguajes y compiladores
Autómatas y Compiladores Novena Semana. Ricardo Vargas Del Valle A35469.
Teoría de lenguajes y compiladores
PRINCIPIOS DE PROGRAMACIÓN
Teoría de lenguajes y compiladores
El proceso de compilación
Lic. Carla Aguirre Montalvo
PROGRAMACION DE Pilas o Stacks
IV. GRAMÁTICAS DISTRIBUIDAS Y TABLAS DE SÍMBOLOS
Programación de Sistemas
DETECCION DE SEÑALES BINARIAS EN RUIDO GAUSSIANO El criterio de toma de decisión fue descrito por la ecuación Un criterio muy usado para escoger el nivel.
REPÚBLICA BOLIVARIANA DE VENEZUELA MINISTERIO DEL PODER POPULAR PARA LA EDUCACION SUPERIOR UNIVERSIDAD VALLE DEL MOMBOY CARVAJAL EDO. TRUJILLO ENERO 2014.
Ciclos condicionales y exactos Estructura de control de ciclos
Transcripción de la presentación:

Compiladores e intérpretes Análisis Sintáctico VI Profesor: Eridan Otto

Análisis Sintáctico VI Análisis de Presedencia de Operador Operadores unarios Funciones de precedencia Manejo de errores Diagnóstico y recuperación Errores de reducción Errores de desplazamiento

Compiladores e intérpretes Análisis sintáctico VI : Análisis de precedencia, Operadores unarios Manejo de operadores unarios, casos: Un operador unario que no usa el mismo símbolo que el binario podría ser por ejemplo la negación lógica (NOT, !), en forma abstracta: Se puede crear en el esquema de relaciones de precedencia, normal, siendo op cualquier operador,usando las siguientes reglas: op < > op, si tiene mayor precedencia que op < op, si tiene menor precedencia que op Un operador unario que a demás es binario como el signo - El análisis debería fallar en casos como : id*-id, mediante el uso de la tabla de precedencia. Solución:utilizar el analizador léxico para devolver dos componentes léxicos distintos, analizando el componente léxico anterior, para distinguir uno de otro. Ejemplo:es el menos unario, si antes el componente léxico leído es un operador, un parénesis izquierdo, una coma o un símbolo de asignación.

Compiladores e intérpretes Análisis sintáctico VI : Análisis de precedencia,funciones de precedencia La tabla de precedencia, se puede simplificar , con el objetivo de ahorrar memoria y aumentar la velocidad de proceso, mediante dos funciones f () y g() Estas funciones toman un token o símbolo terminal y entregan un entero. Tienen que cumplir que si a < b , f (a) < g(b) si a = b , f (a) =< g(b) si a > b , f (a) > g(b) Para determinar la relación de precedencia entre a y b , basta comparar entre f (a) y g(b) No todas las relaciones de precedencia tienen funciones de precedencia. Por ejemplo las entradas sin relación, que determinan errores, no son representables, por lo que habría que manejarlas en una lista aparte.

Compiladores e intérpretes Análisis sintáctico VI : Análisis de precedencia,funciones de precedencia Construcción de las funciones de precedencia Crear símbolos y para cada símbolo terminal más $ Se dividen los y en tantos grupos como sea posible: Si a = b, entonces y están en el mismo grupo. Note que esta regla se aplica transitvamente, por ejemplo si c=b,entonces y también están en el mismo grupo que . Crear un grafo dirigido cuyos nodos son los grupos encontrados en el paso 2, los arcos se forman: Si a < b, entoncesun arco apunta desde el al Si a > b, entoncesun arco apunta desde el al Se debe revisar la precencia de ciclos en el grafo: Si hay ciclos, entonces no se pueden definir funciones de precedencia. Si no hay ciclos, entonces f(a) y g(a) se calculan, determinando los caminos más largos que se pueden recorrer desde y respectivamente.

Compiladores e intérpretes Análisis sintáctico VI : Análisis de precedencia,funciones de precedencia Ejemplo, dada la siguiente tabla construir las funciones de precedencia, a partir de la siguiente tabla: Cada grupo es formado por un solo símbolo, aplicando las relaciones se obtiene el siguiente grafo:

Compiladores e intérpretes Análisis sintáctico VI : Análisis de precedencia,funciones de precedencia No hay ciclos por lo que se pueden definir las funciones de procedencia. Como las funciones de $ no tienen arcos, entonces f($)=g($)=0 El camino más largo desde , tiene longitud 1, entonces g(+) =1. El camino más largo desde , forma una ruta desde a a a a a de longitud 5, entonces g(id) =5 La, tabla se reduce a la mitad, de 16 a 8 elementos:

Compiladores e intérpretes Análisis sintáctico VI : Análisis de precedencia,Manejo de errores Detección de errores Hay dos puntos en el proceso de análisis sintáctico de pecedencia de operadores que pueden detectar errores sintácticos. Si no hay una relación de precedencia entre un terminal en el tope del stack y el símbolo contenido en el preanálisis de la cadena de entrada. Si un pivote ha sido encontrado, pero no existe un lado derecho de las producciones en la gramática que calce en con el pivote. Si se revisa el algoritmo para realizar el análisis, la forma de reducción de pivotes se compone sólo de terminales. De esta forma, si se encuentra una secuencia a < b1= b2=..... =bk, en el stack listo para ser reducido, no significa que b1 b2..... bk es una cadena símbolos terminales que corresponda con el lado derecho de una producción. El algoritmo estándar no hace este chequeo, pero claramente se puede hacer, y se debe para poder: Detectar errores de Tipo 2 Facilitar el análisis semántico a partir de las reducciones La solución es alterar el algoritmo para que mantenga en forma explícita los no termianles en el stack y agregar un chequeo de le gramatica para buscar el pivote detectado.

Compiladores e intérpretes Análisis sintáctico VI : Análisis de precedencia,Manejo de errores Para que el algoritmo funcione, los no terminales no participan en las relaciones de precedencia. Las definiciones de entrada, salida e inicialización son las mismas, se agrega en la entrada G:gramática. mueva el símbolo de preanálisis al primer token de w$ Repita Siempre si $S está en el tope del stack y preanálisis = $ entonces return ok /*S no terminal inicial de G*/ sino inicio sea a el simbolo terminal tope del stack y sea b el símbolo apuntado por preanálisis si a < b o a = b entonces inicio push b en stack; avance el puntero de preanálisis al próximo símbolo fin sino si a > b entonces inicio pivote=‘’ repita pivote= concatenar (simbolo del tope del stack, pivote); pop stack hasta el terminal del tope del stack es < que el terminal más recientemente retirado; buscar pivote en lado derecho de las producciones de G; si encuentra entonces push no terminal del lado izquierdo de la produccion sino error_t2() sino error_t1()

Compiladores e intérpretes Análisis sintáctico VI : Análisis de precedencia,Manejo de errores Con el algoritmo modificado, Analice la cadena id * +id usando la tabla y la gramática ya definidas, en los ejemplos anteriores: Pila precedencia Acción Entrada $ menor mayor id * +id $ * +id $ +id $ Desplazamiento Reducción por E::=id Reducción, no existe Pivote E* por lo tanto el análisis arroja error tipo 2 $ id $E $E* $

Compiladores e intérpretes Análisis sintáctico VI : Análisis de precedencia,Manejo de errores Diagnóstico y recuperación de errores de redución Para el caso 2, la idea es diagnosticar lo más certeramente el error. Una vez que se obtiene el pivote, se compara y no hay coincidencia, en una primera instancia, la rutina de manejo de errores debe intentar decidir, qué producción del lado derecho es la más “parecida” al pivote errado. Un criterio para acercarce a una producción es medir la “distancia” de diferencia con respecto al pivote, donde por distancia se entiende, el número de símbolos terminales o tokens en que difieren las producciones del pivote (en cuanto a no coincidencia en orden, falta o exceso). La producción más cercana será la de minima distancia con respecto al pivote, con un criterio de cero uno a dos, más distancia es muy riesgoso elegir un lado derecho, por lo que un mensaje de error genérico debería generarse. La recuperación consistirá en hacer push del no terminal correspondiente al lado derecho más cercano, en caso de no encontrarlo, seguir analizando después del pop.

Esperando expresión en linea ..... Compiladores e intérpretes Análisis sintáctico VI : Análisis de precedencia,Manejo de errores Diagnóstico y recuperación de errores de reducción Genéricamente, por ejemplo, supongamos, un pivote sólo de terminales abc, no hay producción con un lado derecho que coincida, entonces se puede dar: Los tokens pueden sobrar, por ejemplo el lado derecho de la producción aEbE, con diferencia de 1 resultó ser la más cercana, se debe emitir un diagnóstico: b ilegal en linea ..... Se debe considerer el cambio o falta de un carácter, por ejemplo el lado derecho de la producción abEdc, con diferencia de 2 resultó ser la más cercana, se debe emitir un diagnóstico: Esperando d en linea ..... Se debe considerer el cambio o cero diferencias en los no terminales pero una falta de coincidencia en la secuencia consideando los no terminales, por ejemplo el lado derecho de la producción abEc, resultó ser la más cercana, se debe emitir un diagnóstico: Esperando expresión en linea ..... Donde el no terminal E tiene la categoría de Expresión

Compiladores e intérpretes Análisis sintáctico VI : Análisis de precedencia,Manejo de errores Diagnóstico y recuperación de errores de reducción Para la gramática de operadores: E::= E+E|E-E|E*E|E/E| (E)|-E|id Es fácil ver que siempre se podrá en contrar el lado derecho correspondiente al pivote con error, pues no se acumulan más de dos tokens por noterminal antes de una reducción. Basta, entonces que dependiendo del no terminal del pivote con error, se cheque sus no terminales: Si el terminal es +,-,*,/ está en el pivote con error, chequear cuáles de los no terminales faltan y diagnosticar: falta(n) operandos en linea... Si el terminal es () está en el pivote con error, diagnosticar: falta expresión entre los paréntesis en linea... Para casos imprevistos, diagnosticar: error en linea...

Compiladores e intérpretes Análisis sintáctico VI : Análisis de precedencia,Manejo de errores Diagnóstico y recuperación de errores de desplazamiento La forma 1 de detectar errores, ocurre cuando se consulta a la matriz de precedencia para decidir si desplazar o reducir y no hay definida una relación entre el símbolo del tope del stack y el símbolo actual d preanálisis. Para recuperar el proceso se debe, modificar el stack, la entrada, o ambos. Modificación del stack: Insertar, o sacar e insertar (modificar). Se debe ser cuidadoso para no caer en loops. Una forma de no caer en loop, es asegurarse que el próximo símbolo de entrada pueda ser desplazado. Pop e intentar seguir el análisis. Para la sigiente configuración donde no hay relación entre b y c $ab cd$ Si a < = c , s puede hacer pop del stack, o saltar c si b< = d . Una tercera elección es encontrar un símbolo e tal que b< =e< =c haciendo push de e. No hay recetas para una solución general.

Compiladores e intérpretes Análisis sintáctico VI : Análisis de precedencia,Manejo de errores Diagnóstico y recuperación de errores de desplazamiento Una estrategia a seguir, si se usa tabla, es incorporar en la matriz de precedencia la incorporación de el nombre de una rutina de recuperación de error en cada celda en blanco. Si no hay relación el analizador saltará a la rutina de recuperación de errores especificada. Se puede usar la misma rutina para varias celdas. Ejemplo: Matriz reducida que muestra celdas en blanco de la matriz original, Cada rutina debe tener una acción y un diagnóstico: E1:/*falta una expresion*/ acción:insertar id en el stack diagnóstico: “falta operando......” Id ( ) $ Id e3 e3 > > ( < < = e4 ) e3 e3 > > $ < < e2 e1

Compiladores e intérpretes Análisis sintáctico VI : Análisis de precedencia,Manejo de errores Diagnóstico y recuperación de errores de desplazamiento E2:/*una expresión parte con paréntesis derecho*/ acción:no considerar ) en entrada avanzando preanálisis diagnóstico: “parentesis derecho desbalanceado......” E3:/*cuando falta un operador entre dos id o entre id y ( o ) id*/ acción:insertar +en la entrada diagnóstico: “falta operador......” E4:/* una expresión termina con paréntesis izquierdo */ acción:pop ( del stack diagnóstico: “falta paréntesis derecho......” Id ( ) $ Id e3 e3 > > ( < < = e4 ) e3 e3 > > $ < < e2 e1

Compiladores e intérpretes Análisis sintáctico VI : Análisis de precedencia,Manejo de errores Diagnóstico y recuperación de errores Finalmente un ejemplo para considerer todos los mecanismos en conjunto. Pila precedencia Acción Entrada $ menor mayor Mayor No hay id +) $ +) $ +)$ )$ $ Desplazamiento Reducción por E::=id Reducción, no existe pivote E*, por lo tanto reducir el más cercano:E::=E+E Diag:falta operando Llamar a rutina e2, diagnostica Parentesis derecha desbalanceado Acción saltar (, por lo que el análisis termina OK $ id $E $E+