• Nenhum resultado encontrado

Compiladores-12

N/A
N/A
Protected

Academic year: 2021

Share "Compiladores-12"

Copied!
50
0
0

Texto

(1)

Análise Semântica

"Porque se perdoarem as ofensas uns dos outros, o Pai celestial também lhes perdoará. Mas se não perdoarem uns aos outros, o Pai celestial não lhes perdoará as ofensas."

(2)

Etapas da Compilação

Análise Léxica Análise Sintática Analise Semântica Geração de Código Intermediário Geração de Código Final

(3)

Sumário da Aula

Conceitos Básicos

Regras de Escopo

Tabela de Símbolos

Verificação de Tipos

(4)
(5)

Estático X Dinâmico

Estático

 É quando acontece durante a compilação

Dinâmico

 É quando acontece durante a execução  Ou o interpretador faz

(6)

Exemplos

Estático

 Alocação/desalocação de variáveis locais (C, Java)  Descoberta de tipos em expressões numéricas (C,

Java)

Dinâmico

Alocação na heap com a função malloc (em C)

Verificação de cast de uma classe para outra classe

“ancestral” dela (em Java)

(7)

Análise Semântica

Faz verificações estáticas sobre o código fonte

 Exemplo: Se as variáveis usadas foram declaradas

Prepara para etapas posteriores, acrescentando

informações

 Exemplo: Para cada nome de variável usado,

(8)

Atenção: Semântica X Análise

Semântica

 Semântica da Linguagem

 Parte conceitual da linguagem

 Envolve tudo que diz respeito ao significado de um programa

 Envolve características estáticas e dinâmicas

 Interfere no desenvolvimento de todas as fases posteriores à análise sintática

 Análise Semântica

 Parte do compilador

 Verifica apenas algumas das regras da semântica da linguagem  Outro nome usado (mais adequado) é "Análise Contextual"

(9)

Análise Semântica

 Dois papéis principais de um analisador semântico:

Verificar (ou tratar) escopo (ou o acesso a nomes)Verificar (ou tratar) tipos

 Observações:

1. Esta divisão tem propósitos didáticos apenas. As duas etapas são interligadas.

2. Estas etapas não apenas verificam se está certo ou errado. Elas também coletam informações e armazenam na árvore (se ela for criada).

(10)
(11)

Análise Semântica

Em essência, o papel de verificar escopo

consiste principalmente em:

1. Associar as ocorrências de nomes com as suas

declarações respectivas

 Por exemplo: Uma ocorrência do nome “temp” é uma

variável local ou global? De que tipo?

(12)

Exemplos

int alfa; int main() { int beta; [...] x = 10*beta + alfa; }

(13)

Análise Semântica

Porém, como consequência, a verificação de

escopo também pode envolver outras ações:

2. Identificar erros como: nomes não declarados,

declarações duplicadas, etc.

3. Verificar se o acesso obedece restrições impostas

pelos modificadores de acessos

(14)

Exemplos

(15)

Verificações de Escopo

Nomes (ou identificadores) – são strings

definidas pelo usuário para identificar

 Variáveis  Funções  Classes  Etc.

