Beruflich Dokumente
Kultur Dokumente
Procesadores de Lenguaje II
Comprobacin de Tipos
Introduccin Sistemas de tipos
Expresiones de tipos Sistemas de tipos Comprobacin esttica y dinmica de tipos Tablas de Smbolos
Comprobacin de Tipos
Un comprobador de tipos
Calcula y mantiene la informacin de tipos (inferencia) informaci Comprueba que el tipo de una construccin tenga sentido en construcci su contexto segn el lenguaje seg
Ubicacin:
tokens
rbol sintctico abstracto Analizador Analizador sintctico sintctico Comprobador Comprobador De tipos De tipos
= : int a : int
Comprobacin de Tipos
Un lenguaje especifica que operaciones son vlidas para cada tipo
Formalizacin de reglas semnticas de verificacin
Se detectan errores
Acceso incorrecto a memoria: Lmites de abstraccin, mal uso de estructuras, etc.
Tipos de lenguajes:
Estticamente tipificados: La mayora de comprobaciones se
realizan en tiempo de compilacin (C, Java) en ejecucin (Scheme, LISP) No tipificados: Ninguna comprobacin (cdigo ensamblador)
Expresiones de tipos I
Representan el tipo de las construcciones
Valores posibles y operaciones que pueden aplicarse Especificaciones del lenguaje para operaciones:
Tipo de Expresin resultante de aplicar operadores aritmticos Resultado de aplicar operador & Tipo de llamada a funcin
Pueden ser
Un tipo bsico
Boolean, Char, Integer, Real, Vacio, Error_tipo,
Expresiones de tipos II
Expresiones de tipos
1. 2. 3.
a)
Tipos bsicos El nombre de un tipo es una expresin de tipo Constructores de tipos y expresiones de tipos son tipo Arrays
Si T es una expresin de tipo entonces array (I, T) es una expresin de tipo que indica una matriz con elementos de tipo T y conjunto de ndices I Var A: array[1..10] of integer es array (1..10, integer)
b)
Productos
Si T1 y T2 son expresiones de tipo, su producto cartesiano T1 x T2 es una expresin de tipo (x es asociativo por la izquierda)
Registros
Tiene como tipo el producto de los tipos de los campos. El constructor de tipo record se aplica a una tupla formada con nombres de campos y tipos de campos. Ej: type fila = RECORD direccion: integer; lexema: array [1..15] of Char; END; var tabla: array [1..10] of fila
fila tiene el tipo: record ((direccin x integer) x (lexema x array(1..15, Char))) Tabla tiene el tipo: array(1..10, record ((direccin x integer) x (lexema x array(1..15,char))) o: array(1..10, Tipo_Fila)
Expresiones de tipos IV
d)
Punteros
Si T es una expresin de tipo, Pointer (T) es una expresin de tipo que es un puntero a un objeto de tipo T. Ej.: Var p: ^fila; p es de tipo: pointer (fila)
e)
Funciones
Si T1 y T2 son expresiones de tipos, entonces T1 T2 es la expresin de tipos de una funcin que toma argumentos de T1 y los transforma en T2 Function f (a, b : Char) : ^Integer; f tiene el tipo: (char x char) pointer (Integer)
Representacin de tipos
En el lenguaje que implementa el compilador
Estructura especial de tabla de smbolos
Representacin de tipos
Ejemplo representacin constructores de tipos
typedef struct{ char nombre[20]; char apellido[20]; int edad;} TipoPersona;
TipoPersona
x x x nombre array 0..19 char apellido x array 0..19 char x edad int
Representacin cclica
Representacin de tipos
Representacin tabular
Si se definen tipos nuevos, preciso TS para aadirlos Ej.:
int a; float **b; float *c[10] int f(char,float,int); Tabla Smbolos
Id. a b c f Tipo 0 4 5 8
Tabla Tipos
Nm . 0 1 2 3 4 5 6 7 8 Tipo entero real caracter puntero puntero array pr. cart. pr. cart. funcin Tam/ Tipo1 4 8 1 1 1 10 2 6 7 1 3 3 1 0 0 Tipo Base
Representacin de tipos
Tipos declarados y tipos annimos
struct{ char nombre[20]; char apellido[20]; int edad;} e1; char[20] n1; typedef struct{ char nombre[20]; char apellido[20]; int edad;} tipoPersona; typedef char[20] cadena; tipoPersona e2; cadena n2;
Tipos annimos
Tipos declarados
x edad int
0..19 char
0..19 char
Sistemas de tipos
Sistema de tipos: conjunto de reglas para asignar expresiones de tipos a construcciones de un programa
VAR x: RECORD p_real: real; p_imag: real; END; VAR y: RECORD p_imag: real; p_real: real; END; x=y; INCORRECTO x.p_real=y.p_imag; CORRECTO
Un comprobador de tipos implanta un sistema de tipos Se pueden implementar en la definicin dirigida por la sintaxis
Esttica: Aquella que es realizada por el compilador antes de la ejecucin del programa Dinmica: Aquella que es realizada al ejecutar el programa objeto
Tablas de Smbolos I
Recogen las diferentes declaraciones (explcitas) del programa
Declaraciones de constantes (nombre, tipo, valor,)
const int SIZE=20
Tablas de Smbolos II
Estructura de Datos para almacenar identificadores definidos en el programa
Se utiliza en diferentes fases del anlisis y sntesis Funciones de insercin, bsqueda y eliminacin Solucin habitual con tabla de hash
Optimizacin del compilador
Identificador aux Hashing ndices 0 1 2 N-1
a temp aux
Registros
Lista elementos
Tablas de Smbolos IV
Gestin de mbitos en la tabla se smbolos
Los lenguajes con estructura de bloques permiten declaraciones en distintos mbitos, se puede dar anidamiento
{ int x = 0; foo(x); { int x = 1; bar(x); } baz(x); }
Tablas de Smbolos V
Tablas para estructuras registro
Los registros tienen campos con desplazamiento fijo typedef struct cplx{ cplx.real double real; cplx.imag double imag; }; Tabla Tipos cplx a, b;
Nm . 0 1 Tipo real pr. cart. 4 0 0 base de cplx desplaz. campo imag
Tam/ Tipo1
Tipo Base
Tabla Smbolos
Id. a b Tipo 1 1 direccin 100 116
Tabla Registros
Nombre real imag Tipo 0 0 direccin 0 8
Un lenguaje sencillo I
Ejemplo de lenguaje, con todos los identificadores declarados antes de uso
Objetivo: comprobar el tipo de toda expresin
Tipos complejos
Array[n] of T es de tipo array (T, 1..n) ^T es de tipo pointer (T)
Un lenguaje sencillo II
Gramtica del lenguaje
P Ds E P Ds E Ds Ds D ;; Ds || D Ds D D id :: T id T T T char || integer || array [num] of T || ^T char integer array [num] of T ^T E literal || num || id || E mod E || E [[ E ]] || E^ E literal num id E mod E E E E^ D es cada declaracin T es el tipo E es la expresin
{{aadeTipo (id.entrada, T.tipo) }} aadeTipo (id.entrada, T.tipo) {{T.tipo := char }} T.tipo := char {{T.tipo := integer }} T.tipo := integer {{T0.tipo := pointer (T1.tipo) }} T0.tipo := pointer (T1.tipo) {{T0.tipo := array(1..num.val, T0.tipo := array(1..num.val, T1.tipo) }} T1.tipo)
Un lenguaje sencillo IV
Acciones semnticas de verificacin de tipos en expresiones
Constantes E E literal literal E E num num Identificadores E E id id Operadores E E E mod E E mod E {{E.tipo := Char }} E.tipo := Char {{E.tipo := Integer }} E.tipo := Integer {{E.tipo := buscaTipo (id.entrada) }} E.tipo := buscaTipo (id.entrada) {{if (E1.tipo = Integer) and if (E1.tipo = Integer) and (E2.tipo = Integer) (E2.tipo = Integer) E0.tipo = Integer E0.tipo = Integer else E0.tipo = Error_Tipo }} else E0.tipo = Error_Tipo
Un lenguaje sencillo V
Acciones semnticas de verificacin de tipos en expresiones
Arrays E E E [[E ]] E E {{if (E1.tipo = Integer) and if (E1.tipo = Integer) and (E2.tipo = array(s, t) (E2.tipo = array(s, t) )) E0.tipo = tt E0.tipo = else E0.tipo = Error_Tipo }} else E0.tipo = Error_Tipo
Punteros E E E^ E^ {{if (E1.tipo = pointer(t)) if (E1.tipo = pointer(t)) E0.tipo = tt E0.tipo = else E0.tipo = Error_Tipo }} else E0.tipo = Error_Tipo
(a)
array [ T ]
n
cpa
of ^
T T
cp
(10)
num
char
TS
a cpa
b c
(b)
id [ E
E
cp
(a)
mod E
(1)
num
(1)
num
Tipos en sentencias
Por defecto, una sentencia es de tipo nulo (vaco), salvo si es errnea Proposiciones if y while
S S S S S S S S id := E id := E if E then S if E then S {{if (id.tipo = E.tipo) then S0.tipo = vaco if (id.tipo = E.tipo) then S0.tipo = vaco else S0.tipo := Error_Tipo }} else S0.tipo := Error_Tipo {{if (E.tipo = boolean) then S.tipo = S1.tipo if (E.tipo = boolean) then S.tipo = S1.tipo else S0.tipo := Error_Tipo }} else S0.tipo := Error_Tipo
while E do S {{if (E.tipo = boolean) then S.tipo = S1.tipo while E do S if (E.tipo = boolean) then S.tipo = S1.tipo else S0.tipo := Error_Tipo }} else S0.tipo := Error_Tipo S ;;S S S {{if (S1.tipo = vaco) and (S2.tipo = vaco) if (S1.tipo = vaco) and (S2.tipo = vaco) then S0.tipo = vaco then S0.tipo = vaco else S0.tipo := Error_Tipo }} else S0.tipo := Error_Tipo
Tipos en sentencias
Ampliar G para permitir declaracin de funciones T T
Ej.:
T T T T
T2.tipo }} T2.tipo
int f(double x, char y) { ... } tipo de f: double x char int tipos argum. tipo devolucin
Llamada a la funcin, con parmetros E E E ((E )) E E {{if (E2.tipo = s) and (E1.tipo = ss t) t) if (E2.tipo = s) and (E1.tipo = then E0.tipo = tt then E0.tipo = else E0.tipo := Error_Tipo }} else E0.tipo := Error_Tipo
Conversiones de tipos
Algunos operadores pueden aplicarse a operandos de distintos tipos (promocin o coercin): x+y ? Si el tipo de x es double y el de y int, tipo resultado? (afecta al cdigo a generar)
E E E op E E op E {{if (E1.tipo = Integer) and if (E1.tipo = Integer) and (E2.tipo = Integer) then E0.tipo = Integer (E2.tipo = Integer) then E0.tipo = Integer else if (E1.tipo = Integer) and else if (E1.tipo = Integer) and (E2.tipo = real) then E0.tipo = real (E2.tipo = real) then E0.tipo = real else if (E1.tipo = real) and else if (E1.tipo = real) and (E2.tipo = Integer) then E0.tipo = real (E2.tipo = Integer) then E0.tipo = real else if (E1.tipo = real) and else if (E1.tipo = real) and (E2.tipo = real) then E0.tipo = real (E2.tipo = real) then E0.tipo = real else E0.tipo = tipo_error} else E0.tipo = tipo_error}
Tipos sobrecargados I
Algunos operadores y funciones pueden tener distintos significado segn su contexto:
(4 + a) y (4+a) son expresiones distintas en Java No siempre es posible resolver slo con los operandos cuando hay promocin automtica:
function * (k,j: integer) return integer function * (x,y: real) return real Hay sobrecarga en Ada y en C++, no en C y Pascal * Puede tener los tipos posibles:
integer x integer integer x integer integer real
real real x real As: 3.1*5 pasa a ser 3.1*(real)5 3*5 es ambiguo: puede ser integer o real: (real)3 * (real) 5 i en la expresin 2*(3*5) tiene tipo (i*i) en la expresin z*(3*5) tiene tipo (r*r) r
Tipos sobrecargados II
Tipado sobrecargado: si permite que las construcciones tengan ms de un tipo
Procedure swap(var x,y:anytype): plantilla (template)
La sobrecarga permite varias declaracions del mismo nombre El extremo es una declaracin para cualquier tipo:
Se generalizan las verificaciones para considerar conjuntos de tipos posibles de una expresin:
Ejemplo DDS E E E E E E E E id id
Se supone que la tabla de smbolos puede contener el conjunto de posibles tipos El tipo conjunto vaco se asimila con tipo_error Problema similar a la inferencia de tipos
{{E.tipos=E.tipos} E.tipos=E.tipos} {{E.tipos=consulta(id.entrada)} E.tipos=consulta(id.entrada)} {E0.tipos= {t ||existe un {E0.tipos= {t existe un tal que ss tal que tipo ssen E2.tipos tipo en E2.tipos t, con tten E1.tipos} t, con en E1.tipos}
E ((E )) E E
E0 E1 ((E2 )) E0 E1 E2
Tipos sobrecargados IV
Ej.: a: cplx; a=3 + 4 * 1.2 *, + sobrecargados: int x int int real x real real cplx x cplx cplx
P D S T cplx
(a)
id :
(a)
id = E
(3)
E+ E
(4)
E * E
(1.2)
E v=2.5 cierto
real
E v=1.0 cierto num . num v=1.0 / E E v=5.0 v=2.0 1.0 falso falso num num v=5 v=2 2 5 real
/ E v=2.5 falso
Equivalencia de tipos
Aspecto esencial en las verificaciones semnticas Dos posibilidades bsicas:
La equivalencia de nombres considera cada nombre de un tipo La equivalencia de nombres considera cada nombre de un tipo como un tipo distinto, de modo que dos expresiones de tipo como un tipo distinto, de modo que dos expresiones de tipo tienes equivalencia de nombres si yyslo si son idnticas tienes equivalencia de nombres si slo si son idnticas Con la equivalencia estructural, los nombres se sustituyen por las Con la equivalencia estructural, los nombres se sustituyen por las expresiones de tipos que definen. Dos expresiones de tipos son expresiones de tipos que definen. Dos expresiones de tipos son estructuralmente equivalentes si yyson idnticas al sustituidos los estructuralmente equivalentes si son idnticas al sustituidos los tipos por sus expresiones de tipo correspondientes tipos por sus expresiones de tipo correspondientes
Equivalencia estructural I
Dos expresiones de tipos son estructuralmente equivalentes si son el mismo tipo bsico o se forman aplicando el mismo constructor de tipos a expresiones de tipos estructuralmente equivalentes
integer es equivalente a integer pointer (integer) es equivalente a pointer (integer)
Las expresiones estructuralmente equivalentes se corresponden con rboles o grafos acclicos iguales
Equivalencia estructural II
Algoritmo para comprobar la equivalencia estructural:
Function Equivale (s, t) ::boolean Function Equivale (s, t) boolean if ssyyttson del mismo tipo bsico then return true if son del mismo tipo bsico then return true else if ss= array(s1,,ss ))and tt= array (t1,,tt ))then else if = array(s1 22 and = array (t1 22 then return Equivale (s1,,tt ))and Equivale (s2,,tt )) return Equivale (s1 11 and Equivale (s2 22 else if ss= ss xxss and tt= tt xxtt then else if = 11 22 and = 11 22 then return Equivale (s1,,tt ))and Equivale (s2,,tt )) return Equivale (s1 11 and Equivale (s2 22 else if ss= pointer (s1))and tt= pointer (t1))then else if = pointer (s1 and = pointer (t1 then return Equivale (s1,,tt )) return Equivale (s1 11 else if ss= ss 2 and = 1 2 then else if = 11 ss2and tt= tt1 tt2then return Equivale (s1,,tt ))and Equivale (s2,,tt )) 11 and Equivale (s2 22 return Equivale (s1 else return false else return false Algunas comprobaciones pueden relajarse (arrays)
Equivalencia de nombres
Algoritmo para comprobar la equivalencia de nombres:
Function Equivale (s, t) ::boolean Function Equivale (s, t) boolean if ssyyttson del mismo tipo bsico then return true if son del mismo tipo bsico then return true else if ssy ttson nombres de tipo else if y son nombres de tipo if son iguales return true if son iguales return true else return false else return false
Equivalencia de nombres
Solucin ms comn en lenguajes imperativos
Ms restrictiva, ms fcil de implementar
typedef struct{ char nombre[20]; char apellido[20]; int edad;} cliente; void registrar (cliente*p){...} empleado e; registrar(&e); //error
x x x nombre array apellido x array edad x int
0..19
char
0..19
char