Clase15.ppt

26
Análisis Semántico Clase 14

Transcript of Clase15.ppt

Page 1: Clase15.ppt

Análisis Semántico

Clase 14

Page 2: Clase15.ppt

El Compilador hasta ahora

• Análisis léxico– Detecta entradas de tokens legales

• Análisis Sintáctico– Detecta entradas con árboles mal formados.

• Análisis Semántico– Detecta todos los errores restantes

Page 3: Clase15.ppt

Por qué necesitamos el análisis semántico

• El analizador sintáctico no puede detectar todos los errores.

• Algunos constructores del lenguaje no son libres de contexto– Ejemplo: declaración de identificadores y su uso.– No puedes utilizar una GLC para describir que

alguna palabra particulares aparezca dos veces en una cadena separada por un texto en medio.

– Una versión abstracta del problema es:{wcw | w (a | b)* }

declaración uso

Page 4: Clase15.ppt

¿Qué hace el análisis semántico?

• Verificaciones de varias clases, típicamente:– Que todos los identificadores estén declarados.– Los tipos de las expresiones y la compatibilidad

de las asignaciones.– Invocación de métodos compatibles con las

declaraciones– etc …– Los requerimientos dependes del lenguaje.

Page 5: Clase15.ppt

Ámbitos

• Consiste en empatar las declaraciones de identificadores con su uso

• El ámbito de un identificador es la porción del programa en la cual el identificador es accesible.

• El mismo identificador se puede referir a diferentes cosas en diferentes partes del programa.– Ámbitos diferentes para el mismo nombre no se

sobreponen.• Un identificador puede tener ámbitos restringidos.

– Es decir solo es visible en áreas particulares del programa

Page 6: Clase15.ppt

Ámbitos estáticos vs dinámicos

• La mayoría de los lenguajes tienen ámbitos estáticos.– El ámbito sólo depende del texto del programa no

de la conducta en tiempo de ejecución.– Java, C, C++, Pascal, Modula, cool, etc. Tienen

ámbito estático.

• Pocos lenguajes tiene ámbitos dinámicos– Lisp, SNOBOL– El ámbito depende de la ejecución del programa

Page 7: Clase15.ppt

Ejemplo de ámbito estático

int x; -- variable global o campo estáticofloat convert_speed(float y) {

float x; --una x diferente (variable local)x=y*1.6return x;

}(El uso de x se refiere a la definición más

cercana )

Page 8: Clase15.ppt

Ámbito en lenguajes OO

• No todas las clases de identificadores siguen la regla del anidamiento más cercano

• Por ejemplo las definiciones de clases– Todas son visibles globalmente

• Declaración de campos en Java– Visibles a todos los métodos en una clase– Y algunas veces a otras clases también

• Dependiendo si son públicas o privadas, etc.

Page 9: Clase15.ppt

Más sobre ámbito

• Los nombres de métodos y atributos tienen reglas complejas.

• Los nombres de campos son globales dentro de cualquier clase.

• Pero los métodos y campos no necesitan estar definidos en la clase en la cual se están utilizando, pero si en una clase padre (herencia)

• Los métodos se pueden redefinir (sobreescritura)

Page 10: Clase15.ppt

Implementación de la regla anidada más cercana

• La mayor parte del análisis semántico se puede expresar como un recorrido descendente recursivo de un árbol o AST.– Procesa un nodo n– Procesa los hijos de n– Finaliza procesando el nodo n

• En cualquier porción del árbol (contexto en el programa), necesitamos saber que identificadores están definidos.

Page 11: Clase15.ppt

Tabla de Símbolos• Una tabla de símbolos es una estructura de datos

empleada para registrar las declaraciones de identificadores.

• Los identificadores se almacenan cuando se declaran– Con atributos

• Nombres de clases, métodos, variables, etc

– Y sub-atributos• public, private, integer, float, static, array, etc• Su localización en la pila si es variable local

– La tabla de símbolos se consulta para cualquier uso.• Verificación semántica y generación de código.

Page 12: Clase15.ppt

Implementación de la tabla de símbolos

• La estructura es una pila– O una lista ligada que opera como pila

• Operaciones– add_symbol(x) inserta x y la información asociada,

tal como el tipo, en la pila.– find_symbol(x) busca en la pila, comenzando del

