
También se encarga de revisar que cada agrupación o conjunto de token tenga sentido, y no sea un absurdo. En esta etapa se reúne la información sobre los tipos para la fase posterior, en esta etapa se utiliza la estructura jerárquica de la etapa anterior y así poder determinar los operadores, y operandos de expresiones y preposiciones.
Se compone de un conjunto de rutinas independientes, llamadas por los analizadores léxico y sintáctico.
El análisis semántico utiliza como entrada el árbol sintáctico detectado por el análisis sintáctico para comprobar restricciones de tipo y otras limitaciones semánticas y preparar la generación de código.
En compiladores de un solo paso, las llamadas a las rutinas semánticas se realizan directamente desde el analizador sintáctico y son dichas rutinas las que llaman al generador de código. El instrumento más utilizado para conseguirlo es la gramática de atributos. En compiladores de dos o más pasos, el análisis semántico se realiza independientemente de la generación de código, pasándose información a través de un archivo intermedio, que normalmente contiene información sobre el árbol sintáctico en forma lineal (para facilitar su manejo y hacer posible su almacenamiento en memoria auxiliar). En cualquier caso, las rutinas semánticas suelen hacer uso de una pila (la pila semántica) que contiene la información semántica asociada a los operandos (y a veces a los operadores) en forma de registros semánticos. En el caso de los operadores polimórficos (un único símbolo con varios significados), el análisis semántico determina cuál es el aplicable. Por ejemplo, consideremos la siguiente sentencia de asignación: A := B + C En Pascal, el signo “+” sirve para sumar enteros y reales, concatenar cadenas de caracteres y unir conjuntos. El análisis semántico debe comprobar que B y C sean de un tipo común o compatible y que se les pueda aplicar dicho operador. Si B y C son enteros o reales los sumará, si son cadenas las concatenará y si son conjuntos calculará su unión.
Funciones
Entre las funciones de un analizador semántico están las siguientes:
· Detectar si las variables, constantes y funciones han sido declaradas antes de ser utilizadas.
· Verificar que las variables, constantes y funciones sean accesibles (visibilidad) desde el ámbito en que son utilizadas. · Comprobar que los diferentes identificadores solo hayan sido declarados una vez.
· Comprobaciones de tipos al evaluar las expresiones. Por ejemplo que no se multiplique un número por una cadena que la expresión a evaluar en un IF sea del tipo booleano. Las reglas de inferencia de tipos gobiernan el tipo de una expresión en función del operador y el tipo de sus operandos.
· Verificar que no se intente modificar el valor de una constante.
· Generar la tabla de símbolos.
¿Cómo hacer un análisis semántico?
Para realizar el análisis semántico utilizaremos una gramática de atributos. Dichos atributos se asociaran tanto a los símbolos terminales como a los no terminales y se propagarán por el árbol sintáctico desde abajo hacia arriba, dando lugar al árbol semántico.
Lo primero que haremos será definir las reglas semánticas, para ello utilizaremos de nuevo la notición BNF a la que añadiremos en pseudocódigo las reglas semánticas.
Recorreremos recursivamente el árbol sintáctico en postorden (para cada nodo procesamos recursivamente todos los descendientes primero y luego el nodo). Iremos añadiendo atributos con información al árbol a medida que procesemos nodos. Como el recorrido se realiza en postorden cuando procesemos un nodo ya habremos procesado previamente todos sus descendientes por lo que dispondremos de la información de que nos provean sus atributos.
Añadiremos a la tabla de símbolos todas las constantes y variables que se vayan reconociendo, junto con la información del tipo y el valor (en el caso de las constantes). La tabla de símbolos será una lista de elementos del tipo símbolo.
Ejemplo
int i; // Variable tipo entero
a = i + 2 ;
Análisis Léxico: Devuelve la secuencia de tokens: id asig id suma numero
Análisis Sintáctico: Orden de los tokens válido
Análisis Semántico: Tipo de variables asignadas incorrecta
Se compone de un conjunto de rutinas independientes, llamadas por los analizadores léxico y sintáctico.
El análisis semántico utiliza como entrada el árbol sintáctico detectado por el análisis sintáctico para comprobar restricciones de tipo y otras limitaciones semánticas y preparar la generación de código.
En compiladores de un solo paso, las llamadas a las rutinas semánticas se realizan directamente desde el analizador sintáctico y son dichas rutinas las que llaman al generador de código. El instrumento más utilizado para conseguirlo es la gramática de atributos. En compiladores de dos o más pasos, el análisis semántico se realiza independientemente de la generación de código, pasándose información a través de un archivo intermedio, que normalmente contiene información sobre el árbol sintáctico en forma lineal (para facilitar su manejo y hacer posible su almacenamiento en memoria auxiliar). En cualquier caso, las rutinas semánticas suelen hacer uso de una pila (la pila semántica) que contiene la información semántica asociada a los operandos (y a veces a los operadores) en forma de registros semánticos. En el caso de los operadores polimórficos (un único símbolo con varios significados), el análisis semántico determina cuál es el aplicable. Por ejemplo, consideremos la siguiente sentencia de asignación: A := B + C En Pascal, el signo “+” sirve para sumar enteros y reales, concatenar cadenas de caracteres y unir conjuntos. El análisis semántico debe comprobar que B y C sean de un tipo común o compatible y que se les pueda aplicar dicho operador. Si B y C son enteros o reales los sumará, si son cadenas las concatenará y si son conjuntos calculará su unión.
Funciones
Entre las funciones de un analizador semántico están las siguientes:
· Detectar si las variables, constantes y funciones han sido declaradas antes de ser utilizadas.
· Verificar que las variables, constantes y funciones sean accesibles (visibilidad) desde el ámbito en que son utilizadas. · Comprobar que los diferentes identificadores solo hayan sido declarados una vez.
· Comprobaciones de tipos al evaluar las expresiones. Por ejemplo que no se multiplique un número por una cadena que la expresión a evaluar en un IF sea del tipo booleano. Las reglas de inferencia de tipos gobiernan el tipo de una expresión en función del operador y el tipo de sus operandos.
· Verificar que no se intente modificar el valor de una constante.
· Generar la tabla de símbolos.
¿Cómo hacer un análisis semántico?
Para realizar el análisis semántico utilizaremos una gramática de atributos. Dichos atributos se asociaran tanto a los símbolos terminales como a los no terminales y se propagarán por el árbol sintáctico desde abajo hacia arriba, dando lugar al árbol semántico.
Lo primero que haremos será definir las reglas semánticas, para ello utilizaremos de nuevo la notición BNF a la que añadiremos en pseudocódigo las reglas semánticas.
Recorreremos recursivamente el árbol sintáctico en postorden (para cada nodo procesamos recursivamente todos los descendientes primero y luego el nodo). Iremos añadiendo atributos con información al árbol a medida que procesemos nodos. Como el recorrido se realiza en postorden cuando procesemos un nodo ya habremos procesado previamente todos sus descendientes por lo que dispondremos de la información de que nos provean sus atributos.
Añadiremos a la tabla de símbolos todas las constantes y variables que se vayan reconociendo, junto con la información del tipo y el valor (en el caso de las constantes). La tabla de símbolos será una lista de elementos del tipo símbolo.
Ejemplo
// Un identificador no se puede utilizar si previamente no se ha definido.
char a; // Variable tipo char
int i; // Variable tipo entero
a = i + 2 ;
Análisis Léxico: Devuelve la secuencia de tokens: id asig id suma numero
Análisis Sintáctico: Orden de los tokens válido
Análisis Semántico: Tipo de variables asignadas incorrecta
No hay comentarios:
Publicar un comentario