verificação de tipos

27
Verificação de Tipos • Verificação de erros semânticos. • Verificação estática (e não dinâmica) – Estática: em tempo de compilação – Dinâmica: em tempo de execução • Objetivo: detecção de alguns tipos de erros

Upload: saima

Post on 19-Jan-2016

75 views

Category:

Documents


0 download

DESCRIPTION

Verificação de Tipos. Verificação de erros semânticos . Verificação estática (e não dinâmica) Estática: em tempo de compilação Dinâmica: em tempo de execução Objetivo: detecção de alguns tipos de erros. Tipos de Verificações Estáticas. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Verificação de Tipos

Verificação de Tipos

• Verificação de erros semânticos.

• Verificação estática (e não dinâmica)– Estática: em tempo de compilação– Dinâmica: em tempo de execução

• Objetivo: detecção de alguns tipos de erros

Page 2: Verificação de Tipos

Tipos de Verificações Estáticas

• Verificação de tipos: soma de variáveis de tipos incompatíveis, atribuição de expressões incompatíveis com variáveis.

• Verificações de fluxo de controle: goto entre procedimentos, break em C sem while/for/switch.

• Verificações de unicidade: identificadores, labels.• Verificações ligadas a nomes: mesmo nome

indicando início e fim de bloco, em Ada.

Page 3: Verificação de Tipos

Verificador de Tipos

parserVerificador

de tipostokensGerador de

código intermediário

árvoresintátic

a

árvoresintática

Page 4: Verificação de Tipos

Tarefas do verificador de tipos

• Tipo dos operandos são compatíveis com tipo do operador

• Só ponteiros são derreferenciados

• Só arrays são indexados

• Número e tipo de argumentos passados a uma função estão corretos

Page 5: Verificação de Tipos

Informações geradas pelo verificador de tipos

• Além do uso pelo próprio type checker, várias informações de tipos são mantidas para uso em passos posteriores, inclusive geração de código.

• Exemplo: overloading do ‘+’.

Page 6: Verificação de Tipos

Overloading, coerção e polimorfismo

• Overloading: mesmo símbolo ou nome usado para representar operações diferentes. Exemplo: 2 + 2 vs. 2.0 + 2.0

• Coerção: conversão implícita (ou explícita) de um tipo para outro. Exemplo: 2 + 3.5

• Polimorfismo: corpo (código) de uma mesma função é usado para lidar com tipos difrentes.

Page 7: Verificação de Tipos

Sistemas de Tipos

• Podem ser definidos formalmente ou informalmente.

• Define os tipos válidos e as regras para se atribuir tipos às construções da linguagem.

Page 8: Verificação de Tipos

Sistemas de Tipos

• Report do Pascal: “Se os dois operandos dos operadores aritméticos de adição, subtração e multiplicação são do tipo inteiro, então o resultado é do tipo inteiro.”

• Manual de Referência do C: “O resultado do operador unário & é um ponteiro para o objeto referido pelo operando. Se o tipo do operando for ‘…’ o tipo do resultado é ‘ponteiro para …’”

• Cada expressão tem um tipo associado a ela.

Page 9: Verificação de Tipos

Tipos básicos e tipos construídos

• Tipos básicos (atômicos): boolean, character, integer, real.

• Subrange (1..10) e tipos enumerados (verao,inverno,outono, primavera) podem ser tratados como tipos básicos.

• Tipos construidos: arrays, registros, conjuntos (são formados de outros tipos construidos ou básicos)

• Ponteiros e funções podem ser vistos como tipos construídos.

Page 10: Verificação de Tipos

Expressões de Tipos

• Tipos em uma linguagem são expressos por “expressões de tipos”: tipos básicos ou construtores de tipos aplicados a outras expressões de tipos.

• Os construtores possíveis variam de acordo com a linguagem.

Page 11: Verificação de Tipos

Tipos em uma Linguagem

• Tipos básicos: boolean, integer, char, real, type_error, void.

• Nome de uma expressão de tipos

Page 12: Verificação de Tipos

Tipos em uma Linguagem: Construtores de tipos

• Tipo Array: var A: array[1..10] of integer• Tipo Produto: T1 T2

