IF 688 Checagem de tipos Resumo desta aula

  • Slides: 40
Download presentation
IF 688 – Checagem de tipos

IF 688 – Checagem de tipos

Resumo desta aula • Sistema de tipos em um compilador • Conceitos – Expressões

Resumo desta aula • Sistema de tipos em um compilador • Conceitos – Expressões de tipo – Sistema de tipo: definição com gramática de atributos e implementação usando visitors – Conversão de tipos (coerção e casting), tempo de checagem (estática e dinâmica), rigor da checagem (forte e fraca), polimorfismo (ad-hoc, subtipo, e paramétrico)

Sistema de tipos • O que faz? – Identifica certos tipos de erros estaticamente

Sistema de tipos • O que faz? – Identifica certos tipos de erros estaticamente • Para que serve? – Facilitar programação – Evitar escapamento de erros simples – etc.

Sistema de tipos • O que faz? – Identifica certos tipos de erros estaticamente

Sistema de tipos • O que faz? – Identifica certos tipos de erros estaticamente • Para que serve? – Facilitar programação O problema de – Evitar liberação de erros simples Em tempo de encontrar erros é – etc. indecidível, no caso geral. compilação

Exemplos de erro (ou warning) • Tipos incompatíveis: soma, atribuição, chamada de método, etc.

Exemplos de erro (ou warning) • Tipos incompatíveis: soma, atribuição, chamada de método, etc. • Fluxo de controle: break ou continue fora de loop ou switch • Definição de variável sem uso (warning) • . . .

Exemplos de erro (ou warning) • • • . . . Uso de variável

Exemplos de erro (ou warning) • • • . . . Uso de variável sem definição Indexação em variável não array De-referência em variável não ponteiro etc.

Organização do compilador árvore sintática tokens parser árvore sintática Verificador de tipos tabela de

Organização do compilador árvore sintática tokens parser árvore sintática Verificador de tipos tabela de símbolos Gerador de código intermediário

Sistema de tipos • Define os tipos válidos e as regras para se atribuir

Sistema de tipos • Define os tipos válidos e as regras para se atribuir tipos às construções da linguagem • Podem ser definidos formalmente ou informalmente Opção para esta disciplina.

Exemplo Pascal • Report do Pascal – “Se os dois operandos operadores aritméticos de

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

Exemplo C • Manual de Referência de C – “O resultado do operador unário

Exemplo C • Manual de Referência de C – “O resultado do operador unário & é um ponteiro para o obj. referido pelo operando. Se o tipo do operando for T o tipo do resultado é ponteiro para T” Cada expressão tem um tipo associado!

