El papel del analizador sintáctico

  • 290 views
Uploaded on

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
290
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
11
Comments
0
Likes
1

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. PONTIFICIA UNIVERSIDAD CATOLICA DEL ECUADORSEDE IBARRAESCUELA DE INGENIERIANombre: Espinosa Villarreal Héctor EfrénNivel: Quinto de SistemasFecha: 03-05-2013Asignatura: CompiladoresEl papel del analizador sintácticoTodo lenguaje de programación tiene reglas que describen la estructura sintáctica deprogramas bien formados. En Pascal, por ejemplo, un programa se compone de bloques, unbloque de proposiciones, una proposición de expresiones, una expresión de componentesléxicos, y así sucesivamente. Se puede describir la sintaxis de las construcciones de loslenguajes de programación por medio de gramáticas de contexto libre o notación BNF (Backus-Naur Form).Las gramáticas ofrecen ventajas significativas a los diseñadores de lenguajes y a losdesarrolladores de compiladores.Es la fase del analizador que se encarga de chequear el texto de entrada en base a unagramática dada. Y en caso de que el programa de entrada sea válido, suministra el árbolsintáctico que lo reconoce.En teoría, se supone que la salida del analizador sintáctico es alguna representación delárbol sintáctico que reconoce la secuencia de tokens suministrada por el analizador léxico.En la práctica, el analizador sintáctico también hace:• Acceder a la tabla de símbolos (para hacer parte del trabajo del analizador semántico).• Chequeo de tipos (del analizador semántico).• Generar código intermedio.• Generar errores cuando se producen.En definitiva, realiza casi todas las operaciones de la compilación. Este método de trabajoda lugar a los métodos de compilación dirigidos por sintaxis.• Las gramáticas son especificaciones sintácticas y precisas de lenguajes de programación.• A partir de una gramática se puede generar automáticamente un analizador sintáctico.• El proceso de construcción puede llevar a descubrir ambigüedades.• Una gramática proporciona una estructura a un lenguaje de programación, siendo másfácil generar código y detectar errores.• Es más fácil ampliar/modificar el lenguaje si está descrito con una gramáticaAnálisis sintáctico ascendente y descendenteDe la forma de construir el árbol sintáctico se desprenden dos tipos o clases deanalizadores sintácticos. Pueden ser descendentes o ascendente• Descendentes : Parten del axioma inicial, y van efectuando derivaciones a izquierda hastaobtener 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
  • 2. hacia atrás (desde el consecuente hasta el antecedente), hasta llegar al axioma inicial.Pueden ser:_ Con retroceso._ LR(1)Árbol sintáctico de una sentencia de un lenguajeEs una representación que se utiliza para describir el proceso de derivación de dichasentencia.Como nodos internos del árbol, se sitúan los elementos no terminales de las reglas deproducción que vayamos aplicando, y tantos hijos como símbolos existan en la partederecha de dichas reglas.Veamos un ejemplo: Sea la gramática anterior.E Ú E + T | TT Ú T * F | FF Ú ( E ) | a | bSupongamos que hay que reconocer: ( a + b ) * a + bSi el árbol puede construirse, es que la sentencia es correcta:
  • 3. Ambigüedad: Una gramática es ambigua si derivando de forma diferente con el mismotipo de derivación se llega al mismo resultado.Ejemplo: Considérese la gramáticaE  E + EE  E * EE  ( E )E  id | numsi tenemos aux + cont + i<ID><+><ID><+><ID>Tratamiento de erroresHay dos conceptos fundamentales: Corrección de errores: exige que el programa pueda ejecutarse. Suele utilizarse ensistemas que generán .EXE directamente, pues ahorra tiempo (permite encontrarerrores de ejecución a la vez que los de compilación). Recuperación de errores: sólo trata de evitar que el número de mensajes de error seademasiado grande y que el compilador/intérprete pueda seguir ejecutándosecorrectamente en instrucciones sucesivas.Corrección ortográficaErrores ortográficos típicos: Un carácter por otro. Un carácter perdido. Un carácter añadido. Dos caracteres intercambiados.Pueden comprobarse sólo los errores anteriores, lo que acelera el proceso.Correcciones posibles: Análisis sintácticoo Si se espera una palabra reservada y aparece un identificador, buscar lapalabra reservada más parecida al identificador.o Deshacer errores de concatenación. Por ejemplo, convertir begina en begina. Análisis semánticoo Si un identificador se utiliza en un contexto incompatible con su tipo, tratarde sustituirlo por otro de nombre parecido y tipo compatible con el contexto.
  • 4. o Si un identificador no ha sido referenciado o asignado, es candidato paracorrección ortográfica. Sólo en compiladores de dos pasos. En la tabla desímbolos se puede añadir como valor un par de contadores de uso yasignación.Todas las correcciones efectuadas deben ser cuidadosamente documentadas, para evitar queel programador se pierda al probar el programa.Corrección de errores sintácticosSi se detecta al analizar la cadenaxUydonde x,y en A* y U en A es el próximo símbolo a analizar, podemos intentar lo siguiente: Borrar U e intentarlo de nuevo. Insertar una cadena de terminales z entre x, U y empezar a analizar a partir de z. Insertar una cadena de terminales z entre x, U y empezar a analizar a partir de U,poniendo z en la pila (si es análisis bottom-up). Borrar símbolos del final de x e intentar de nuevo.No hacer nunca los dos últimos. Deshace la información semántica asociada.Ejemplo: tenemosif (...) { x=0; else ...El error se detecta en "else". Solución posible: añadir "}" delante de "else", analizandoif (...) { x=0; } else ...Recuperación de errores de compilaciónConviene tener una sola rutina de recuperación de errores separada del resto delcompilador. Evitar que un solo error produzca varios mensajes.Ejemplo: A[i1,i2,...,i3], donde A no es un "array". Al abrir el corchete nos dará unerror: "A no es un array". Al cerrar el corchete podría dar otro: "El número deíndices no coincide con el rango de A". Si se ha dado el primero, el segundo esinnecesario. Una solución: detectado el primer error, se sustituye la referencia a Apor una referencia a un identificador "fantasma". La rutina de recuperación deerrores podría ignorar los mensajes que se refieren al identificador fantasma. Evitar que un error idéntico repetido produzca varios mensajes. Ejemplo: { ... { int i; ... /* { */ ... } for (i=0; i<j; i++) { a=j-i+1; b=2*a+i; } } }Se nos olvida poner la tercera llave. La llave siguiente cierra el segundo bloque. "i"está indefinida en el primer bloque. El bucle "for" nos daría cinco veces el mensaje"variable i indefinida".Solución: crear un identificador llamado "i" en la tabla de símbolos con los atributoscorrectos. Esto elimina los mensajes subsiguientes. Atención: esto podría hacer queno se detecte un error real que nos interesaría atrapar. Otra alternativa sería imprimir
  • 5. un solo mensaje diciendo que el identificador "i" ha sido utilizado sin declaraciónprevia en las líneas número a,b,c...Recuperación de errores en un intérpreteHay que señalar el error y detener la ejecución, permitiendo al programador revisar las variables revisar el código modificar el código reanudar la ejecución saltarse líneas abandonar la ejecución del último programa abandonar totalmente la ejecucióny asegurarse de que todo sigue correctamente. En lenguaje simbólico se puedemanipular la pila de ejecución, salir automáticamente de rutinas pendientes, sincontinuar la ejecución, etc.http://www.lcc.uma.es/~galvez/ftp/tci/tictema3.pdfhttp://arantxa.ii.uam.es/~alfonsec/docs/compila9.htm