Pila Semántica en Un Analizador Sintáctico

February 4, 2019 | Author: Raúl Axel Mariscal | Category: Compiler, Parsing, Programming Language, Computer Science, Areas Of Computer Science
Share Embed Donate


Short Description

Pila semantica...

Description

TECNOLÓGICO NACIONAL DE MÉXICO INSTITUTO TECNOLÓGICO DE ACAPULCO

INGENIERÍA EN SISTEMAS COMPUTACIONALES

LENGUAJES Y AUTÓMATAS II

INVESTIGACIÓN: PILA SEMÁNTICA EN UN ANALIZADOR SINTÁCTICO

PROFESOR: MARIO GIMÉNEZ VÁZQUEZ

 ALUMNO: RAÚL AXEL MARISCAL ESCOBAR NO. CONTROL: 12320775

HORA: 7:00  – 8:00  AULA: 712

 ACAPULCO, GRO. GRO.

5 - SEPTIEMBRE - 2016 2016

PILA SEMÁNTICA EN UN ANALIZADOR SINTÁCTICO

Índice Definición y descripción ........................................................................................... 2 Características ........................................................................................................ 4 Ventajas .................................................................................................................. 5 Desventajas............................................................................................................. 6 Ejemplos (Como trabaja la pila semántica con las expresiones) ............................. 6 Bibliografía ............................................................................................................ 11

1|Página

PILA SEMÁNTICA EN UN ANALIZADOR SINTÁCTICO

Definición y descripción Las pilas semánticas son estructuras de datos que se utilizan generalmente para simplificar ciertas operaciones de programación. Estas estructuras pueden implementarse mediante arrays o listas enlazadas. También podemos definirlas como una colección de dato s a los cuales se les puede acceder mediante un extremo, que se conoce generalmente como tope. Las pilas semánticas tienen dos operaciones básicas:  

Push (para introducir un elemento) Pop (para extraer un elemento)

La pila semántica en un analizador sintáctico juega un papel fundamental en el desarrollo de cualquier analizador semántico. Dentro de cada elemento de la pila se guardan los valores que pueden tener una expresión. Como podemos entender un analizador sintáctico ascendente utiliza durante el análisis una pila semántica. En esta va guardando datos que le permiten ir haciendo las operaciones de reducción que necesita. Para incorporar acciones semánticas como lo es construir el árbol sintáctico, es necesario incorporar a la pila del analizador sintáctico ascendente otra columna que guarde los atributos de los símbolos que se van analizando.

Bottom up Es un principio de muchos años del estilo de programación utilizado para realizar una pila semántica. Los elementos funcionales de un programa no deben ser demasiado grandes. Si un cierto componente de un programa crece más allá de la etapa donde está fácilmente comprensible, se convierte en una masa de la complejidad que encubre errores tan fácilmente como una ciudad grande encubre a fugitivos. 2|Página

PILA SEMÁNTICA EN UN ANALIZADOR SINTÁCTICO

Top-down Este método consiste en dividir los problemas en subproblemas más sencillos para conseguir una solución más rápida. El diseño descendente es un método para resolver el problema que posteriormente se traducirá a un lenguaje comprensible por la computadora.

