Analizador sintactico

4
PONTIFICIA UNIVERSIDAD CATOLICA DEL ECUADOR SEDE IBARRA Nombre: Alexis Vilañez Fecha: 03/05/13 Materia: Compiladores ANALIZADOR SINTACTICO El papel del analizador sintáctico: El análisis sintáctico convierte el texto de entrada en otras estructuras (comúnmente árboles), que son más útiles para el posterior análisis y capturan la jerarquía implícita de la entrada. Un analizador léxico crea tokens de una secuencia de caracteres de entrada y son estos tokens los que son procesados por el analizador sintáctico para construir la estructura de datos, por ejemplo un árbol de análisis o árboles de sintaxis abstracta. El análisis sintáctico también es un estado inicial del análisis de frases de lenguaje natural. Es usado para generar diagramas de lenguajes que usan flexión gramatical, como los idiomas romances o el latín. Los lenguajes habitualmente reconocidos por los analizadores sintácticos son los lenguajes libres de contexto. Cabe notar que existe una justificación formal que establece que los lenguajes libres de contexto son aquellos reconocibles por un autómata de pila, de modo que todo analizador sintáctico que reconozca un lenguaje libre de contexto es equivalente en capacidad computacional a un autómata de pila. Los analizadores sintácticos fueron extensivamente estudiados durante los años 70 del siglo XX, detectándose numerosos patrones de funcionamiento en ellos, cosa que permitió la creación de programas generadores de analizadores sintáticos a partir de una especificación de la sintaxis del lenguaje en forma Backus-Naur por ejemplo, tales como yacc, GNU bison y javaCC. Análisis sintáctico ascendente y descendente La tarea esencial de un analizador es determinar si una determinada entrada puede ser derivada desde el símbolo inicial, usando las reglas de una gramática formal, y como hacer esto, existen esencialmente dos formas:

Transcript of Analizador sintactico

Page 1: Analizador sintactico

PONTIFICIA UNIVERSIDAD CATOLICA DEL ECUADOR

SEDE IBARRA

Nombre: Alexis Vilañez

Fecha: 03/05/13

Materia: Compiladores

ANALIZADOR SINTACTICO

El papel del analizador sintáctico:

El análisis sintáctico convierte el texto de entrada en otras estructuras (comúnmente árboles), que

son más útiles para el posterior análisis y capturan la jerarquía implícita de la entrada. Un

analizador léxico crea tokens de una secuencia de caracteres de entrada y son estos tokens los que

son procesados por el analizador sintáctico para construir la estructura de datos, por ejemplo un

árbol de análisis o árboles de sintaxis abstracta.

El análisis sintáctico también es un estado inicial del análisis de frases de lenguaje natural. Es

usado para generar diagramas de lenguajes que usan flexión gramatical, como los idiomas

romances o el latín. Los lenguajes habitualmente reconocidos por los analizadores sintácticos son

los lenguajes libres de contexto. Cabe notar que existe una justificación formal que establece que

los lenguajes libres de contexto son aquellos reconocibles por un autómata de pila, de modo que

todo analizador sintáctico que reconozca un lenguaje libre de contexto es equivalente en

capacidad computacional a un autómata de pila.

Los analizadores sintácticos fueron extensivamente estudiados durante los años 70 del siglo XX,

detectándose numerosos patrones de funcionamiento en ellos, cosa que permitió la creación de

programas generadores de analizadores sintáticos a partir de una especificación de la sintaxis del

lenguaje en forma Backus-Naur por ejemplo, tales como yacc, GNU bison y javaCC.

Análisis sintáctico ascendente y descendente La tarea esencial de un analizador es determinar si una determinada entrada puede ser derivada desde el símbolo inicial, usando las reglas de una gramática formal, y como hacer esto, existen esencialmente dos formas:

Page 2: Analizador sintactico

