Tabla de Símbolos

31
Tabla de Símbolos Universidad De San Carlos De Guatemala. Organización de Lenguajes y Compiladores 1. Segundo Semestre 2010

description

Definición de la tabla de símbolosObjetivos de la tabla de símbolosCompilador de una pasadaCompilador de varias pasadasContenidos de la tabla de símbolosOperaciones de la tabla de símbolosOperación con lenguajes estructurados de bloques.

Transcript of Tabla de Símbolos

Page 1: Tabla de Símbolos

Tabla de Símbolos

Universidad De San Carlos De Guatemala.Organización de Lenguajes y

Compiladores 1.Segundo Semestre 2010

Page 2: Tabla de Símbolos

Índice

Definición de la tabla de símbolos Objetivos de la tabla de símbolos Compilador de una pasada Compilador de varias pasadas Contenidos de la tabla de símbolos Operaciones de la tabla de símbolos Operación con lenguajes estructurados

de bloques.

Page 3: Tabla de Símbolos

Objetivos:

El estudiante comprenda el funcionamiento de la tabla de símbolos.

El estudiante pueda implementar la tabla de símbolos en una o varias pasadas del compilador.

El estudiante entienda que estructura de datos debe utilizar al realizar una tabla de símbolos.

El estudiante conozca los diferentes atributos implementa la tabla de símbolos.

Page 4: Tabla de Símbolos

Definición de la tabla de símbolos

La tabla de símbolos es una estructura de datos que nos permite realizar operaciones de inserción, búsqueda y eliminación de información en varias construcciones del lenguaje fuente, la cual es analizada por el compilador originándose un código objeto.

Page 5: Tabla de Símbolos
Page 6: Tabla de Símbolos

Definición de la tabla de símbolos

Mediante la tabla de símbolos un compilador (la mayoría de lo dicho sería aplicable también a un intérprete) puede, dependiendo de la fase en que se encuentre, determinar: › Si un identificador es una variable, conociendo su tipo

o la dirección relativa que se le ha asignado. › Si una variable o un procedimiento ha sido declarado

antes de utilizarse la primera vez. › Si un identificador es una palabra reservada y por

tanto no debe permitir su redefinición. › Los identificadores que son visibles dependiendo de su

ámbito y el bloque que se está procesando en cada momento.

Page 7: Tabla de Símbolos

Objetivos de la Tabla de Símbolos:

Las Tablas de Símbolos (TS) son estructuras de datos que almacenan toda la información de los identificadores del lenguaje fuente.

Las misiones principales de la TS en el proceso de traducción son: › Colaborar con las comprobaciones semánticas. › Facilitar ayuda a la generación de código.

Habitualmente los elementos del lenguaje que requieren el uso de la TS son los distintos tipos de identificadores del lenguaje (nombres de variables, de objetos, de funciones, de etiquetas, de clases, de métodos, etc.).

Page 8: Tabla de Símbolos

Objetivos de la Tabla de Símbolos:

La información relativa a un elemento del lenguaje se almacena en los denominados atributos de dicho elemento.

Así ejemplos de atributos tales como nombre, tipo, dirección relativa en tiempo de ejecución, dimensiones de los arrays, número y tipo de los parámetros de procedimientos, funciones y métodos, tipos de acceso a los elementos de una clase (public, private, protected…), etc. se recogen y se guardan en la TS.

Page 9: Tabla de Símbolos

Compiladores de una pasada:

Donde el análisis léxico, sintáctico, semántico y la generación de código se realizan en una pasada, es decir, se explora el texto fuente sentencia a sentencia (o bloques de sentencias) realizándose los tres análisis y la generación de código.

Esta estrategia tiene dos ventajas: a. Reduce la complejidad de la gramática para

análisis sintáctico. b. Permite una mejor especificación de los

errores sintácticos por el compilador gracias a la utilización de construcciones menos generales.

Page 10: Tabla de Símbolos

Compiladores de una pasada:

Page 11: Tabla de Símbolos

Compiladores de Varias Pasadas:

En un compilador de varias pasadas, tal como el de la Figura 1, la TS se crea durante el análisis léxico y sintáctico (pasada 1). En los compiladores modernos la TS se crea durante el primer recorrido del árbol AST, una vez creado éste mediante al analizador sintáctico (pasada 2).

