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

Entradas populares