1 / 17

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

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.

blaise
Download Presentation

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

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Compiladores eintérpretes Análisis Sintáctico VI Profesor: Eridan Otto

  2. 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

  3. 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.

  4. 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.

  5. 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.

  6. 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:

  7. 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:

  8. 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.

  9. 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() fin sino error_t1() fin

  10. 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 Acción precedencia Entrada Desplazamiento Reducción por E::=id Desplazamiento Reducción, no existe Pivote E* por lo tanto el análisis arroja error tipo 2 menor mayor menor mayor $ id * +id $ * +id $ * +id $ +id $ $ id $E $E* $

  11. 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.

  12. 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

  13. 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...

  14. 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.

  15. 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

  16. 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

  17. 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 Acción precedencia Entrada Desplazamiento Reducción por E::=id Desplazamiento 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 menor mayor menor Mayor No hay $ id +) $ +) $ +)$ )$ )$ $ $ id $E $E+ $E $E $E

More Related