Durante la fase de análisis sintáctico no se usan procedimientos que manejen la TS, excepto que sean necesarias comprobaciones semánticas para resolver ambigüedades sintácticas.

Page 12: Tabla de Símbolos

Compiladores de Varias Pasadas:

No es hasta las fases de análisis semántico y de generación de código cuando vuelve a utilizarse la TS, pues en estas fases ocurre que alguno de los atributos asociados a un identificador se les pueda asignar un valor en la TS.

Este código se comprueba por el analizador semántico y se usa en la fase de generación de código para la implementación de las instrucciones en código objeto.

Page 13: Tabla de Símbolos
Page 14: Tabla de Símbolos

Contenido de la tabla de símbolos:

Una TS se puede definir como una estructura de datos organizada en función de los identificadores que aparecen en el programa fuente.

Aunque su nombre parece indicar una estructuración en una tabla no es necesariamente ésta la única estructura de datos utilizada, también se emplean árboles, pilas, tabla hash, etc.

Page 15: Tabla de Símbolos

Listas o tablas sin orden

Una de las estructuras de datos más sencillas que pueden utilizarse es una lista o una tabla (vector) en la que no se mantiene orden, de manera que las operaciones pueden ejecutarse con los siguientes órdenes de eficiencia:

Page 16: Tabla de Símbolos

Listas o tablas sin orden Inserción: O(1) si se inserta siempre al final de la

lista/vector sin comprobación previa de si la clave existe o no.

Búsqueda: Al no haber orden la búsqueda es necesariamente secuencial, por lo que el orden de eficiencia será O(1) en el mejor de los casos y O(n) en el peor (siendo n el número de símbolos existentes). La eficiencia esperada sería, por tanto, de O(n+1)/2.

Actualización y Borrado: Puesto que son operaciones que precisan una búsqueda previa, en principio tendríamos una eficiencia esperada de O(n+1)/2.

Teniendo en cuenta que una tabla de símbolos contendrá habitualmente varios cientos de claves, incluso miles en los programas grandes, salta a la vista que esta estructura de datos no resulta adecuada salvo en los casos más sencillos

Page 17: Tabla de Símbolos

Listas o tablas con orden En lugar de usar listas o vectores sin orden, podría

utilizarse la clave para mantener los elementos ordenados a fin de mejorar la eficiencia en la búsqueda de símbolos. La existencia de orden permitiría utilizar un algoritmo de búsqueda dicotómica o binaria, cuyo orden de eficiencia es logarítmico: O(log n).

Page 18: Tabla de Símbolos

Arboles Se trata de una estructura con una eficiencia

aceptable para las distintas operaciones que se necesitan siempre que se mantenga equilibrado, ya que de lo contrario pueden terminar convirtiéndose en una lista y la búsqueda sería secuencial. Los más apropiados serían los árboles AVL o los árboles rojo-negro.

Page 19: Tabla de Símbolos

Tablas hash Las técnicas de hashing hacen posible mantener

tablas de datos con acceso por clave con un orden de eficiencia teórico de O(1) para todas las operaciones, lo que les hace ideales para el mantenimiento de una tabla de símbolos. Ese orden de eficiencia teórico se alcanzará en mayor o menor medida dependiendo del algoritmo de hashing que se emplee y de que éste resulte adecuado para el tipo de claves utilizadas.

El uso de una tabla hash, resultará mucho más eficiente a la hora de realizar búsquedas en la tabla de símbolos, así como a la hora de insertar, actualizar o borrar. El tiempo no dependerá del tamaño de la tabla, es decir, de lo grande que sea el programa a compilar, sino que se mantendrá aproximadamente constante.

Page 20: Tabla de Símbolos
Page 21: Tabla de Símbolos

Contenido de la tabla de símbolos:

Lo que la estructura debe permitir es establecer un homomorfismo entre los ámbitos de utilización de los símbolos en el programa fuente y el modo en que aparecen en las sucesivas búsquedas en la tabla. Para ello debe manejar diferentes contextos de búsqueda que imiten los diferentes tipos de bloques del lenguaje fuente que se compila.

Los símbolos se guardan en la tabla con su nombre y una serie de atributos opcionales que dependerán del lenguaje y de los objetivos del procesador. Este conjunto de atributos almacenados en la TS para un símbolo determinado se define como registro de la tabla de símbolos (symbol-table record)