Tipos básicos e derivados • Básicos: inteiro, char, string, tipos enumerados, subrange (exemplo 1.

Tipos básicos e derivados • Básicos: inteiro, char, string, tipos enumerados, subrange (exemplo 1. . 10), etc. • Derivados: ponteiro para inteiro, array de char, registro, classe, etc.

Expressões de tipo • Construções da linguagem que declaram tipos – Construtores básicos. Eg.

Expressões de tipo • Construções da linguagem que declaram tipos – Construtores básicos. Eg. , integer, boolean, etc. – Construtores elaborados: E. g. , record, class, etc. Construtores elaborados referem-se a outros tipos em uma cadeia com tipos básicos no final. Não confundir com tipo de uma expressão

Construtores de tipos • Array: array[1. . 10] of integer • Tipo Registro: record

Construtores de tipos • Array: array[1. . 10] of integer • Tipo Registro: record address: integer; lexeme: array [1. . 15] of char; end; • Ponteiro: ^row • Produto: T 1 T 2 • Função: integer

Tipos de variáveis var ar: array[1. . 10] of integer; Expressão de tipo.

Tipos de variáveis var ar: array[1. . 10] of integer; Expressão de tipo.

Sistema de tipos • Coleção de regras que definem o tipo associado às várias

Sistema de tipos • Coleção de regras que definem o tipo associado às várias partes do programa – Violação de regra => erro de tipo

Exemplo • Considerando que – Função foo possui tipo real boolean – Variável x

Exemplo • Considerando que – Função foo possui tipo real boolean – Variável x possui tipo inteiro • Erros de tipo: foo(1. 0) + x !foo(x + 1. 0) foo(x, 1. 0)

Type checker simples P D; E D D ; D | id : T

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

Type checker simples P D; E D D; D D id : T {addtype(id.

Type checker simples 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, T 1. type)}

Type checker simples T ^T {T. type = pointer(T 1. type)} E literal {E.

Type checker simples T ^T {T. type = pointer(T 1. type)} E literal {E. type = char} E num {E. type = integer} E id {E. type = lookup(id. entry)} E E mod E {E. type = if (E 1. type == integer && E 2. type == integer) integer else type_error }

Type checker simples E E[E] {E. type = if (E 2. type == integer

Type checker simples E E[E] {E. type = if (E 2. type == integer && E 1. type == array(s, t)) = t else type_error } E E^ {E. type = if (E 1. type == pointer(t)) t else type_error }

Regras Semânticas e Visitors • Definição dirigida por sintaxe é traduzida em visitors sobre

Regras Semânticas e Visitors • Definição dirigida por sintaxe é traduzida em visitors sobre a estrutura do programa Frequentemene o ambiente de tradução não é flexível o suficiente para definir sistemas de tipos que usam construções com estas. Por exemplo, if dentro de regras semânticas.

Exercício 1 • Escreva um visitor para fazer a checagem de tipos conforme definição

Exercício 1 • Escreva um visitor para fazer a checagem de tipos conforme definição anterior

Exercício 2 • Adicione regras semânticas para comandos S id = E S if

Exercício 2 • Adicione regras semânticas para comandos S id = E S if E then S S while E do S S S; S Extensão da linguagem

Resposta S id = E {S. type = if (lookup(id. entry) == E. type)

Resposta S id = E {S. type = if (lookup(id. entry) == E. type) void else type_error } S if E then S {S. type = if (E. type == boolean) S 1. type else type_error }

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

Resposta S while E do S {S. type = if (E. type == boolean) S 1. type else type_error } S S; S {S. type = if (S 1. type == void && S 2. type == void) void else type_error }

Exercício 3 • Modifique a gramática. Adicione tipo função e nova expressão para chamada

Exercício 3 • Modifique a gramática. Adicione tipo função e nova expressão para chamada de função (considere apenas 1 argumento)

Resposta T T T E E(E)

Resposta T T T E E(E)

Exercício 4 • Adicione regras semânticas às novas produções para realizar a checagem de

Exercício 4 • Adicione regras semânticas às novas produções para realizar a checagem de tipos

Resposta T T T {T. type = T 1. type T 2. type} E

Resposta T T T {T. type = T 1. type T 2. type} E E(E) {E. type = if (E 2. type == s && E 1. type == s t) t else type_error }

Conversão de tipo • Coerção: O compilador adiciona implicitamente função de conversão – Normalmente

Conversão de tipo • Coerção: O compilador adiciona implicitamente função de conversão – Normalmente não há perda de informação. Por exemplo, de int para float • Casting: O programador precisa explicitar void foo(double d) { …((int) k) * 10… } void interpret(Instruction insn) { switch (insn. opcode()) { case Opcode. IADD : exec. Arith((Arith. Instruction) insn)); break; …}

Tempo de checagem • Terminologia: “[Dynam|Stat]ically-typed language” • Statically-typed: checagem durante compilação • Dynamically-typed:

Tempo de checagem • Terminologia: “[Dynam|Stat]ically-typed language” • Statically-typed: checagem durante compilação • Dynamically-typed: erros de tipo são checados dinamicamente Motivo de grande debate até hoje! Dynamically-typed mais flexível (menos proibitivo) no uso de tipos, porém pode deixar escapar erros e checagem de tipos pode ser custosa.

Rigor do sistema de tipos • Strong vs. Weak Typing • Linguagens “strongly-typed” não

Rigor do sistema de tipos • Strong vs. Weak Typing • Linguagens “strongly-typed” não deixam escapar (maioria dos) erros de tipo p/ execução Diferença está na flexibilidade no uso de tipos. C permite fazer casting de tipos não relacionados. Na prática, algumas verificações só podem ser feitas dinamicamente. E. g. , índices de arrays.

Exemplos • • Dynamically-typed: Perl, PHP, Java. Script Statically-typed: C, Java, C# Strongly-typed: Java

Exemplos • • Dynamically-typed: Perl, PHP, Java. Script Statically-typed: C, Java, C# Strongly-typed: Java Weakly-typed: C

Polimorfismo Ad-hoc (sobrecarga) • Mesmo nome de função (ou operador) é usado em contextos

Polimorfismo Ad-hoc (sobrecarga) • Mesmo nome de função (ou operador) é usado em contextos diferentes • Exemplos – Java: operador + para strings, inteiros, reais – Ada: operador “()” usado para indexar arrays, chamada de funções, e conversão de tipos

Modificação da gramática E E 1 { E. types = E 1. types }

Modificação da gramática E E 1 { E. types = E 1. types } E id { E. types = lookup(id. entry) } E E (E) { E. types = { t | s E 2. types s t E 1. types}} Atributo armazena conjunto de tipos associados a um nó.

Polimorfismo de subtipo • Qualquer subtipo de T pode ser usado no contexto onde

Polimorfismo de subtipo • Qualquer subtipo de T pode ser usado no contexto onde objeto de tipo T é esperado • E. g. , Java Pode-se chamar foo passando qualquer void foo(T t) {…} subtipo de T como parâmetro.

Polimorfismo paramétrico • Facilita definição de funções que manipulam objetos com estruturas diferentes •

Polimorfismo paramétrico • Facilita definição de funções que manipulam objetos com estruturas diferentes • E. g. definição da função length para listas Está para linguagens funcionais assim como polimorfismo de subtipo está para OO. OO dá suporte com generics.

Exemplo positivo em Haskell t é uma variável de tipo. Neste caso, qualquer lista

Exemplo positivo em Haskell t é uma variável de tipo. Neste caso, qualquer lista é aceita como parâmetro. length : : [t] -> Int; length [] = 0 length (a: as) = 1 + length as

Exemplo negativo em Pascal type link = ^cell; cell = record info: integer; next:

Exemplo negativo em Pascal type link = ^cell; cell = record info: integer; next: link; end; function length (lptr : link) : integer; var len : integer; begin len = 0; while (lptr <> nil) do begin len : = len + 1; lptr : = lptr^. next; end; length : = len; end;

Resumo desta aula • Sistema de tipos em um compilador • Conceitos – Expressões

Resumo desta aula • Sistema de tipos em um compilador • Conceitos – Expressões de tipo – Sistema de tipo: definição com gramática de atributos e implementação usando visitors – Conversão de tipos (coerção e casting), tempo de checagem (estática e dinâmica), rigor da checagem (forte e fraca), polimorfismo (ad-hoc, subtipo, e paramétrico)