Analizador sintáctico descendente (Top-Down-Parser): ..un analizador puede empezar con el símbolo inicial e intentar transformarlo en la entrada, intuitivamente esto sería ir dividiendo la entrada progresivamente en partes cada vez más pequeñas, de esta forma funcionan los analizadores LL, un ejemplo es el javaCC. Analizador sintáctico ascendente (Bottom-Up-Parser): un analizador puede empezar con la entrada e intentar llegar hasta el símbolo inicial, intuitivamente el analizador intenta encontrar los símbolos más pequeños y progresivamente construir la jerarquía de símbolos hasta el inicial, los analizadores LR funcionan así y un ejemplo es el Yacc. Otros tipos de analizadores son: Analizador sintáctico descendente recursivo Chart parser Left corner parser Analizador sintáctico LR De la forma de construir el árbol sintáctico se desprenden dos tipos o clases de analizadores sintácticos. Pueden ser descendentes o ascendente • Descendentes : Parten del axioma inicial, y van efectuando derivaciones a izquierda hasta obtener la secuencia de derivaciones que reconoce a la sentencia. Pueden ser: Con retroceso. Con recursión. LL(1) • Ascendentes: Parten de la sentencia de entrada, y van aplicando reglas de producción hacia atrás (desde el consecuente hasta el antecedente), hasta llegar al axioma inicial. Pueden ser: Con retroceso. LR(1)

Análisis semántico y tratamiento de errores Si un compilador tuviera que procesar sólo programas correctos, su diseño e implantación se simplificarían mucho. Pero los programadores a menudo escriben programas incorrectos, y un buen compilador debería ayudar al programador a identificar y localizar errores. Es más, considerar desde el principio el manejo de errores puede simplificar la estructura de un compilador y mejorar su respuesta a los errores. 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. El manejo de errores de sintaxis es el más complicado desde el punto de vista de la

Page 3: Analizador sintactico

creación de compiladores. Nos interesa que cuando el compilador encuentre un error, se recupere y siga buscando errores. Por lo tanto el manejador de errores de un analizador sintáctico debe tener como objetivos: • Indicar los errores de forma clara y precisa. Aclarar el tipo de error y su localización. • Recuperarse del error, para poder seguir examinando la entrada. • No ralentizar significativamente la compilación. Un buen compilador debe hacerse siempre teniendo también en mente los errores que se pueden producir; con ello se consigue: • Simplificar la estructura del compilador. • Mejorar la respuesta ante los errores. Tenemos varias estrategias para corregir errores, una vez detectados: • Ignorar el problema (Panic mode ): Consiste en ignorar el resto de la entrada hasta llegar a una condición de seguridad. Una condición tal se produce cuando nos encontramos un token especial (por ejemplo un ‘;’ o un ‘END’).A partir de este punto se sigue analizando normalmente. Ejemplo: aux = a[i] a[i] = a[j]; a[j] = aux; Error id ‘=’ id ‘*‘ id ‘+’ id ’*‘ id ‘+’ ’=’ id ’*‘ id ‘+’ ‘;’ id ’*‘ id ‘+’ ‘=’ id ‘;’ Token especial, seguimos compilando a partir de él • Recuperación a nivel de frase: Intenta recuperar el error una vez descubierto. En el caso anterior, por ejemplo, podría haber sido lo suficientemente inteligente como para insertar el token ‘;’ . Hay que tener cuidado con este método, pues puede dar lugar a recuperaciones infinitas. • Reglas de producción adicionales para el control de errores: La gramática se puede aumentar con las reglas que reconocen los errores más comunes. En el caso anterior, se podría haber puesto algo como: sent_errónea Ú sent_sin_acabar sentencia_acabada ’;’ sentencia_acabada Ú sentencia ‘;’ sent_sin_acabar Ú sentencia Lo cual nos da mayor control en ciertas circunstancias • Corrección Global : Dada una secuencia completa de tokens a ser reconocida, si hay algún error por el que no se puede reconocer, consiste en encontrar la secuencia completa más parecida que sí se pueda reconocer. Es decir, el analizador sintáctico le pide toda la secuencia de tokens al léxico, y lo que hace es devolver lo más parecido a la cadena de entrada pero sin errores, así como el árbol que lo reconoce.

Page 4: Analizador sintactico

Árboles Sintácticos Es una representación que se utiliza para describir el proceso de derivación de dicha

sentencia.

Como nodos internos del árbol, se sitúan los elementos no terminales de las reglas de

producción que vayamos aplicando, y tantos hijos como símbolos existan en la parte

derecha de dichas reglas.

Veamos un ejemplo: Sea la gramática anterior.

E Ú E + T | T

T Ú T * F | F

F Ú ( E ) | a | b

Supongamos que hay que reconocer: ( a + b ) * a + b

Si el árbol puede construirse, es que la sentencia es correcta:

Ambigüedad: Una gramática es ambigua si derivando de forma diferente con el mismo

tipo de derivación se llega al mismo resultado.

Ejemplo: Considérese la gramática

E � E + E

E � E * E

E � ( E )

E � id | num

si tenemos aux + cont + i

<ID><+><ID><+><ID>