






Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Prepara tus exámenes
Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Prepara tus exámenes con los documentos que comparten otros estudiantes como tú en Docsity
Los mejores documentos en venta realizados por estudiantes que han terminado sus estudios
Estudia con lecciones y exámenes resueltos basados en los programas académicos de las mejores universidades
Responde a preguntas de exámenes reales y pon a prueba tu preparación
Consigue puntos base para descargar
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Comunidad
Pide ayuda a la comunidad y resuelve tus dudas de estudio
Descubre las mejores universidades de tu país según los usuarios de Docsity
Ebooks gratuitos
Descarga nuestras guías gratuitas sobre técnicas de estudio, métodos para controlar la ansiedad y consejos para la tesis preparadas por los tutores de Docsity
En este documento especificaremos los detalles de un analizador sintáctico
Tipo: Transcripciones
1 / 12
Esta página no es visible en la vista previa
¡No te pierdas las partes importantes!
Es esencial que el proceso de análisis no se detenga al primer error encontrado ya que así podrá informar al usuario en un solo informe de todos los errores generados. Aparte de esta función principal, el párser es la unidad que guía todo el proceso, o casi todo, de la compilación. Esto es así porque por un lado va solicitando al léxer los tokens y al mismo tiempo va dirigiendo el proceso de análisis semántico y generación de código intermedio. Por lo que muchas veces se le llama al proceso de análisis semántico y generación de código intermedio, traducción dirigida por la sintaxis.
Si el compilador solo necesita procesar el programa correcto, su diseño e implementación se simplificarán enormemente. Pero los programadores a menudo escriben programas malos, por lo que un buen compilador debería ayudar a los programadores a identificar y localizar errores. Sorprendentemente, aunque los errores son tan comunes, pocos lenguajes están diseñados teniendo en cuenta el manejo de errores. Si el lenguaje hablado requiere la misma alta precisión sintáctica que un lenguaje de programación, entonces esta civilización será completamente diferente. La mayoría de las especificaciones del lenguaje de programación no describen cómo debería responder el compilador a los errores; la respuesta queda en manos del diseñador del compilador. La consideración temprana del manejo de errores puede simplificar la estructura del compilador y mejorar su respuesta a los errores. Como todos sabemos, los programas pueden Ilustración 1 : Función del analizador sintáctico
contener muchos tipos de errores. Por ejemplo, el error puede ser: Léxicos, como redactar mal un identificador. palabra clave u operador. Sintácticos, como una expresión aritmética con paréntesis no equilibrados. Semánticos, como un operador aplicado a un operando incompatible. Lógicos, como una llamada infinitamente recursiva. Tenemos algunas tácticas para arreglar errores, una vez detectaos. Ignorar el problema (Panic mode): Se apoya en desconocer lo demás del ingreso hasta llegar a una condición de estabilidad. Una condición tal se genera una vez que estamos un token particular (por ejemplo, un ‘;’ o un ‘END’). A partir de este punto se sigue analizando comúnmente. Recuperación a nivel de frase: Aspira recobrar el error una vez descubierto. En la situación anterior, ejemplificando, podría haber sido lo suficientemente inteligente como para insertar el token ‘;’. Se debe tener cuidado con este procedimiento, puesto que puede ofrecer sitio a recuperaciones infinitas. Reglas de producción adicionales para el control de errores: La gramática se puede incrementar con las normas que Ilustración 2 : Modo Pánico
Muchas construcciones de los lenguajes de programación tienen una estructura inherentemente recursiva que se puede definir mediante gramáticas independientes del contexto. Por ejemplo, se puede tener una proposición condicional definida por una regla como: Si S1 yS2 son proposiciones y E es una expresión, entonces “if E then S1 else S2” es una proposición. No se puede especificar esta forma de proposición condicional usando la notación de las expresiones regulares. Por otro lado, utilizando la variable sintáctica “prop” para denotar la clase de las proposiciones y “expr” para la clase de las expresiones, ya que se puede expresar usando la producción gramatical.
El cálculo de la gramática se basa en el concepto de derivación. A partir de una cadena que consta solo del símbolo de inicio, las reglas de P se aplican repetidamente hasta que se alcanza una cadena que consiste solo en el terminador. Para aplicar una regla, solo necesita encontrar la parte izquierda de la regla en la cadena actual y reemplazarla con la parte derecha correspondiente. Por ejemplo, sea la gramática: G = ({(s), (E)}, {id,+,*},P,(S)), com
Sigamos con la gramática G: (S) (E) (E) (E)+(E) (E) (E)(E) (E) id La sentencia idid+id, tiene distintas derivaciones: Sin embargo, en cierto sentido, todas estas derivaciones representan la misma "estructura". De alguna manera nos transmitieron la idea de que se agregó el producto de los dos primeros identificadores Y tercero. Podemos expresar esto de manera compacta usando un árbol como el siguiente: Esto se denomina árbol de análisis sintáctico o árbol derivado. Intuitivamente, lo que hacemos "Paralelo" significa las reglas necesarias para derivar la cadena de entrada. La raíz es El símbolo inicial de la gramática y cada nodo interno representa una producción: está marcado Con el símbolo no terminal, (A) y Ilustración 4 : Árbol de análisis
Gramáticas con ciclo: S:: = A S:: = a A:: = S Gramáticas con alguna regla de la forma: E:: = E ……E Gramática con unas reglas que ofrezcan caminos alternativos entre dos puntos. Por ejemplo: S:: = B S:: = C B:: = C Producciones recursivas en las que las variables no recursivas de la producción puedan derivar a la cadena vacía. Por ejemplo. S:: = A B S S:: = s A:: = a | € B:: = b | € Símbolos no terminales que puedan derivar a la cadena vacía y a la misma cadena de terminales, y que aparezcan juntas en la parte derecha de una regla o en alguna forma sentencial. Por ejemplo.
Los errores sintácticos son esos que se generan en el instante de redactar el programa en el lenguaje de programación de elevado grado y que no cumplen las normas gramaticales de comentado lenguaje de programación de elevado grado y que no cumplen las normas gramaticales de hablado lenguaje de programación. Dichos errores son principalmente detectados por el propio compilador, debido a que éste solamente traduce programas que se encuentren “bien escritos”. Por consiguiente, un programa que contenga errores sintácticos no va a poder ser jamás compilado. En forma de ejemplo, un error sintáctico
bastante típico en el lenguaje Pascal es olvidarse de redactar el signo “;” para dividir las sentencias del programa. Otro error sintáctico bastante común es redactar mal alguna palabra reserva del lenguaje, ejemplificando, redactar “POGRAM” en vez de “PROGRAM” al principio de un programa Pascal. Generalmente, dichos errores son de forma fácil detectados y enmendados. Los errores de ejecución son esos que se detectan a lo largo de la ejecución del código objeto y, como resultado, abortan la ejecución del mismo. Una vez que un programa puede ocasionar errores de ejecución frente a un acceso definido, se plantea que es poco robusto. La solidez de un programa sugiere puesto que la función de un programa para continuar en funcionamiento ante entradas “erróneas”. Los menajes que logren producirse en el instante de la interrupción tienen la posibilidad de contribuir a comprender el error. Dichos mensajes son integrados en el propio código objeto por el compilador.
una cadena de entrada w con el delimitador $ por la derecha. una tabla M de análisis sintáctico LL para una gramática G Salida: una derivación por la izquierda de w, en caso de que pertenezca a L(G), o la indicación de error en caso contrario. Método: Al inicio, la pila tiene $S, estando S -el axioma de G- en la cumbre, y la cadena de acceso w$ está pendiente de ser analizada. El analizador hace entonces el siguiente programa: p señala al primer token de la cadena w$ repeat sea X el símbolo de la cima de la pila y a el símbolo apuntado por p if X es un terminal then if X = a then begin extraer X de la pila avanzar p