class TPila { public: TPila( ); TPila( TPila & ); ~TPila( ); TPila& operator=( TPila &); TItem& Cima( ); void Apilar( TItem& ); . . . private: struct TNodo { TItem dato; TNodo *sig; }; TNodo *fp; }; TPila::TPila( ) { fp = NULL; } void TPila::Desapilar( ) { TNodo *aux; aux = fp; fp = fp -> sig; delete aux;

Ejemplo de implementacion en codigo C++ de una pila semantica.

Reglas semánticas Son el conjunto de normas y especificaciones que definen al lenguaje de programación y están dadas por la sintaxis del lenguaje, las reglas semánticas asignan un significado lógico a ciertas expresiones definidas en la sintaxis del lenguaje. La evaluación de las reglas semánticas define los valores de los atributos en los nodos del árbol de análisis sintáctico para la cadena de entrada. Una regla semántica también puede tener efectos colaterales, por ejemplo, imprimir un valor o actualizar una variable global. 3|Página

PILA SEMÁNTICA EN UN ANALIZADOR SINTÁCTICO

Compatibilidad de tipos Durante la fase de análisis semántico, el compilador debe verificar que los tipos y valores asociados a los objetos de un programa se utilizan de acuerdo con la especificación del lenguaje.  Además, debe detectar conversiones implícitas de tipos para efectuarlas o insertar el código apropiado para efectuarlas, así como almacenar información relativa a los tipos de los objetos y aplicar las reglas de verificación de tipos.

Características Sus características fundamentales es que al extraer se obtiene siempre el último elemento que acabe de insertarse. Por esta razón también se conoce como estructuras de datos LIFO, una posible implementación mediante listas enlazadas seria insertando y extrayendo siempre por el principio de la lista. Una pila semántica ayuda al compilador a reconocer la estructura de una cadena de componentes léxicos.  Al decir pila semántica no se refiere a que hay varios tipos de pila, hace referencia a que se debe programar única y exclusivamente en un solo lenguaje, es decir, no podemos mezclar código de C++ con Visual Basic. Con el uso de las pilas semánticas es posible construir un árbol de análisis sintáctico, este raramente se construye como tal, sino que las rutinas semánticas integradas van generando el árbol de Sintaxis abstracta. Se especifica mediante una gramática libre de contexto. Para incorporar acciones semánticas como lo es construir el árbol sintáctico, es necesario incorporar a la pila del  parser   otra columna que guarde los atributos de los símbolos que se van analizando. En general una pila semántica hace posible al analizador sintáctico:  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. 4|Página

PILA SEMÁNTICA EN UN ANALIZADOR SINTÁCTICO



En definitiva, realiza casi todas las operaciones de la compilación. Este método de trabajo da lugar a los métodos de compilación dirigidos por sintaxis.

Ventajas  Al utilizar una pila semántica en un analizador sintáctico podemos obtener los siguientes beneficios: 













Detecta la validez semántica de las sentencias aceptadas por el analizador sintáctico. El analizador semántico suele trabajar simultáneamente al analizador sintáctico y en estrecha cooperación. Se entiende por semántica como el conjunto de reglas que especifican el significado de cualquier sentencia sintácticamente correcta y escrita en un determinado lenguaje. Las rutinas semánticas deben realizar la evaluación de los atributos de las gramáticas siguiendo las reglas semánticas asociadas a cada p roducción de la gramática. Permite agilizar la fase del análisis sintáctico en la que se trata de determinar el tipo de los resultados intermedios, comprobar que los argumentos que tiene un operador pertenecen al conjunto de los operad ores posibles, y si son compatibles entre sí, etc. El análisis semántico utiliza como entrada el árbol sintáctico detectado por el análisis sintáctico para comprobar restricciones de tipo y otras limitaciones semánticas y preparar la generación de código. Las rutinas semánticas suelen hacer uso de una pila que contiene la información semántica asociada a los operadores en forma de registros semánticos. Permiten guardar el estado de las variables o tokens en el momento en que se hace la llamada, para seguir ocupándolas al regresar del analizador. Su implementación suele ser relativamente fácil.

5|Página

PILA SEMÁNTICA EN UN ANALIZADOR SINTÁCTICO

Desventajas 









Los problemas de integración entre los subsistemas son sumamente costosos y muchos de ellos no se solucionan hasta que la programación alcanza la fecha límite para la integración total del sistema. Se necesita una memoria auxiliar que nos permita guardar los datos para poder hacer la comparación. Un grave error que puede ocurrir es tratar de eliminar un elemento de una pila semántica vacía. Este tipo de error se le conoce como subdesbordamiento (underflow ) y puede ocasionar que el analizador sintáctico se detenga repentinamente y con ello se aborte este proceso. El tamaño de la pila puede ser un problema, en caso de que esta crezca hasta tal punto de sobrepasar la memoria disponible. A veces un error provoca una avalancha de muchos errores que se solucionan con el primero.

Ejemplos (Como trabaja la pila semántica con las expresiones) 1. Sea la gramática simplificada que analiza las instrucciones de asignación: ::= id #PId := #RAs ::= + #RS | ::= id #PId | Ct #PCt

Se observará que hemos hecho uso de cuatro símbolos de acción: 







#PId: PUSH a la pila semántica el registro asociado al identificador. #PCt: PUSH a la pila semántica el registro asociado a la constante. #RS: Realizar suma: POP los dos registros superiores de la pila; comprobar que es posible sumarlos; realizar la suma (mediante una llamada al generador de código) o generar representación intermedia (si es una compilación en dos o más pasos); PUSH registro semántico del resultado en la pila semántica. #RAs: Realizar asignación: POP los dos registros superiores de la pila; comprobar que es posible realizar la asignación; realizarla (mediante una 6|Página

PILA SEMÁNTICA EN UN ANALIZADOR SINTÁCTICO

llamada al generador de código) o generar representación intermedia (si es una compilación en dos o más pasos). En los analizadores sintácticos top-down basados en gramáticas LL(1), la introducción de los símbolos de acción en las rutinas correspondientes es trivial. En los analizadores bottom-up basados en gramáticas SLR(1) es más delicado, pues los estados del análisis se mueven simultáneamente sobre varias reglas. Sólo en el momento de realizar una reducción sabemos exactamente dónde estamos. Por ello, se suele introducir la restricción de que los símbolos de acción deben estar situados únicamente al final de una regla. Cuando no se cumple esto (como en el ejemplo anterior) es trivial conseguirlo, introduciendo símbolos no terminales adicionales.