tope de la pila.Regresa el primer x encontrado o NULL si no se encontro.

– remove_symbol() saca elemento de la pila

Page 13: Clase15.ppt

Una tabla de símbolos más elaborada

• enter_scope() comenzar un nuevo ámbito anidado

• find_symbol(x) encuentra el x actual (o null)

• add_symbol(x) agrega un símbolo x a la tabla

• check_scope(x) verdadero si x esta definido en el ámbito actual (verificar declaraciones múltiples)

• exit_scope() salir del ámbito– Descartar todos los símbolos del ámbito reciente

Page 14: Clase15.ppt

Definición de clase

• Los nombres de clases se pueden usar antes de que sean definidos.

• Usualmente no se puede verificar esto para los nombres de clases.– Usando una tabla de símbolos (compilación

separada?)– O en una pasada (a menos que se requieran

prototipos)

Page 15: Clase15.ppt

Definición de clase

• Solución usual– Fase 1: Junta todos los nombres de clases (+

otras cosas)– Fase 2: Realiza la verificación

• El análisis semántico completo requiere varias pasadas.– Probablemente más de una

• La mayoría de compiladores en JAVA busca por archivos de clases previamente compiladas.

Page 16: Clase15.ppt

Tipos

• ¿Qué es un tipo?– La noción varía de lenguaje a lenguaje.

• Consenso– Un conjunto de valores– Un conjunto de operadores sobre los

valores

• Las clases son una instanciación moderna de la noción de tipo

Page 17: Clase15.ppt

Tipos y operaciones

• Ciertas Operaciones son legales para cada tipo– No tiene sentido sumar un apuntador a

función y un entero en C– Tiene sentido sumar dos enteros– Pero ambos tienen la misma

implementación en lenguaje ensamblador!

Page 18: Clase15.ppt

Sistema de tipos

• Un sistema de tipos de un lenguaje especifica las operaciones que son válidas para cada tipo.

• La meta de la verificación de tipos es asegurar que las operaciones se utilizan con los tipos correctos.– Hace cumplir la interpretación de los valores.– Algunas veces puede realizar conversiones automáticas

cuando el lenguaje permite modos mezclados y promoción de tipos.

• El sistema de tipos provee una formalización concisa de las reglas de verificación semántica.

Page 19: Clase15.ppt

Traslación dirigida por la sintaxis

• La mayoría de los compiladores son de múltiples pasadas.

• Recorre el AST para el análisis semántico, verificación de tipos.

• Recorre este otra vez para optimización.

• y generación de código• .. etc.

Page 20: Clase15.ppt

Compilación de una pasada

• Bajo ciertas circunstancias, es posible construir un compilador completo de una sola pasada.

• Es posible con ciertas condiciones del lenguaje – Particularmente cuando se declara antes de que se

use.

• Esto requiere que la traslación se realice durante un recorrido del árbol en profundidad.– La forma en que el analizador sintáctico se mueve a

través del árbol

Page 21: Clase15.ppt

Verificación de tipos

• Existen dos aspectos a considerar en la verificación de tipos de un compilador:– Procesar las declaraciones y mantener una tabla de

símbolos.• Almacenar el tipo de cada identificador en la tabla de

símbolos.– Realizar la verificación de tipos y hacer cumplir las reglas

semánticas en expresiones y otros elementos del lenguaje (e.g. Lista de argumentos, etc)

– Buscar el tipo de los identificadores usados.– Inferir los tipos de constantes– Calcular el tipo de los nodos que denotan expresiones.

Page 22: Clase15.ppt

Verificación de tipos con aseveraciones

• En cada regla declaramos la aseveración que se debe cumplir si el programa es válido.

• ASSERT(condición) ¨mensaje¨ significa:– La condición se supone debe cumplirse– Si no es verdadera, imprime mensaje.

• Puede usarse una macro en C para este propósito#define ASSERT(x,y) if (!x) printf(¨line %d: %s\n¨,lineno, (y))

Page 23: Clase15.ppt

Ejemplo de verificación de tipos (un ejemplo similar esta en la Sec. 6.4.4 de Kenneth)

Page 24: Clase15.ppt

Implementación de una Tabla de Símbolos simple

Page 25: Clase15.ppt

Verificación de tipos en Bison

Page 26: Clase15.ppt

Verificación de tipos (Cont.)