Analizador Semanticos
ANALIZADOR SEMANTICO
La
semántica corresponde al significado asociado a las estructuras formales
(sintaxis) del lenguaje.
El
analizador semántico para que pueda funcionar correctamente utiliza el árbol
sintáctico al igual que la información que hay en la tabla de símbolos para
poder comprobar la consistencia semántica del programa fuente con la definición
del lenguaje, también tiene que recopilar información sobre el tipo de programa
y la guarda, ya sea en el árbol sintáctico o en la tabla de símbolos, para
usarla más tarde durante la generación de código intermedio.
Una
parte importante del análisis semántico es la comprobación o verificación de
tipos, en donde el compilador verifica que cada operador tenga operando que
coincidan. La especificación del lenguaje puede permitir ciertas conversiones
de tipo conocidas como coerciones. En ella se utiliza la estructura jerárquica
determinada por la clase de análisis sintáctico para identificar los operadores
y operandos de expresiones y proposiciones.
Un
componente importante del analizador semántico es la verificación de tipos. El
compilador del programa verifica si cada operador tiene operandos permitidos
por la especificación del lenguaje fuente, por ejemplo: cuando un operador
aritmético binario se aplica a un número entero y a un número real. En este
caso, el compilador puede necesitar convertir el número entero a real.
Al momento
de la creación del analizador semántico hay que tener en mente otro tipo de
cosas importantes como por ejemplo que hay un registro por cada identificador
definido o que este declarado por el programador, añadiéndose información
asociada, las cuales podrían ser:
- ·
Ristra
del identificador: ¿mayúsculas y minúsculas?
- ·
Categoría:
variable, constante, tipo, campo, procedimiento, función, parámetro, clase,
etiqueta, módulo, macro, etc.
- ·
A
qué ámbito pertenece (profundidad)
- ·
Otra
información según categoría: tamaño; ubicación; valor; enlaces a tipo,
parámetros o campos; si incompletamente definido; etc.
Otro
punto de importancia que hay que tener en mente es la estructura lógica de cómo
estará organizada la tabla, hay distintas formas de organizarla pero la
decisión final seria del programador ya que solo el sabría cómo implementarlo
mejor al diseño sin que este pueda tener fallas; como por ejemplo tendría que
ver el tipo de ámbito si seria de forma estática o dinámica, también se
tendrían que tener en mente el mecanismo que utilizaría o se le implementaría
al lenguaje como si se implementarían los tipos de bloques o si se usaría
herencias o módulos, etc. Entre otras cosas se debe tener una compilación
separada con ficheros y sus respectivas tablas.
Ejemplo de tabla de símbolos
Aunque
hay mucha información sobre los analizadores semánticos, nunca hay que olvidar
que las operaciones principales se realizan mediante lógica, pero además de las
decisiones que ya se explicaron también se deben considerar otros puntos de
importancia con respecto al compilador que usaríamos, como por ejemplo la
elaboración de una lista completa de las comprobaciones semánticas que va a
realizar el compilador y después estas comprobaciones se extraen de la
especificación del lenguaje lo cual nos indicara si algunas operaciones son
posibles o no, como por ejemplo:
- ·
Si
el lenguaje permite mezcla de tipos en expresiones, las comprobaciones
semánticas son diferentes que si el lenguaje no permite la mezcla de tipos.
- · Si el lenguaje permite la utilización de variables sin previa definición de las mismas, las comprobaciones semánticas son diferentes que si el lenguaje requiere la definición previa de una variable antes de su uso.
También
entre otros puntos debemos considerar lo siguiente:
- ·
Definir
los atributos necesarios para implementar las comprobaciones semánticas
especificadas en el punto anterior.
- ·
Definir
si los atributos son heredados o sintetizados.
- ·
Definir
el modo en que se van a calcular los atributos.
- ·
Si
es necesario, transformar la gramática y ajustar el analizador sintáctico.
ERRORES
SEMANTICOS
Los
errores que puede detectar el analizador sintáctico son aquellos que violan las
reglas de una gramática independiente del contexto. por ejemplo, la restricción
de que los identificadores deben declararse previamente. Por lo tanto, los
principales errores semánticos son:
Conversiones
de tipos no permitidas
int x;
x = 4.32;
Error: Ej1.java
[6:1] possible loss of precision
Variables
usadas y no definidas
Operandos
de tipos no compatibles
if (x || 5) x = 0;
Error: Ej2.java
[7:1] operator || cannot be applied to int,int
Es mucho más difícil introducir métodos formales para la recuperación de errores semánticos que para la recuperación de errores sintácticos. La mayoría de los errores semánticos pueden ser detectados mediante la revisión de la tabla de símbolos, suponiendo un tipo que se base en el contexto donde ocurra o un tipo universal que permita al identificador ser un operando de cualquier operador del lenguaje, para que nos evitemos la impresión de un mensaje de error cada vez que se use la variable no definida. Si el tipo de un operando no concuerda con los requisitos de tipo del operador, también es conveniente reemplazar el operando con una variable ficticia de tipo universal. Este tipo de error es el más difícil de eliminar o resolver, ya que ni el compilador ni el sistema proporcionan información sobre qué está fallando. Lo único cierto es que el programa no se está comportando como debería ya que algo dentro del código se ejecuta con normalidad sin que llegue a tener lógica en la resolución del problema. Un error semántico se produce cuando la sintaxis del código es correcta, pero la semántica o significado no es el que se pretendía. La construcción obedece las reglas del lenguaje, y por ello el compilador o intérprete no detectan los errores semánticos. Los compiladores e intérpretes (programas y lenguajes) sólo se ocupan de la estructura del código que se escribe en ellos, y no de su significado por lo que hay que tener mucho cuidado al momento de declarar variables y al momento de hacer ejercicios lógicos-aritméticos.
Pero
en caso de querer construir un analizador semántico con Bison se deben seguir
los siguientes puntos:
- ·
La
lista de las comprobaciones semánticas: se deduce de la especificación del
lenguaje.
- ·
Los
atributos necesarios se deducen a partir de las comprobaciones semánticas que
haya que hacer (ver lista anterior). El tipo de los atributos se define
mediante la directiva %union dentro del fichero de especificación de Bison.
- ·
Los
atributos son sintetizados.
Esta restricción viene impuesta porque el tipo de analizador sintáctico que
genera Bison es ascendente LALR(1).
Si la gramática de atributos que se diseña para implementar el análisis
semántico requiere atributos heredados, hay que diseñar un mecanismo adecuado.
- ·
El
acceso a los atributos se realiza a través de $$, $1, $2, …
- · El cálculo de los atributos se realiza en las acciones asociadas a las reglas.
REFERENCIAS
Curz, M.
(20 de febrero del 2008). Análisis semántico. Microsoft PowerPonit Online. http://arantxa.ii.uam.es/~mdlcruz/docencia/compiladores/2007_2008/analisis_semantico_07_08_parte1.pdf
Fortes
Galvez, J. (6 de septiembre del 2005). Análisis semántico. PDF Online. http://serdis.dis.ulpgc.es/~ii-pl/ftp/transp/tr-asem-imp.pdf
Comentarios
Publicar un comentario