Page 22: Tabla de Símbolos

Contenido de la tabla de símbolos:

La organización de la TS variará según las limitaciones de memoria y tiempo de acceso donde se implemente el compilador. La lista siguiente de atributos no es necesaria para todos los compiladores, sin embargo cada uno de ellos se puede utilizar en la implementación de un compilador particular.

Page 23: Tabla de Símbolos

Contenido de la tabla de símbolos:

Nombre del identificador. Categoría: Determina a qué pertenece el símbolo

asociado. Tipo: En el caso de las variables, establece el tipo de

información que con-tendrán. Si el símbolo es una función, este mismo atributo indicaría el tipo de valor devuelto.

Argumentos: Para los procedimientos, funciones o métodos indicará la lista de parámetros que precisa y sus tipos.

Posición: Para las variables es habitual contar con una posición relativa de memoria asociada. Los intérpretes utilizarán dicha posición a medida que eje-cuten el código para leer y modificar el valor.

Page 24: Tabla de Símbolos

Contenido de la tabla de símbolos:

Valor: Si el símbolo es una constante este atributo contendría el valor que re-presenta.

Ámbito: En los lenguajes orientados a objetos y con estructura de bloques pueden existir múltiples símbolos con el mismo identificador en ámbitos dis-tintos, sirviendo este atributo para determinar el ámbito a que pertenecen.

Page 25: Tabla de Símbolos

Contenido de la tabla de símbolos:

Dependiendo de las características de cada lenguaje, el compilador puede almacenar directamente en la tabla de símbolos la secuencia de caracteres que componen cada identificador o, en su lugar, mantener una estructura paralela. En el primer caso es obvio que existe una longitud máxima para los identificadores, además de un desperdicio de espacio.

La alternativa, utilizada por la mayoría de los compiladores actuales, consiste en guardar los identificadores en una estructura paralela, almacenando en la propia tabla de símbolos únicamente un puntero a la posición del identificador y su longitud, por ejemplo:

Page 26: Tabla de Símbolos
Page 27: Tabla de Símbolos

Operaciones con la tabla de símbolos:

Las principales operaciones de la tabla de símbolos las definimos así:

Inserción: Almacena información proporcionada por las declaraciones de nombre cuando estas son procesadas.

Búsqueda: Recupera la información asociada con un nombre cuando este se utiliza en una declaración o el código asociado.

Page 28: Tabla de Símbolos

Operaciones con Lenguajes Estructurados en Bloques

Definiremos en este apartado como lenguajes estructurados en bloques a todos los que tiene algún tipo de bloque que defina ámbitos de utilización y visión de identificadores, por tanto están incluidos en este apartado también los lenguajes orientados a objetos y no sólo los lenguajes estructurados.

Los lenguajes estructurados en bloques tienen dos operaciones adicionales llamadas set y reset.

La operación de set se utiliza cuando el compilador detecta el comienzo de un bloque o módulo en el cual se pueden declarar identificadores locales o automáticos.

La operación complementaria reset, se utiliza cuando se detecta el final del bloque o módulo. La naturaleza y necesidad de estas operaciones se muestra en el siguiente fragmento de programa:

Page 29: Tabla de Símbolos
Page 30: Tabla de Símbolos

Operaciones con Lenguajes Estructurados en Bloques

En el fragmento del programa anterior, la variable X se declara en más de un bloque y en cada uno de estos bloques X tiene distintos atributos. En un lenguaje anidado es necesario asegurarse, en cada caso, que el nombre de la variable se asocia con un conjunto único de atributos o de huecos en la TS. La solución de este problema son las operaciones set y reset.

Mediante el uso de subtablas se soluciona la ambigüedad provocada por la búsqueda de identificadores del mismo nombre en distintos bloques.

Page 31: Tabla de Símbolos

Con esta inspección en orden inverso de creación se garantiza que la primera X que aparezca será la del bloque más cercano al uso de dicha variable que es lo que semánticamente pretende el compilador. Es importante notar que no está permitido usar dos variables con el mismo nombre en mismo bloque, de esta forma queda resuelto el problema de la ambigüedad de los nombres de las variables.

Con la salida del bloque, la operación reset suprime las entradas a la subtabla del bloque que se acaba de cerrar. Esta supresión de las entradas significa que las variables del bloque recién acabado no tienen validez en el resto del programa.