• Tipo Registro: é um tipo produto com nomes:type row = record address: integer; lexeme: array [1..15] of char; end;é o mesmo querecord((address integer) (lexeme array(1..15,char))

Page 13: Verificação de Tipos

Construtores de Tipos (cont.)

• Tipo Ponteiro: var p: ^rowdeclara uma variável do tipo pointer(row)

• Tipo Função: mapeiam valores de um domínio D para um domínio destino R, i.e. D R.Exemplo: a função mod tem tem tipo int int int– Por razões de implementação, às vezes os tipos

suportados como resultado de uma função são limitados em algumas linguagens.

Page 14: Verificação de Tipos

Tipos podem ser representados por grafos

int

int int

pointer

char char int

char

int

pointer

Page 15: Verificação de Tipos

Sistemas de Tipos

• Coleção de regras para atribuir expressões de tipo a várias partes de um programa.

• Verificação de tipos pode sempre ser feita dinamicamente, se junto com os dados vierem sempre informações de tipos.

• Um sistema de tipos sound elimina a necessidade de verificações dinâmicas, porque permite detectar estaticamente se erros de tipos podem ocorrer em um programa.

Page 16: Verificação de Tipos

Sistemas de Tipos (cont.)

• Uma linguagem é dita fortemente tipada (strongly typed) se ela garante que erros de tipo não podem ocorrer durante a execução.

• Na pratica, algumas verificações só podem ser feitas dinamicamente. Exemplo: índices de arrays.

Page 17: Verificação de Tipos

Especificação de um type checker simples

P D ; E

D D ; D | id : T

T char | integer | array [ num ] of T | ^T

E literal | num | id | E mod E | E [ E ] | E^

• Exemplo:key : integer;key mod 1999

Page 18: Verificação de Tipos

Especificação de um type checker simples (cont.)

P D ; E

D D ; D

D id : T {addtype(id.entry, T.type)}

T char {T.type = char}

T integer {T.type = integer}

T array [ num ] of T {T.type=array(1..num.val, T1.type)}

T ^T1 {T.type = pointer(T1.type)}

Page 19: Verificação de Tipos

Especificação de um type checker simples (cont.)

E literal {E.type = char}

E num {E.type = integer}

E id {E.type = lookup(id.entry)}

E E1 mod E2 {if (E1.type == integer && E2.type == integer) E.type = integer else E.type = type_error }

Page 20: Verificação de Tipos

Especificação de um type checker simples (cont.)

E E1 [ E2 ] {if (E2.type == integer && E1.type == array(s,t)) E.type = t else E.type = type_error }

E E1^ {E.type = if (E1.type == pointer(t)) t else type_error }

Page 21: Verificação de Tipos

Verificação de tipos de comandos (statements)

S id = E {S.type = if (id.type == E.type) void else type_error }

S if E then S1 {S.type = if (E.type == boolean) S1 .type else type_error }

Page 22: Verificação de Tipos

Verificação de tipos de comandos (statements) (cont.)

S while E do S1 {S.type = if (E.type == boolean) S1.type

else type_error }

S S1 ; S2 {S.type = if (S1.type == void && S2.type == void) void else type_error }

Page 23: Verificação de Tipos

Verificação de funções

T T1 T2 {T.type = T1.type T2.type}

E E1 ( E2 ) {E.type = if (E2.type == s && E1 .type == s t) t

else type_error }

Page 24: Verificação de Tipos

Equivalência de tipos

• Geralmente é usada equivalência estrutural.• Às vezes é necessário fazer modificações, por

exemplo:– Em várias linguagens, os índices de arrays em um

tipo são ignorados em passagem de parâmetros.

– Tratamento de nomes de tipos e tipos sinônimos (equivalência estrutural x equivalência por nomes).

– A função de equivalência deve tratar tipos recursivos!

Page 25: Verificação de Tipos

Ciclos na representação de tipos

type link = ^cell;

cell = record info : integer; next : link; end;

cell = record

pointerinfo integer next

Page 26: Verificação de Tipos

Ciclos na representação de tipos (cont.)

• C evita ciclos na representação de tipos usando equivalência estrutural para todos os tipos exceto records (structs).

Page 27: Verificação de Tipos

Ciclos na representação de tipos (cont.)

• struct cell { int info; struct cell *next; };

cell = record

pointerinfo integer next

Cell