Escopo – partes do código onde um nome (ou

(16)

Regras de Escopo

As verificações dependem das regras de

escopo da linguagem

Regras de escopo

 Dizem em que pontos do programa um nome é válido  Dizem como cada uso de um nome deve ser ligado à

(17)

Tipos de Escopo

As regras de escopo das linguagens podem ser

de dois tipos

 Escopo estático

(18)

Escopo Estático

O escopo de um nome está implicitamente

definido pelo lugar onde o nome foi declarado

(19)

Escopo Estático

Em escopo estático, pode haver uma estrutura

hierárquica de escopos

 Exemplo: blocos aninhados

Variáveis de um escopo mais interno acessam

variáveis do escopo externo, mas não o

contrário

Nome escondido

 Quando é definido um nome igual a outro de um

(20)

Escopo Estático

Blocos aninhados (C ou Java)

Qual o valor de b ? int a = 1; int b = 10; { int a = 2; b += a; } b += a;

(21)

Escopo Dinâmico

Um nome local dentro de um procedimento só

será associado a alguma declaração quando o

procedimento for chamado

Muito pouco usado

Pode ser simulado com macros em C ou com

(22)

Simulando Escopo Dinâmico

em C

A variável inc na macro INC() é tratada parecido com

o que acontece em escopo dinâmico

#define INC(x) (x + inc) int main() { int inc = 1; printf("%d\n", INC(1)); } void func() { float inc = 1.2; printf("%f\n", INC(1)); }

(23)

Simulando Escopo Dinâmico

em Python

A avaliação de expressao_str dá diferentes valores porque o “x”

que ela referencia funciona como uma variável de escopo dinâmico

def funcao1(): x = 5

print "funcao1:", eval(expressao_str) x = 0

expressao_str = "x+10"

print "global:", eval(expressao_str) funcao1()

(24)

Escopo Estático e OO

 Classes introduzem um novo escopo para os seus

membros

 Acesso interno normal

 Porém, esses membros podem ser acessados por

escopos externos

Sintaxe em Java: <obj>.<membro>

 Modificadores podem restringir o acesso externo

 Lembrando que verificar se o acesso é válido é uma possível ação da Análise Semântica

(25)

Resumo dos Tipos de Escopo

Dos tipos de escopo, o escopo estático exige

mais ações da análise semântica

 Justamente por ser estático (em tempo de

compilação)...

Já o escopo dinâmico não requer muitas

verificações da análise semântica

 Porém, o código final tem que ser mais complexo (a

(26)

Análise Semântica

Como manter as informações sobre as

(27)
(28)

Tabela de Símbolos

Guarda informações importantes relacionadas a

cada nome (identificador)

Operações básicas

get ou lookup – recebe um nome e retorna as

informações

put – recebe um nome e a informação relacionada à

(29)

Tabela de Símbolos

A informação a ser guardada depende da

necessidade

Exemplos

 Associar uma variável com o lugar onde foi declarado  Associar uma classe com outra tabela de símbolos

(para guardar os membros da classe)

 Associar um procedimento com o seu tipo de retorno

(30)

Tabela de Símbolos

Implementação

 Lista

 Ineficiente

 Hash table

 Eficiente, mas difícil de implementar

 Java oferece as classes Hashtable e HashMap  Python oferece dicionários

(31)

Tabela de Símbolos

Implementação de escopos aninhados

 Cada escopo terá uma tabela de símbolos própria

 A tabela geral será uma pilha destas tabelas

 A cada início de um novo bloco, cria uma nova tabela

para o escopo e empilha

(32)

Tabela de Símbolos

Implementação de escopos aninhados (cont.)

A operação put irá adicionar na tabela que está no

topo da pilha

A operação de get deverá procurar, primeiramente,

na tabela do topo; se não encontrar, continua a busca na tabela imediatamente abaixo e assim sucessivamente...

(33)
(34)

Verificações de Tipo

O analisador semântico cumpre o papel de

verificador de tipos quando realiza ações para

garantir que os dados estão sendo manipulados

de maneira coerente com o tipo deles

Essas ações dependem das regras de tipo da

linguagem

 Veremos a seguir várias possíveis das ações que

uma linguagem pode exigir do analisador semântico...

(35)

Verificações de Tipo

1) Testa se as operações recebem operandos dos

tipos válidos

 Também infere o tipo resultante da operação

 Exemplo: O projeto

 O operador “+" só pode ser aplicado a dois operandos

numéricos de mesmo tipo (int com int ou float com float)

A expressão 1 + 2 é válida e é do tipo intA expressão 2.0 + 1 é inválida

(36)

Verificações de Tipo

2) Cria conversões automáticas, onde for

aplicável

São chamadas coerções

 Exemplo: C ou Java

Em uma multiplicação "1 * 3.13" (entre um inteiro e um

float), o operando 1 é convertido para o valor float 1.0 (internamente, na árvore)

(37)

Verificações de Tipo

3) Decide qual a verdadeira operação a ser executada em caso de overloading de operadores

Overloading (sobrecarga): múltiplas definições (ou declarações) para um mesmo operador (ou para um procedimento de mesmo nome)

 A Análise Semântica pode “anotar” na árvore qual a declaração específica a ser considerada

 Exemplo: Java

 O token "+" é usado para soma de inteiros, soma de floats, etc e para concatenação de strings

 A escolha da operação certa depende dos operandos

(38)

Parâmetros Formais e Reais

Parâmetros formais – são especificados na definição

da função

No exemplo: a e b

Parâmetros reais – são passados na chamada à função

No exemplo: 2*x e 10

void func(int a, char b) ... int main() {

func(2*x, 10); }

(39)

Verificações de Tipo

4) Verifica parâmetros em chamadas de

procedimentos

Verifica se a quantidade de parâmetros está correta

