analise semantica[mododecompatibilidade].pdf
TRANSCRIPT
INF25 – Compiladores
Análise Semântica
2
Etapas da Compilação
Análise Léxica
Análise Sintática
Analise Semântica
Geração de CódigoIntermediário
Geração de CódigoFinal
3
Sumário da Aula Conceitos Básicos Regras de Escopo Tabela de Símbolos Verificação de Tipos
Conceitos Básicos
5
Estático X Dinâmico Estático
É quando acontece durante a compilação
Dinâmico É quando acontece durante a execução
6
Estático X Dinâmico Estático
Alocação/desalocação de variáveis locais Descoberta de tipos em expressões
numéricas
Dinâmico Alocação na heap com malloc (em C) Verificação de cast de classes (em Java) Verificação de limites de arrays (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 Exemplo: Para cada nome de variável
usado, descobre se ele é local ou global, qual o tipo, etc.
8
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 principais aspectos tratados pela
análise semântica
Regras de escopo
Regras de tipo (verificação de tipos)
Regras de Escopo
11
Regras de Escopo Escopo – partes do código onde um nome é
válido Variáveis, classes, procedimentos, tipos abstratos
Regras de escopo Dizem em que pontos do programa um nome é
válido Dizem como cada ocorrência de um nome deve
ser ligada à sua definição
12
Tipos de Escopo Existem dois tipos de escopo
Estático
Dinâmico
13
Escopo Estático O escopo de um nome está
implicitamente definido pelo lugar onde foi declarado
É o tipo mais conhecido
14
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
escopo mais externo
15
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;
16
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 permitem controle sobre o acesso externo aos nomes
17
Escopo Dinâmico Um nome local em um procedimento só
será associado a alguma declaração quando o procedimento for chamado
Muito pouco usado
Pode ser simulado com macros em C...
18
Escopo Dinâmico 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() {int inc = 10;printf("%d\n", INC(1));
}
19
Análise Semântica Percorre o código fonte identificando
usos de nomes e associando-os às suas declarações respectivas Levando em consideração o tipo de escopo
Exemplos de uso de nomes...
20
Análise Semântica Como manter as informações sobre as
declarações?
Tabela de Símbolos
22
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 à ele e guarda esse par
23
Tabela de Símbolos A informação a ser guardada depende da
necessidade
Exemplos Associa uma variável com o lugar onde foi
declarado
Associa uma classe com outra tabela de símbolos (para sua lista de membros)
Associa um procedimento com o seu tipo de retorno e à sua lista de parâmetros
24
Tabela de Símbolos Implementação
Lista Ineficiente
Hash table Eficiente, mas difícil de implementar Java oferece as classes Hashtable e HashMap C++ oferece o template "map"
25
Tabela de Símbolos Implementação de escopos aninhados
Cada escopo terá uma (sub)tabela própria
A tabela geral será uma pilha dessas tabelas de escopos
A cada início de um novo bloco, cria uma nova tabela para o escopo e empilha
Ao fim do bloco, desempilha
26
Tabela de Símbolos Implementação de escopos aninhados
(cont.) Uma operação put irá adicionar na tabela
que está no topo da pilha
Uma operação de get deverá procurar, primeiramente, na tabela do topo; se não encontrar, continua a busca na tabela imediatamente abaixo
Verificação de Tipos
28
Verificação de Tipos O analisador semântico pode realizar
diversas verificações relacionadas aos tipos de dados
Veremos a seguir...
29
Verificação de Tipos Testa se as operações recebem
operandos dos tipos válidos
Infere tipos de expressões
Exemplo: O projeto O operador "&&" só pode ser aplicada a
dois operandos inteiros O resultado é inteiro
30
Verificação de Tipos 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 internamente para o valor float 1.0
31
Verificação de Tipos Decide qual a verdadeira operação a ser
executada em caso de overloading de operadores
Exemplo: Java O operador "+" é usado para soma de
valores numéricos e concatenação de strings
A escolha da operação certa depende dos operandos
32
Verificação de Tipos Verifica parâmetros em chamadas de
procedimentos
Se a quantidade de parâmetros está correta
Se o tipo de cada parâmetro realcorresponde ao tipo do respectivo parâmetro formal
33
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);
}
34
Verificação de Tipos Verifica se o lado esquerdo de uma
atribuição pode guardar valor
Correto
Incorreto
int array[10];array[0] = 3;*(array + 1) = 3;
(1020) = 3;
35
Análise Semântica Como vimos, no decorrer de toda a análise
semântica o compilador obtém mais informações sobre cada trecho de código Tipos de cada expressão, associação entre os
nomes e suas declarações, etc. Útil para as etapas posteriores da compilação
Se esta etapa for realizada sobre a árvore sintática, muitas dessas informações podem ser acrescentadas na árvore A saída seria uma árvore sintática anotada
36
Análise Semântica Objetivos
Verifica estaticamente a consistência da árvore sintática por meio da aplicação de regras da linguagem
Acrescenta à arvore informações sobre a estrutura lógica código
Entrada/Saída Entrada: árvore sintática Saída: árvore sintática anotada
Exercícios
A seguir serão mostrados alguns exemplos de compiladores simples que podem ser construídos com os conceitos vistos na disciplina de compiladores.
Obs.: Grupos de no máximo 2 pessoas.
38
Gerador de Compiladores Dada uma linguagem para definir gramáticas livres de contexto,
implemente um processador que produza uma tabela LL(1) necessária para implementação de um reconhecedor dessa gramática.
Entrada Saída
X “a” XX “b” YY “c”Y “d” Y
a b c d X a X b Y error errorY error error c d Y
39
Menus Defina uma linguagem para representação de menus de uma interface
gráfica e um gerador de código que produza uma implementação para menus a partir dessa descrição.
Código Fonte Tradução
menu M {submenu File {
Item OpenItem Exit
}submenu Edit {
Item CopyItem CutItem Paste
}}
class M {MenuBar main;SubMenu m1, m2;M() {
main = new MenuBar();m1 = new SubMenu(“File”);m1.add(“Open”); m1.add(“Exit”); m2 = new SubMenu(“Edit”);m2.add(“Copy”); m2.add(“Paste”);main.add(m1);main.add(m2);
}}
40
Gerador de Árvores Sintáticas Dada uma linguagem para definição de árvores sintáticas, produza um
gerador que automaticamente implemente a árvore sintática reconhecida
Entrada Código Compilado
Tree Exp = ConstNum(int) |Soma(Exp,Exp).
Tree Cmd = If (Exp, Cmd, Cmd) |Skip.
class Exp { }class ConstNum extends Exp { int n1; }class Soma extends Exp { Exp n1,n2; }
class Cmd { }class If extends Cmd { Exp n1; Cmd n2; Cmd n3; }class Skip extends Cmd { }
41
Validador XML De forma simplificada, a linguagem XML é formada
por textos e marcações (<tag> Texto XML </tag>) . Construa um processador que reconheça um arquivo XML e faça as seguintes verificações:
Se o nome da marcação que encerra uma seção do documento é o mesmo que inicia uma seção (Identificar documentos com erros da forma: <HTML> Texto </TITLE>)
Construa uma função que automaticamente substitua um “tag” por um documento XML (de “<A> oi </A>” para “<BOLD> <ITALICO> oi </ITALICO> </BOLD>”)