You are on page 1of 31

Tabla de Símbolos

Universidad De San Carlos De Guatemala.


Organización de Lenguajes y Compiladores 1.
Segundo Semestre 2010
Í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.
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.
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.
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.
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.).
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.
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.
Compiladores de una pasada:
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.
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.
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.
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:
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
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).
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.
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.
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)
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.
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.
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.
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:
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.
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:
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.
 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.

You might also like