Se o tipo de cada parâmetro real corresponde ao

tipo esperado pelo respectivo parâmetro formal

 Verifica a ordem

 Obs.: As informações dos parâmetros podem ser

guardadas na tabela de símbolos, associadas ao nome do procedimento

(40)

Verificações de Tipo

5) Verifica se o lado esquerdo de uma atribuição

pode guardar valor

 Em algumas linguagens (como C), a atribuição é um

operador como outro qualquer (como +, -, etc.)

 Porém, a expressão do lado esquerdo, precisa

representar locais de memória que guardam valores (ex.: variáveis)

(41)

Verificações de Tipo

5) (cont.)

 Exemplos: linguagem C  Correto:  Incorreto: int array[10]; array[0] = 3; *(array + 1) = 3; (1020) = 3;

(42)

Verificações de Tipo

6) Verifica expressões nos comandos

Se a expressão de teste em um if é do tipo booleano

(em Java)

Se a expressão usada em um return é do mesmo

tipo que a função/método (em C e Java)

Se a expressão em um switch é de um tipo primitivo

e se os cases são para literais desse mesmo tipo primitivo (em C)

(43)

Verificações de Tipo

7) Tratar novos tipos de dados definidos pelo usuário (especialmente em linguagens OO)

 Quando um usuário define novos tipos (no código fonte de uma linguagem X), a Análise Semântica (da linguagem X) deve

adaptar-se para lidar com esse tipo

Exemplo 1: Em Java, você pode criar um classe C. Depois disso, o compilador permite definir variáveis do tipo C.

 Exemplo 2: C++

O usuário pode definir um novo tipo Racional (para números racionais) e definir (overload) o operador + para este tipo

O compilador, então, passará a aceitar variáveis do tipo Racional e irá aceitar o + nestas variáveis

(44)

Verificações

 Estes sete casos são apenas exemplos de verificações

de tipo

 Tirados das linguagens mais comuns (C e Java, em especial)

 Dependendo da linguagem pode haver outras

verificações distintas

O importante é entender o conceito geral de verificação

de tipo

(45)
(46)

Outras Verificações

Além das verificações de acesso a nomes e

verificações de tipo, a Análise Semântica pode:

 Verificar se uma variável declarada não foi usada  Verificar se um comando é inatingível

 Verificar se falta retornar valor em algum ponto de

um procedimento

(47)
(48)

Análise Semântica

A Análise Semântica não só identifica erros

No decorrer dela, o compilador também obtém

mais informações sobre o código

 Tipos de cada expressão, associação entre os

nomes e suas declarações, etc.

Estas informações são necessárias para as

(49)

Análise Semântica

Se esta etapa for realizada sobre a árvore

sintática, as informações podem ser

acrescentadas na árvore

A saída seria uma árvore sintática anotada

A tabela de símbolos é auxiliar nesse processo

de obtenção de informações e anotação da

árvore

(50)

Análise Semântica – Resumo

Objetivos

 Verifica estaticamente a consistência da árvore

sintática de acordo com as regras de escopo e de tipo da linguagem

 Acrescenta à arvore informações sobre a

organização lógica código

Entrada/Saída

 Entrada: árvore sintática

Referências

Documentos relacionados

Após o escoamento do pré-polímero e catalisador, é necessário que o material seja transferido para o processo posterior de mistura, assim foi aplicado um conjunto com

type (because they necessarily end after a nite period of time), then the wait-for graph, call it ~W , that represents processes' waits in this global state is a directed graph

O artigo apresenta discussões sistematizadas através da realização de pesquisa bibliográfica, cujo objetivo centrou-se em “identificar as contribuições da teoria interacionista

A) Descontaminação da amostra, moagem mecânica, secagem até peso constante, armazenamento das amostras, nova secagem das subamostras antes da análise química. B) Secagem até

Face às reavaliações dos imóveis ocorridas em 2008 e 2009, devidamente apresentado no Balanço de 2009, as despesas com as depreciações dos imóveis reavaliados foram

A pesquisa será realizada na turma de primeiro ano do Ensino Médio, turma 103 e primeiramente será realizada uma pesquisa teórica sobre o que é Síndrome de Down e quais

Desta forma direcionamos nosso estudo aos problemas relacionados à população de trabalhadores da saúde que podem ser afetados pelo estresse, em consonância

Realizar um planejamento de capacidade de longo prazo para es- timar a quantidade de recursos necessários para execução de uma carga de trabalho e, assim, estabelecer bons contratos