-
1. ANLISIS SEMNTICO INTRODUCCIN El anlisis semntico dota de un
significado coherente a lo que hemos hecho en el anlisis sintctico.
El chequeo semntico se encarga de que los tipos que intervienen en
las expresiones sean compatibles o que los parmetros reales de una
funcin sean coherentes con los parmetros formales. Se divide en dos
categoras:
Anlisis de un programa que requiere las reglas del lenguaje de
programacin para establecer su exactitud y garantizar una ejecucin
adecuada.
Anlisis realizado por un compilador para mejorar la eficiencia
de ejecucin del programa traducido.
La especificacin de la semntica puede realizarse de dos
formas:
Lenguaje natural Especificacin formal: Semntica Operacional,
semntica denotacional, semntica
Axiomtica, Gramticas con Atributos. Para que hacer un anlisis
semntico?
Asegurarnos que el programa cumple con la definicin del lenguaje
de programacin.
Proveer mensajes de error tiles al usuario. El Analizador
Semntico finaliza la fase de Anlisis del compilador y comienza la
fase de Sntesis, en la cual se comienza a generar el cdigo objeto.
Hay dos notaciones o mtodos para asociar reglas semnticas con
producciones:
Las definiciones dirigidas por las sintaxis. o Son
especificaciones de lto nivel para traducciones. o Ocultan muchos
detalles de la implementacin y
-
o No es necesario que el usuario especifique explcitamente el
orden en el que tiene lugar la traduccin.
Los esquemas de traduccin o Indican el orden en que se deben
evaluar las reglas semnticas dejando
visibles algunos detalles de la implementacin. Conceptualmente
para ambas notaciones,
Se analizan sintcticamente la cadena de componentes lxicos de
entrada, se construye el rbol para evaluar las reglas semnticas en
sus nodos.
La evaluacin de las reglas semnticas puede generar cdigo,
guardar informacin en una tabla de smbolos, emitir mensajes de
error o realizar otras actividades
La traduccin de las cadenas de componentes lxicos es el
resultado obtenido al evaluar las reglas semnticas.
Hay casos especiales en que se puede implementar en una sola
pasada, evaluando directamente en el anlisis sintctico, sin
construir explcitamente un rbol de anlisis sintctico o un grafo que
muestre las dependencias para los atributos.
1.1. ARBOLES DE EXPRESIONES. Hay determinadas caractersticas de
los lenguajes de programacin que no pueden ser modeladas mediante
gramticas incontextuales y que es necesario comprobar en una fase
posterior al anlisis sintctico. Por otro lado, las fases
posteriores de la compilacin o interpretacin necesitan una
representacin de la entrada que les permita llevar a cabo sus
funciones de manera adecuada. Estas dos vertientes, deteccin de
errores y representacin de la informacin, estn muy relacionadas y
se solapan en la prctica. El uso de rboles de anlisis sintctico
como representacin intermedia permite que la traduccin se separe
del anlisis sintctico. Las rutinas de traduccin invocadas durante
el anlisis sintctico deben activarse con dos clases de
limitaciones. La primera, una gramtica que resulte adecuada para le
anlisis sintctico puede no reflejar la estructura jerrquica natural
de las construcciones del lenguaje. La segunda, el mtodo de anlisis
sintctico restringe el orden en que se consideran los nodos de un
rbol de anlisis
-
sintctico. Pues este orden puede no coincidir con el orden en
que se va disponiendo de la informacin sobre una construccin.
Supongamos, por ejemplo, que nuestro lenguaje permite asignaciones
segn la regla
(Asignacin) id:=(Expresin); Generalmente se imponen ciertas
restricciones, en este caso, estas podran ser:
El identificador de la parte izquierda debe estar declarado
previamente. El tipo de la expresin debe ser compatible con el del
identificador.
El analizador semntico deber comprobar que estas dos
restricciones se cumplen antes de declarar que la sentencia de
asignacin est bien formada. Pero sucede que la informacin necesaria
para comprobarlas es til tambin para generar cdigo. Esto quiere
decir que si tuviramos una separacin estricta entre las fases del
compilador, para generar cdigo deberamos volver a mirar el
identificador para saber a que objeto (variable, funcin, constante,
etc.) corresponde y qu tipo tiene y tambin deberamos volver a
comprobar los tipos de la expresin para generar el cdigo adecuado.
Por otro lado, aunque en teora el rbol de anlisis sera suficiente
para fases posteriores de la compilacin o interpretacin, es una
representacin que contiene mucha informacin redundante. Por
ejemplo, el rbol correspondiente a la expresin a:= b+c; bien podra
tener el aspecto del rbol de la izquierda, cuando el de la derecha
contiene esencialmente la misma informacin y resulta ms cmodo para
trabajar:
-
El segundo rbol se conoce como rbol de sintaxis abstracta. Como
hemos comentado, durante el anlisis semntico se recoge una serie de
informaciones que resultan de utilidad para fases posteriores.
Estas informaciones se pueden almacenar en el rbol: rbol de
Sintaxis Abstracto: Es una forma condensada de un rbol de anlisis
sintctico, til para representar construcciones del lenguaje:
Recoge toda la informacin sintctica y semntica. Elimina los
smbolos que no aportan significado. Los nodos reflejan los datos
asociados a cada smbolo. El objetivo de las acciones semnticas es
construir este rbol.
Por ejemplo la produccin S if B then S1 else S2 puede aparecer
en un rbol sintctico como
If-then-else
B S1 S2 La construccin de rboles sintcticos para expresiones es
similar a la traduccin de la expresin a una forma postfija. Se
construyen subrboles para las subexpresiones creando un nodo para
cada operador y cada operando. Los hijos de un nodo de un operador
son las races de los nodos que representan las subexpresiones que
constituyen los operandos de dicho operador. Se puede implantar
cada nodo en un rbol sintctico como un registro con varios campos.
Algunas de las operaciones utilizadas son:
-
1. hazNodo(op,izquierda,derecha): crea un nodo para un operador
con etiqueta op y dos campos que contienen apuntadores a izquierda
y derecha.
2. hazHoja(id,entrada): crea un nodo para un identificador con
etiqueta id y un campo que contiene entrada, que es un apuntador a
la entrada de la tabla de smbolos para el identificador
3. hazHoja(num,val): crea un nodo para un nmero con etiqueta num
y un campo que contiene val, el valor del nmero.
Por ejemplo, para la expresin a-4+c, p1,p2,p3, , son apuntadores
a nodos y entrada y entradac son apuntadores a las entradas de la
tabla de smbolos para los identificadores a y c
respectivamente.
1. P1: hazHoja(id, entrada) 2. P2: hazHija(num, 4) 3. P3:
hazNodo(-, p1, p2) 4. P4: hazHoja(id, entradac) 5. P5: hazNodo(+,
p3, p4)
El rbol se construye de abajo hacia arriba.
1.2 ACCIONES SEMNTICAS DE UN ANALIZADOR SINTCTICO
a. Comprobacin esttica: El compilador debe comprobar si el
programa fuente sigue tanto las convenciones
sintcticas como las semnticas del lenguaje fuente. Garantiza la
deteccin y comunicacin de algunas clases de errores de
programacin. Dependiendo del tipo de sentencias, las acciones
semnticas pueden agruparse en:
o Sentencias de Declaracin: Completar la seccin de tipos de la
Tabla de Smbolos.
+
- id
id num 4
+
La entrada para c La entrada para a
-
o Sentencias ejecutables: Realizar comprobaciones de tipos entre
los operandos implicados.
o Funciones y procedimientos: Comprobar el nmero, orden y tipo
de los parmetros actuales en cada llamada a una funcin o
procedimiento.
o Identificacin de variables: Comprobar si un identificador ha
sido declarado antes de utilizarlo.
o Etiquetas: Comprobar si hay etiquetas repetidas y validacin. o
Constantes: Comprobar que no se utilicen en la parte izquierda de
una
asignacin. o Conversiones y equivalencias de tipo: Verificacin.
o Sobrecarga de operadores y funciones: Detectar y solventar.
Los ejemplos de comprobacin esttica incluyen: o Comprobacin de
tipos: Un compilador debe informar de un error si se aplica un
operando a un
operador incompatible. o Comprobaciones del flujo del control:
Las proposiciones que hacen que el flujo de control abandone
una
construccin deben tener algn lugar a donde transferir el flujo
de control.
o Comprobaciones de unicidad: Hay situaciones en las que un
objeto solo puede definirse una vez
exclusivamente. Las etiquetas de una sentencia case no deben
repetirse, declaraciones
de objetos, etc. o Comprobaciones relacionadas con nombre: En
ocasiones, el mismo nombre debe aparecer dos o ms veces.
o Adems de comprobar que un programa cumple con las reglas de la
gramtica, hay que comprobar que lo que se quiere hacer tiene
sentido.
o Esta fase tambin modifica la tabla de smbolos y suele estar
mezclada con la generacin de cdigo intermedio.
o Las gramticas independientes del contexto (G2) no son
suficientes para realizar el anlisis semntico. Por ejemplo, no hay
forma de comprobar si una variable ha sido definida ya, o si existe
una determinada etiqueta.
o Es necesario definir un tipo de gramtica ms rica como las
gramticas de atributo: Son gramticas G2 a las que se aaden
atributos y reglas de evaluacin de atributos (funciones/reglas
semnticas)
b. Comprobacin dinmica
-
Se realiza al ejecutar un programa objeto Para que se pueda
realizar, el cdigo objeto debe cargar el tipo de un elemento
junto con el valor de dicho elemento. 1.3 COMPROBACIN DE TIPOS
un comprobador de tipos se asegura de que el tipo de una
construccin coincida con su contexto, por ejemplo el operador
aritmtico mod debe asegurarse que los operandos sean de tipo
entero, etc.
Sistemas de tipos Es una serie de reglas para asignar
expresiones de tipos a las distintas partes de un programa. Un
comprobador de tipos implanta un sistema de tipos. El diseo de un
comprobador de tipos se basa en informacin acerca de las
construcciones sintcticas del lenguaje, la nocin de tipos a las
construcciones del lenguaje. Expresin de tipo Es un tipo bsico o se
forma aplicando un operador llamado constructor de tipos a otras
expresiones de tipos. Los conjuntos de tipos y constructores bsicos
dependen del lenguaje que deba comprobarse. Algunas definiciones de
expresiones de tipos son
Un tipo bsico es una expresin de tipo. Entre los tipos bsicos se
encuentran boolean, char, integer, real y vaco. Un tipo bsico
especial, error_tipo, sealar un error durante la comprobacin de
tipos.
El nombre de un tipo es una expresin de tipo. Un constructor de
tipos aplicado a expresiones de tipos es una expresin de tipos.
Los constructores incluyen: o Matrices: T indica el tipo de una
matriz con elementos de tipo T y
conjuntos de ndices I (generalmente enteros)
-
o Productos: si T1 y T2 son expresiones de tipo, entonces su
producto cartesiano es una expresin de tipos.
o Registros: la diferencia entre un producto y un registro es
que los campos de un registro tienen nombre. El constructor del
registro se aplica a una tupla formada por el nombre y el tipo del
campo.
o Apuntadores: si T es un apuntador de tipo entonces el puntero
es una expresin de tipos que indica el tipo apuntador a un objeto
de tipo T.
o Funciones: una funcin transforma elementos de un conjunto
(dominio), a elementos de otro conjunto (rango).
Las expresiones de tipo pueden contener variables cuyos valores
son expresiones de tipo.
Recuperacin de errores La comprobacin de tipos tiene la
capacidad de descubrir errores en los programas por lo que debe
realizar algo razonable cuando se descubre un error. 1.4. PILA
SEMNTICA EN UN ANALIZADOR SINTCTICO. El diseo ascendente tambin
conocido como anlisis sintctico por desplazamiento o reduccin (LR)
se refiere a la identificacin de aquellos procesos que necesitan
computarizarse con forme vayan apareciendo, su anlisis como sistema
y su codificacin, o bien, la adquisicin de paquetes de software
para satisfacer el problema inmediato. El diseo ascendente puede
ser aplicado a travs de la definicin de atributos sintetizados. El
analizador puede conservar en su pila los valores de los atributos
sintetizados asociados con los smbolos gramaticales, siempre que se
haga una reduccin se calculan los valores de los atributos
sintetizados a partir de los atributos que aparecen en la pila para
los smbolos gramaticales del lado derecho para la produccin que
reduce. Un analizador LR utiliza una pila para guardar los valores
de los atributos sintetizados. Se pueden utilizar campos
adicionales en la pila del analizador para guardar los valores de
los atributos sintetizados.
-
P. E. Podemos considerar el siguiente cdigo que corresponde a la
definicin dirigida por la sintaxis de la calculadora de escritorio.
1.5. ESQUEMA DE TRADUCCIN. Es una gramtica independiente de
contexto en la que se asocian atributos con los smbolos
gramaticales y se insertan acciones semnticas encerradas entre
llaves { } dentro de los lados derechos de las producciones. Los
esquemas de traduccin pueden tener tanto atributos sintetizados
como heredados. Cuando se disea un esquema de traduccin, se deben
respetar algunas limitaciones para asegurarse de que el valor de un
atributo est disponible cuando una accin se refiera a l. Estas
limitaciones, motivadas por las definiciones con atributos por la
izquierda, garantizan que las acciones no hagan referencia a un
atributo que an no haya sido calculado. El ejemplo ms sencillo
ocurre cuando slo se necesitan atributos sintetizados, en este
caso, se puede construir el esquema de traduccin creando una accin
que conste de una asignacin para cada regla semntica y colocando
esta accin al final del lado derecho de la produccin asociada.
Podemos decir que un esquema de traduccin consta de:
Una gramtica incontextual que le sirve de soporte. Un conjunto
de atributos asociados a los smbolos terminales y no terminales. Un
conjunto de acciones asociadas a las partes derechas de las
reglas.
Hay dos tipos de esquemas de traduccin:
EDT slo con atributos sintetizados: o Su valor se calcula en
funcin de los atributos de los nodos hijos.
-
o Acciones al final de la produccin EDT con atributos
sintetizados y heredados:
o Su valor se calcula en funcin de los atributos de los nodos
hermanos y/o del nodo padre.
o Atributos heredados de un smbolo del consecuente o Atributos
sintetizados utilizados en acciones o Atributos sintetizados del
antecedente
Slo con atributos sintetizados
Utiliza una accin para cada regla semntica Los atributos se
colocan al final del lado derecho de la produccin
Produccin Regla Semntica TT1*F T.val:= T1.val x F.val TT1*F
{T.val:= T1.val x F.val}
Con atributos heredados y sintetizados
Un atributo heredado para un smbolo en el lado derecho de una
produccin debe calcularse en una accin antes que dicho smbolo.
Una accin no debe referirse a un atributo sintetizado de un
smbolo que est a la derecha de la accin.
Un atributo sintetizado para el NO terminal de la izquierda solo
puede calcularse despus de que se hayan calculado todos los
atributos a los que hace referencia. (La accin se sita al final del
lado derecho de la produccin).
1.6. GENERACIN DE LA TABLA DE SMBOLO Y DE DIRECCIONES. Una tabla
de smbolos es til para:
Llevar un registro de la informacin sobre el mbito y el enlace
de los nombres. Examinar la tabla de smbolos cada vez que se
encuentra un nombre en el texto
fuente. Si se descubre un nombre nuevo o una nueva informacin
sobre un nombre ya existente, se producen cambios en la tabla.
Permite aadir entradas nuevas y encontrar las entradas
existentes eficientemente Existen dos mecanismos para las tablas de
smbolos:
Listas lineales: Fcil de implementar, pero su rendimiento es
pobre. Esquemas o tablas de dispersin: proporcionan un mayor
rendimiento pero
requieren mayor programacin y gasto de espacio.
-
No se introduce toda la informacin a la vez, las palabras claves
se introducen al inicio. Cada entrada de la tabla de smbolos
contienen un registro por cada identificador predefinido o definido
por el programador, aadindose informacin asociada:
Ristra del identificador (caracteres maysculas y/o minsculas)
Categora: variable, constante, tipo, campo, procedimiento, funcin,
parmetro,
clase, etiqueta, mdulo, macro, etc. mbito al que pertenece y su
tipo. Otra informacin: tamao, ubicacin, valor, parmetros o campos
(enlaces),
referencia adelante o no, mbito que define, etc. Estructura de
la tabla de smbolos
1. Estructura lgica, est determinada por: a. El tipo de mbito
(esttico o dinmico). b. Los mecanismos de mbito del lenguaje:
procedimientos, bloques,
herencia, mdulos, espacios de nombres, registros, etc. c. El
nmero de pasadas. d. Compilacin separada: ficheros con tablas.
2. Implementacin fsica: a. La ms eficiente suele ser la de una
tabla hash b. Asociada a pila de mbitos activos. c. Permite
insertar el elemento actual a la cabeza de la lista.
3. Las ristras (identificadores, constantes) pueden ir en listas
aparte. Alternativas para almacenar registros con los nombres de
smbolos y sus atributos.
1. Almacenamiento en la tabla de smbolos en un espacio de tamao
fijo dentro de un registro.
2. Almacenamiento en la tabla de smbolos en una matriz
independiente.
-
3. Almacenamiento en la tabla de smbolos definiendo el campo
nombre como un
ndice en un vector de nombres.
La tabla de smbolos tambin recibe el nombre de ambiente. Un
ambiente contiene un conjunto de parmetros que slo son visibles en
ese ambiente. La tabla de smbolos se mantiene durante todo el
proceso de traduccin agregando elementos especficos en cada paso.
Operaciones sobre la tabla de smbolos
Inserta(smbolo) Existe(nombre) Tipo(nombre)
Tcnicas para la designacin dinmica de la memoria:
1. Asignacin explcita de bloques de tamao fijo. 2. Asignacin
explcita de bloques de tamao variable. (asigna de acuerdo al
tamao
del smbolo, provoca fragmentacin)
-
3. Designacin implcita. (cooperacin entre el problema del
usuario y el paquete para la ejecucin)
1.7. MANEJO DE ERRORES SEMNTICOS. Los errores semnticos son
pocos y los que existen no se pueden detectar tan fcilmente.
Hasta esta etapa los errores son mostrados a los usuarios. Los
dems errores ya son muy difciles de detectar y generalmente se dan
en tiempo de ejecucin
Algunos problemas se presentan durante la fase de gestin de
memoria al pasar argumentos o al crear la pila semntica.
Muchos errores se generan durante la etapa del enlazador, al
tratar de obtener cdigo existente de algunas funciones/mtodos ya
implementadas en bibliotecas/APIs
Errores de compilacin: Son los que genera el compilador cuando
se exceden lmites marcados por l mismo. Algunos son:
Limitaciones en memoria lo que implica limitaciones en el tamao
de la tabla de smbolos, nmero FOR anidados, etc.
Limitaciones en las pilas de anlisis sintcticos y generacin de
cdigo, condicionando de esta forma la complejidad del cdigo.
Limitaciones en el nmero de bloques que se pueden definir en el
programa. Todos los lmites del compilador deberan estar claramente
definidos.
Errores de ejecucin: Son los que se producen durante la ejecucin
del cdigo objeto generado. Algunos son:
Aritmticos, como por ejemplo una divisin por 0 o una raz
cuadrada de un nmero negativo.
Acceso a matrices fuera de rango. Acceso a ficheros no abiertos.
Problemas en punteros a ficheros (por ejemplo intentar acceder a un
dato ms
all del fin de fichero). Problemas de memoria en tiempo de
ejecucin al intentar reservar memoria
dinmicamente cuando no hay disponibilidad. Limitaciones de la
pila de ejecucin (una de las situaciones ms tpicas es el abuso
en la recursividad de partes del cdigo).