::= ::= ::= ::=

:= #RAs id #PId + #RS | id #PId | Ct #PCt

Poner un ejemplo del análisis sintáctico-semántico bottom-up de la instrucción A := B + 1. Otro ejemplo: instrucciones condicionales con las reglas ::= If #S2 then #S1 | If #S2 then else #S3 #S1 ::= If then #S1 | If then #S1 ::= #S2 ::= else #S3

2. Sea la expresión int a,b,c; a/(b+c^2)

El árbol sintáctico es: / --------| | a + --------| | b ^ --------| | c 2

7|Página

PILA SEMÁNTICA EN UN ANALIZADOR SINTÁCTICO

De la instrucción declarativa, la tabla de símbolos y el analizador morfológico obtenemos los atributos de los operandos: / --------| | a + int --------| | b ^ int --------| | c 2 int int

Propagando los atributos obtenemos: / int --------| | a + int int --------| | b ^ int int --------| | c 2 int int

Si la expresión hubiera sido a/(b+c^-2)

El árbol sintáctico sería el mismo, sustituyendo 2 por -2. Sin embargo, la propagación de atributos sería diferente: / real --------| | a + real int --------| | b ^ real int --------| | c -2 int int

En algún caso podría llegar a producirse error (p.e. si / representara sólo la división entera).

8|Página

PILA SEMÁNTICA EN UN ANALIZADOR SINTÁCTICO

Si la expresión hubiera sido int a,b,c,d; a/(b+c^d)

El árbol sintáctico sería el mismo, sustituyendo 2 por d. Sin embargo, la propagación de atributos sería incompleta: / {int,real} --------| | a + {int,real} int --------| | b ^ {int,real} int --------| | c d int int

El analizador semántico podría reducir los tipos inseguros al tipo máximo (real) o utilizar un tipo interno nuevo (ej. arit={int,real}, una unión). Lo anterior es un ejemplo de propagación bottom-up. La propagación top-down también es posible: lo que se transmite son las restricciones y los tipos de las hojas sirven de comprobación. Por ejemplo, si la división sólo puede ser entera, transmitimos hacia abajo la restricción de que sus operandos sólo pueden ser enteros. La implantación de todos los casos posibles de operación con tipos mixtos podría ser excesivamente cara. En su lugar, se parte de operaciones relativamente simples (ej. int+int, real+real) y no se implementan las restantes (ej. int+real, real+int), añadiendo en su lugar operaciones monádicas de cambio de tipo (ej. int->real). Esta decisión puede introducir ambigüedades. Por ejemplo, sea el programa real a; int b,c; a:=b+c

9|Página

PILA SEMÁNTICA EN UN ANALIZADOR SINTÁCTICO

Existen dos conversiones posibles: := real --------| | a + real real --------| | b c int int

:= real --------| | a + int real --------| | b c int int

El problema es que no tenemos garantía de que los dos procedimientos sean equivalentes. El segundo puede dar overflow   de la pila, el primero pérdida de precisión. La definición del lenguaje debe especificar estos casos. Las transformaciones posibles se pueden representar mediante un grafo cuyos nodos son los tipos de datos y cada arco indica una transformación. Dado un operando de tipo A que se desea convertir al tipo B, se trata de encontrar una cadena de arcos que pase de A a B en el grafo anterior. Podría haber varios grafos, cada uno de los cuales se aplicará en diferentes condiciones, por ejemplo, uno para las asignaciones, otro para las expresiones, etc.

3. Con la producción A!i:=E, se asocia una acción de agregar el valor de E a i.

10 | P á g i n a

PILA SEMÁNTICA EN UN ANALIZADOR SINTÁCTICO

Bibliografía 1.  Alfred V. Aho, J. D. (2000). Compiladores Principios, tecnicas y herramientas. Mexico: Addison Wesley. 2.  Alfred V. Aho, M. S. (2008). Compiladores: principios, técnicas y herramientas. Mexico: Pearson Adisson Wesley. 3. N., E. W. (2006). Compiler Construction. New York: Addison Wesley. 4. Terry, P. (1997). Compilers and Compiler Generators: an introduction with C++. Boston: International Thomson Computer Press.

11 | P á g i n a

View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF