A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

CES-41 COMPILADORES Capítulo I Introdução. Capítulo I - Introdução 1.1 – Compiladores 1.2 – Estrutura de um compilador 1.3 – Interpretadores 1.4 – Automação.

Apresentações semelhantes


Apresentação em tema: "CES-41 COMPILADORES Capítulo I Introdução. Capítulo I - Introdução 1.1 – Compiladores 1.2 – Estrutura de um compilador 1.3 – Interpretadores 1.4 – Automação."— Transcrição da apresentação:

1 CES-41 COMPILADORES Capítulo I Introdução

2 Capítulo I - Introdução 1.1 – Compiladores 1.2 – Estrutura de um compilador 1.3 – Interpretadores 1.4 – Automação da construção de compiladores

3 1.1 – Compiladores – Definição Compilador é um software que Compilador é um software que Lê um programa escrito numa linguagem: a linguagem- fonte (é o programa-fonte) Lê um programa escrito numa linguagem: a linguagem- fonte (é o programa-fonte) Traduz em um programa equivalente, escrito noutra linguagem : a linguagem-objeto (é o programa-objeto) Traduz em um programa equivalente, escrito noutra linguagem : a linguagem-objeto (é o programa-objeto) Reporta a presença de erros no programa-fonte Reporta a presença de erros no programa-fonte

4 Esquematicamente: Compilador Programa fonte Programa objeto Mensagens de erro

5 Possíveis linguagens-fontes: Mais comuns: linguagens tradicionais de programação: Fortran, Pascal, C, Modula-2, C++, Java, etc. Mais comuns: linguagens tradicionais de programação: Fortran, Pascal, C, Modula-2, C++, Java, etc. Linguagens especializadas: simulação, computação gráfica, banco de dados, experimentos Linguagens especializadas: simulação, computação gráfica, banco de dados, experimentos Possíveis linguagens-objetos: Mais comuns: linguagem assembly ou linguagem de máquina de vários computadores Mais comuns: linguagem assembly ou linguagem de máquina de vários computadores Outras linguagens de programação Outras linguagens de programação

6 Exemplos de linguagens de programação como linguagens-objetos: Transformação de programas sequenciais escritos em C ou Fortran, em programas paralelos escritos em HPF (High Performance Fortran) Transformação de programas sequenciais escritos em C ou Fortran, em programas paralelos escritos em HPF (High Performance Fortran) for (i = 1; i <= n; i++) C[i] = A[i] + B[i] do parallel i = 1, n C[i] = A[i] + B[i] for (i = 1; i <= n; i++) C[i] = A[i] + C[i-1] do parallel i = 1, n C[i] = A[i] + C[i-1 ]

7 Tradução de programas realizadores de certos experimentos: Tradução de programas realizadores de certos experimentos: Escritos numa linguagem especializada Escritos numa linguagem especializada Traduzidos (compilados) para uma linguagem de programação como C Traduzidos (compilados) para uma linguagem de programação como C Compilados depois por um compilador similar ao de C Compilados depois por um compilador similar ao de C Programas em Lex e Yacc são traduzidos para C Programas em Lex e Yacc são traduzidos para C Lex e Yacc são linguagens especializadas para construir componentes de um compilador Lex e Yacc são linguagens especializadas para construir componentes de um compilador

8 Enfoque desta disciplina: A linguagem-fonte é uma linguagem tradicional e a linguagem-objeto é o Assembly de uma máquina A linguagem-fonte é uma linguagem tradicional e a linguagem-objeto é o Assembly de uma máquina Para a implementação, a linguagem-fonte é Lex e Yacc e a linguagem-objeto é C Para a implementação, a linguagem-fonte é Lex e Yacc e a linguagem-objeto é C

9 1.1.2 – O contexto de um compilador Além do compilador, outros programas são exigidos para criar um programa executável nalguma máquina Além do compilador, outros programas são exigidos para criar um programa executável nalguma máquina

10 Pré-processador Programa fonte Compilador Programa objeto em Assembly Montador Código de máquina com endereçamento deslocado Editor de Ligações Bibliotecas e outros arquivos com endereçamento deslocado Código de máquina executável com endereçamento deslocado Carregador Código de máquina executável com endereçamento correto Programa fonte com diretivas de pré-processamento

11 a) Pré-processador – realiza várias tarefas antes da compilação: Inclusão de arquivos ao programa – Por exemplo, na Linguagem C: Inclusão de arquivos ao programa – Por exemplo, na Linguagem C: #include : inclui protótipos de funções matemáticas pertencentes à biblioteca da linguagem; essas funções já estão em linguagem de máquina #include : inclui protótipos de funções matemáticas pertencentes à biblioteca da linguagem; essas funções já estão em linguagem de máquina #include sistemas.c: inclui arquivo pertencente ao acervo do programador; contém código fonte #include sistemas.c: inclui arquivo pertencente ao acervo do programador; contém código fonte

12 Processamento de macros – para abreviar construções longas Exemplo, em C, com as macros: Exemplo, em C, com as macros: #define EHPAR(x) (((x)%2)?0:1) #define ERRO(msg) printf (ERRO: % s/n, msg) pode-se escrever comandos dos tipos: if (EHPAR(a+b)) ; if (valor max) ERRO(valor muito grande); O resultado do pré-processamento é: if ((((a+b)%2)?0:1)) ; if (valor > max) printf(ERRO:%s\n,valor muito grande); O pré-processador substitui a primeira parte do #define pela segunda, realizando inclusive passagem de argumentos

13 Processamento de extensões de linguagens: Algumas linguagens são acrescidas de certos artifícios para propósitos específicos de certas aplicações Algumas linguagens são acrescidas de certos artifícios para propósitos específicos de certas aplicações Exemplos: comandos para manipular banco de dados, para computação gráfica, processamento paralelo, etc. Exemplos: comandos para manipular banco de dados, para computação gráfica, processamento paralelo, etc. Muitas linguagens são, na realidade, extensões da Linguagem C Muitas linguagens são, na realidade, extensões da Linguagem C Diretivas iniciadas pelos caracteres ## são substituídas pelo pré-processador por chamadas de funções, comandos do sistema operacional, etc. Diretivas iniciadas pelos caracteres ## são substituídas pelo pré-processador por chamadas de funções, comandos do sistema operacional, etc.

14 b) Montador (Assembler): Transforma o código Assembly, produzido pelo compilador, em código de máquina relocável Transforma o código Assembly, produzido pelo compilador, em código de máquina relocável Exemplo: programa em C para o cálculo do fatorial de um número digitado e seus correspondentes em Assembly e em linguagem de máquina Exemplo: programa em C para o cálculo do fatorial de um número digitado e seus correspondentes em Assembly e em linguagem de máquina Supõe-se uma CPU bem simples, com apenas um registrador de propósitos gerais (AC - acumulador) Supõe-se uma CPU bem simples, com apenas um registrador de propósitos gerais (AC - acumulador) Para fazer C = A + B Sendo A, B e C endereços de memória InstruçãoSignificado LD A AC Mem(A) ADD B AC AC + Mem(B) ST C Mem(C) AC

15 #include void main ( ) { int n, fat, i; scanf (%d, &n); fat = 1; i = 2; while (i <= n) { fat = fat * i; i = i + 1; } printf (%d, fat); } Primeiramente, reserva de espaço para as constantes 1 e 2 C1:CONST1 C2:CONST2

16 #include void main ( ) { int n, fat, i; scanf (%d, &n); fat = 1; i = 2; while (i <= n) { fat = fat * i; i = i + 1; } printf (%d, fat); } Em seguida, reserva de espaço para as variáveis n, i, fat C1:CONST1 C2:CONST2 n:CONST0 fat:CONST0 i:CONST0

17 #include void main ( ) { int n, fat, i; scanf (%d, &n); fat = 1; i = 2; while (i <= n) { fat = fat * i; i = i + 1; } printf (%d, fat); } Agora a tradução dos comandos C1:CONST1 C2:CONST2 n:CONST0 fat:CONST0 i:CONST0

18 #include void main ( ) { int n, fat, i; scanf (%d, &n); fat = 1; i = 2; while (i <= n) { fat = fat * i; i = i + 1; } printf (%d, fat); } C1:CONST1 C2:CONST2 n:CONST0 fat:CONST0 i:CONST0 inic:READn Na realidade, a tradução de scanf é algo mais complexo: É uma chamada de subprograma Rótulo da 1ª instrução executável: inic

19 #include void main ( ) { int n, fat, i; scanf (%d, &n); fat = 1; i = 2; while (i <= n) { fat = fat * i; i = i + 1; } printf (%d, fat); } C1:CONST1 C2:CONST2 n:CONST0 fat:CONST0 i:CONST0 inic:READn LDC1 STfat LDC2 STi Rótulo da 1ª instrução executável: inic

20 #include void main ( ) { int n, fat, i; scanf (%d, &n); fat = 1; i = 2; while (i <= n) { fat = fat * i; i = i + 1; } printf (%d, fat); } C1:CONST1 C2:CONST2 n:CONST0 fat:CONST0 i:CONST0 inic:READn LDC1 STfat LDC2 STi loop:SUBn JPescrever JUMPloop Rótulo da 1ª instrução executável: inic escrever é o rótulo da instrução logo após JUMP

21 #include void main ( ) { int n, fat, i; scanf (%d, &n); fat = 1; i = 2; while (i <= n) { fat = fat * i; i = i + 1; } printf (%d, fat); } C1:CONST1 C2:CONST2 n:CONST0 fat:CONST0 i:CONST0 inic:READn LDC1 STfat LDC2 STi loop:SUBn JPescrever LDfat MULTi STfat LDi ADDC1 STi JUMPloop Rótulo da 1ª instrução executável: inic

22 #include void main ( ) { int n, fat, i; scanf (%d, &n); fat = 1; i = 2; while (i <= n) { fat = fat * i; i = i + 1; } printf (%d, fat); } C1:CONST1 C2:CONST2 n:CONST0 fat:CONST0 i:CONST0 inic:READn LDC1 STfat LDC2 STi loop:SUBn JPescrever LDfat MULTi STfat LDi ADDC1 STi JUMPloop escrever:WRITEfat Rótulo da 1ª instrução executável: inic Na realidade, a tradução de printf é algo mais complexo: É uma chamada de subprograma

23 #include void main ( ) { int n, fat, i; scanf (%d, &n); fat = 1; i = 2; while (i <= n) { fat = fat * i; i = i + 1; } printf (%d, fat); } C1:CONST1 C2:CONST2 n:CONST0 fat:CONST0 i:CONST0 inic:READn LDC1 STfat LDC2 STi loop:SUBn JPescrever LDfat MULTi STfat LDi ADDC1 STi JUMPloop escrever:WRITEfat STOP ENDinic Rótulo da 1ª instrução executável: inic

24 #include void main ( ) { int n, fat, i; scanf (%d, &n); fat = 1; i = 2; while (i <= n) { fat = fat * i; i = i + 1; } printf (%d, fat); } C1:CONST1 C2:CONST2 n:CONST0 fat:CONST0 i:CONST0 inic:READn LDC1 STfat LDC2 STi loop:SUBn JPescrever LDfat MULTi STfat LDi ADDC1 STi JUMPloop escrever:WRITEfat STOP ENDinic Final da compilação Agora vem a montagem

25 C1:CONST 1 C2:CONST 2 n:CONST 0 fat:CONST 0 i:CONST 0 inic:READ n LD C1 ST fat LD C2 ST i loop:SUB n JP escrever LD fat MULT i ST fat LD i ADD C1 ST i JUMP loop escrever:WRITE fat STOP END inic endereçocodopender rótuloendereço O Assembler monta uma tabela de rótulos para ajudar a preencher o programa em linguagem de máquina

26 C1:CONST 1 C2:CONST 2 n:CONST 0 fat:CONST 0 i:CONST 0 inic:READ n LD C1 ST fat LD C2 ST i loop:SUB n JP escrever LD fat MULT i ST fat LD i ADD C1 ST i JUMP loop escrever:WRITE fat STOP END inic endereçocodopender rótuloendereço MnemônicoCod Op LD1 ST2 ADD4 SUB5 MULT6 JUMP11 JP14 READ15 WRITE16 STOP17

27 C1:CONST 1 C2:CONST 2 n:CONST 0 fat:CONST 0 i:CONST 0 inic:READ n LD C1 ST fat LD C2 ST i loop:SUB n JP escrever LD fat MULT i ST fat LD i ADD C1 ST i JUMP loop escrever:WRITE fat STOP END inic endereçocodopender rótuloendereço C10 C21 n2 fat3 i4 MnemônicoCod Op LD1 ST2 ADD4 SUB5 MULT6 JUMP11 JP14 READ15 WRITE16 STOP17

28 C1:CONST 1 C2:CONST 2 n:CONST 0 fat:CONST 0 i:CONST 0 inic:READ n LD C1 ST fat LD C2 ST i loop:SUB n JP escrever LD fat MULT i ST fat LD i ADD C1 ST i JUMP loop escrever:WRITE fat STOP END inic endereçocodopender rótuloendereço C10 C21 n2 fat3 i4 inic5 MnemônicoCod Op LD1 ST2 ADD4 SUB5 MULT6 JUMP11 JP14 READ15 WRITE16 STOP17

29 C1:CONST 1 C2:CONST 2 n:CONST 0 fat:CONST 0 i:CONST 0 inic:READ n LD C1 ST fat LD C2 ST i loop:SUB n JP escrever LD fat MULT i ST fat LD i ADD C1 ST i JUMP loop escrever:WRITE fat STOP END inic endereçocodopender rótuloendereço C10 C21 n2 fat3 i4 inic5 MnemônicoCod Op LD1 ST2 ADD4 SUB5 MULT6 JUMP11 JP14 READ15 WRITE16 STOP17

30 C1:CONST 1 C2:CONST 2 n:CONST 0 fat:CONST 0 i:CONST 0 inic:READ n LD C1 ST fat LD C2 ST i loop:SUB n JP escrever LD fat MULT i ST fat LD i ADD C1 ST i JUMP loop escrever:WRITE fat STOP END inic endereçocodopender rótuloendereço C10 C21 n2 fat3 i4 inic5 loop10 MnemônicoCod Op LD1 ST2 ADD4 SUB5 MULT6 JUMP11 JP14 READ15 WRITE16 STOP17

31 C1:CONST 1 C2:CONST 2 n:CONST 0 fat:CONST 0 i:CONST 0 inic:READ n LD C1 ST fat LD C2 ST i loop:SUB n JP escrever LD fat MULT i ST fat LD i ADD C1 ST i JUMP loop escrever:WRITE fat STOP END inic endereçocodopender ??? rótuloendereço C10 C21 n2 fat3 i4 inic5 loop10 escrever??? MnemônicoCod Op LD1 ST2 ADD4 SUB5 MULT6 JUMP11 JP14 READ15 WRITE16 STOP17

32 C1:CONST 1 C2:CONST 2 n:CONST 0 fat:CONST 0 i:CONST 0 inic:READ n LD C1 ST fat LD C2 ST i loop:SUB n JP escrever LD fat MULT i ST fat LD i ADD C1 ST i JUMP loop escrever:WRITE fat STOP END inic endereçocodopender ??? rótuloendereço C10 C21 n2 fat3 i4 inic5 loop10 escrever??? MnemônicoCod Op LD1 ST2 ADD4 SUB5 MULT6 JUMP11 JP14 READ15 WRITE16 STOP17

33 C1:CONST 1 C2:CONST 2 n:CONST 0 fat:CONST 0 i:CONST 0 inic:READ n LD C1 ST fat LD C2 ST i loop:SUB n JP escrever LD fat MULT i ST fat LD i ADD C1 ST i JUMP loop escrever:WRITE fat STOP END inic endereçocodopender rótuloendereço C10 C21 n2 fat3 i4 inic5 loop10 escrever19 MnemônicoCod Op LD1 ST2 ADD4 SUB5 MULT6 JUMP11 JP14 READ15 WRITE16 STOP17

34 C1:CONST 1 C2:CONST 2 n:CONST 0 fat:CONST 0 i:CONST 0 inic:READ n LD C1 ST fat LD C2 ST i loop:SUB n JP escrever LD fat MULT i ST fat LD i ADD C1 ST i JUMP loop escrever:WRITE fat STOP END inic endereçocodopender rótuloendereço C10 C21 n2 fat3 i4 inic5 loop10 escrever19 MnemônicoCod Op LD1 ST2 ADD4 SUB5 MULT6 JUMP11 JP14 READ15 WRITE16 STOP17

35 C1:CONST 1 C2:CONST 2 n:CONST 0 fat:CONST 0 i:CONST 0 inic:READ n LD C1 ST fat LD C2 ST i loop:SUB n JP escrever LD fat MULT i ST fat LD i ADD C1 ST i JUMP loop escrever:WRITE fat STOP END inic endereçocodopender rótuloendereço C10 C21 n2 fat3 i4 inic5 loop10 escrever19 Endereço inicial da execução: 5 Essa informação deve acompanhar o programa em linguagem de máquina

36 O programa em linguagem C é o programa-fonte O programa em linguagem C é o programa-fonte O programa gerado pelo Assembler é o programa-objeto O programa gerado pelo Assembler é o programa-objeto O programa-objeto foi montado a partir do endereço zero da RAM O programa-objeto foi montado a partir do endereço zero da RAM Esse programa é guardado num arquivo (extensão obj) Esse programa é guardado num arquivo (extensão obj) endereçocodopender Endereço inicial da execução: 5

37 O local para execução é estabelecido pelo sistema operacional do computador O local para execução é estabelecido pelo sistema operacional do computador Esse local depende da disponibilidade da RAM Esse local depende da disponibilidade da RAM E se o local não for o endereço zero (por exemplo, endereço 3000)? E se o local não for o endereço zero (por exemplo, endereço 3000)? endereçocodopender Endereço inicial da execução: 5

38 Os locais para C1, C2, n, fat e i não são mais 0, 1, 2, 3 e 4, mas sim 3000, 3001, 3002, 3003 e 3004 Os locais para C1, C2, n, fat e i não são mais 0, 1, 2, 3 e 4, mas sim 3000, 3001, 3002, 3003 e 3004 Os rótulos inic, loop e escrever mudarão para os endereços 3005, 3010 e 3019 Os rótulos inic, loop e escrever mudarão para os endereços 3005, 3010 e 3019 Então todos os campos ender das instruções estarão com um erro (deslocamento de 3000 posições) Então todos os campos ender das instruções estarão com um erro (deslocamento de 3000 posições) Isso tem de ser corrigido antes da execução Isso tem de ser corrigido antes da execução endereçocodopender Endereço inicial da execução: 3005

39 c) Editor de ligações Antes de corrigir os endereços do programa-objeto, é necessário juntar a ele todos os subprogramas auxiliares pertencentes à biblioteca da linguagem Antes de corrigir os endereços do programa-objeto, é necessário juntar a ele todos os subprogramas auxiliares pertencentes à biblioteca da linguagem Exemplos: funções para entrada e saída (scanf, printf, etc.), funções matemáticas (sqr, pow, sqrt, log, sin, cos, etc.) Exemplos: funções para entrada e saída (scanf, printf, etc.), funções matemáticas (sqr, pow, sqrt, log, sin, cos, etc.) Esse trabalho de juntar o programa-objeto com tais subprogramas é feito por um software denominado editor de ligações (linkage-editor) Esse trabalho de juntar o programa-objeto com tais subprogramas é feito por um software denominado editor de ligações (linkage-editor) O produto do editor de ligações é um arquivo denominado programa-executável (extensão exe) O produto do editor de ligações é um arquivo denominado programa-executável (extensão exe)

40 d) Carregador A região de memória onde um programa será alocado para execução só será conhecida quando ele for chamado para isso A região de memória onde um programa será alocado para execução só será conhecida quando ele for chamado para isso Então o endereçamento do arquivo executável precisa ser corrigido, quando sua execução for solicitada Então o endereçamento do arquivo executável precisa ser corrigido, quando sua execução for solicitada Esse trabalho é feito pelo carregador (loader), que produz a versão final do programa, pronto para rodar Esse trabalho é feito pelo carregador (loader), que produz a versão final do programa, pronto para rodar

41 1.2 – Estrutura de um Compilador – Componentes de um compilador O trabalho de compilação é dividido em 2 fases: O trabalho de compilação é dividido em 2 fases: Fase de análise e fase de síntese Além disso, existem atividades que fazem parte das duas fases Além disso, existem atividades que fazem parte das duas fases

42 O processo não precisa ser sequencial

43 load i R1: sub n JZ R2 JP R2 load i add j st i J R1 R2: Exemplo Analisador léxico Analisador sintático Analisador semântico Gerador de código intermediário Otimizador de código intermediário Gerador de código objeto while (i < n) i = i + j; Programa-fonte (caracteres) Sequência de átomos Árvore sintática while i < ni = i + j i n j int Tabela de símbolos while(i

44 1.2.2 – A fase de análise São realizados três tipos de análise: São realizados três tipos de análise: Análise linear ou léxica Análise linear ou léxica Análise hierárquica ou sintática Análise hierárquica ou sintática Análise semântica Análise semântica

45 a) Análise léxica Os caracteres do texto são agrupados em átomos (tokens) Os caracteres do texto são agrupados em átomos (tokens) A validade dos átomos é verificada A validade dos átomos é verificada Os átomos recebem uma classificação Os átomos recebem uma classificação

46 Exemplo: frase da Língua Portuguesa: Exemplo: frase da Língua Portuguesa: ajbxswn o homem alto apanhou a laranja madura na laranjeira tdhf

47 Exemplo: um comando while em Pascal: Exemplo: um comando while em Pascal: while num 50 do num := num * 2

48 b) Análise sintática Os átomos são agrupados em frases, em estrutura de árvore (árvore sintática) Os átomos são agrupados em frases, em estrutura de árvore (árvore sintática) A validade da posição dos átomos é verificada A validade da posição dos átomos é verificada

49 Exemplo: frase: Exemplo: frase: o homem alto apanhou a laranja madura na laranjeira

50 Exemplo: comando while de Pascal: Exemplo: comando while de Pascal: while num 50 do num := num * 2

51 c) Análise semântica Verifica se a árvore sintática tem sentido Verifica se a árvore sintática tem sentido Coleta informações de tipos para a fase de síntese Coleta informações de tipos para a fase de síntese

52 Exemplo: frase sem sentido: Exemplo: frase sem sentido: a laranja apanhou o homem Erro: o verbo apanhar não admite sujeito do tipo vegetal Erro: o verbo apanhar não admite sujeito do tipo vegetal

53 Exemplo: comando while de Pascal: while n+3 do n*5 (com integer n) Erro: O operador de uma atribuição deve ser := Erro: A expressão de um comando while deve ser do tipo lógico

54 1.2.3 – A fase de síntese Depois da análise, a fase de síntese constrói o programa objeto Depois da análise, a fase de síntese constrói o programa objeto São realizadas três tarefas: São realizadas três tarefas: Geração do código intermediário Geração do código intermediário Otimização do código intermediário Otimização do código intermediário Geração do código objeto Geração do código objeto

55 a) Geração do código intermediário: A estrutura do programa-fonte costuma ser bem diferente da estrutura do programa-objeto A estrutura do programa-fonte costuma ser bem diferente da estrutura do programa-objeto A transformação da primeira estrutura para a segunda deve ser aliviada passando por uma fase intermediária A transformação da primeira estrutura para a segunda deve ser aliviada passando por uma fase intermediária Fazendo analogia com metamorfose na vida animal: Fazendo analogia com metamorfose na vida animal: Ovo Lagarta Borboleta Ovo Girino Sapo

56 Exemplo: Exemplo: while n 50 do n := n * 2 Quádruplas: 1º elemento: operador 2º e 3º elementos: operandos 4º elemento: resultado Código de três endereços: 2 endereços p/operandos 1 endereço p/resultado

57 O código intermediário deve ser fácil de: O código intermediário deve ser fácil de: Ser produzido Ser produzido Ser transformado em código objeto (Assembly da máquina) Ser transformado em código objeto (Assembly da máquina)

58 b) Otimização do código intermediário: Elimina operações desnecessárias e repetidas Elimina operações desnecessárias e repetidas Visa simplificar o código intermediário Visa simplificar o código intermediário Visa tornar o programa executável mais rápido Visa tornar o programa executável mais rápido Visa economia de memória Visa economia de memória

59 Exemplo: sejam os comandos Exemplo: sejam os comandos x := a + b + c; y := a + b + c + d;

60 Outros casos para otimização: Outros casos para otimização: Detecção de atribuições e operações cujos valores não são usados no programa Detecção de atribuições e operações cujos valores não são usados no programa Detecção de código morto, ou seja, de código que não é executado, qualquer que seja a entrada de dados Detecção de código morto, ou seja, de código que não é executado, qualquer que seja a entrada de dados Otimização faz análise de fluxo de dados e de controle Otimização faz análise de fluxo de dados e de controle

61 c) Geração do código objeto: Transformação do código intermediário otimizado no código objeto (normalmente o Assembly da máquina alvo) Transformação do código intermediário otimizado no código objeto (normalmente o Assembly da máquina alvo) O código objeto pode também receber otimizações O código objeto pode também receber otimizações Exemplo: seja o comando Exemplo: seja o comando while n < 50 do n := n * 2

62 1.2.4 – Atividades em ambas as fases Manipulação da tabela de símbolos Manipulação da tabela de símbolos Tratamento de erros Tratamento de erros a) Tabela de símbolos Guarda informações sobre todos os identificadores usados em um programa Guarda informações sobre todos os identificadores usados em um programa

63 Informações sobre os identificadores: Tipo do identificador: Tipo do identificador: Variável Variável Constante Constante Definição de tipo Definição de tipo Nome de subprograma Nome de subprograma Rótulo Rótulo Escopo: em que trecho ele é válido Escopo: em que trecho ele é válido

64 Se for nome de variável: Se for nome de variável: Tipo Se é ou não indexada Se é ou não estrutura Se é ou não ponteiro Endereço de memória Espaço a ser alocado Se for variável indexada Número de dimensões Número de elementos em cada dimensão Se for estrutura: Nome e tipo de cada campo Se for ponteiro: Tipo dos locais apontados por ela

65 Exemplos em C: Exemplos em C: int a; float X[7][5][4]; a nome var tipo int tipovar não eharray X nome var tipo real tipovar sim eharray 3 ndim 754 dims 012

66 Se for nome de subprograma: Se for nome de subprograma: Tipo de subprograma (função ou procedimento) Tipo de subprograma (função ou procedimento) Número de parâmetros Número de parâmetros Lista de parâmetros por valor Lista de parâmetros por valor Lista de parâmetros por referência Lista de parâmetros por referência Tipo a ser retornado Tipo a ser retornado Lista de variáveis locais Lista de variáveis locais

67 Exemplo em C: Exemplo em C: int fff (int m, int n) {float a, b; } ffffuncint2 nometipotipofunnparamList param List Var Loc n nome var tipo int tipovar b nome var tipo real tipovar m nome var tipo int tipovar a nome var tipo real tipovar

68 A tabela de símbolos é manipulada pelos vários componentes das fases de análise e síntese: Análise léxica detecta e pode armazenar o identificador Análise léxica detecta e pode armazenar o identificador Análise sintática pode armazenar seu tipo e outras informações Análise sintática pode armazenar seu tipo e outras informações Análise semântica faz consultas à tabela Análise semântica faz consultas à tabela Geração de código introduz e usa informações sobre espaço alocado Geração de código introduz e usa informações sobre espaço alocado

69 b) Detecção e tratamento de erros Cada componente do compilador pode encontrar erros Cada componente do compilador pode encontrar erros Encontrado um erro, um componente deve tratá-lo de forma a permitir que outros erros sejam detectados Encontrado um erro, um componente deve tratá-lo de forma a permitir que outros erros sejam detectados Um compilador que para, quando encontra o primeiro erro, não pode ajudar muito Um compilador que para, quando encontra o primeiro erro, não pode ajudar muito Existem erros léxicos, sintáticos e semânticos Existem erros léxicos, sintáticos e semânticos

70 Exemplos: Exemplos: Erro léxico: Conjunto de caracteres que não corresponde a nenhum átomo Erro léxico: Conjunto de caracteres que não corresponde a nenhum átomo Erro sintático: Sequência de átomos que viola construções sintáticas Erro sintático: Sequência de átomos que viola construções sintáticas Erro semântico: Construções sintáticas corretas porém sem sentido Erro semântico: Construções sintáticas corretas porém sem sentido Cada componente da estrutura do compilador será estudado detalhadamente em capítulo específico Cada componente da estrutura do compilador será estudado detalhadamente em capítulo específico

71 1.2.5 – Outra decomposição de um compilador Compilador é uma interface entre: Compilador é uma interface entre: linguagem-fonte e máquina-alvo Frente ou front-end : parte do compilador dependente da linguagem-fonte Frente ou front-end : parte do compilador dependente da linguagem-fonte Retaguarda ou back-end: parte do compilador dependente da máquina-alvo Retaguarda ou back-end: parte do compilador dependente da máquina-alvo

72 Frente (front-end) compreende: Análises léxica, sintática e semântica Análises léxica, sintática e semântica Criação e consultas à tabela de símbolos Criação e consultas à tabela de símbolos Geração do código intermediário Geração do código intermediário Muita otimização do código intermediário Muita otimização do código intermediário Tratamento de erros léxicos, sintáticos e semânticos Tratamento de erros léxicos, sintáticos e semânticos

73 Retaguarda (back-end) compreende: Alguma otimização do código intermediário Alguma otimização do código intermediário Geração de código objeto Geração de código objeto Otimização do código objeto Otimização do código objeto Operações na tabela de símbolos Operações na tabela de símbolos Tratamento de alguns erros Tratamento de alguns erros

74 Essa decomposição facilita a criação de compiladores de: Essa decomposição facilita a criação de compiladores de: Mesma linguagem-fonte para várias máquinas-alvos Mesma linguagem-fonte para várias máquinas-alvos Várias linguagens-fontes para mesma máquina-alvo Várias linguagens-fontes para mesma máquina-alvo L M1M2Mi M L1L2Lj Uma única linguagem para código intermediário

75 No primeiro caso: sucesso absoluto Pode-se projetar um código intermediário que se aproxime bem da linguagem de máquina de uma variedade de arquiteturas Pode-se projetar um código intermediário que se aproxime bem da linguagem de máquina de uma variedade de arquiteturas L M1M2Mi M L1L2Lj

76 No segundo caso: sucesso limitado Diferenças sutis entre algumas linguagens dificultam a obtenção de um código intermediário comum entre elas Diferenças sutis entre algumas linguagens dificultam a obtenção de um código intermediário comum entre elas L M1M2Mi M L1L2Lj


Carregar ppt "CES-41 COMPILADORES Capítulo I Introdução. Capítulo I - Introdução 1.1 – Compiladores 1.2 – Estrutura de um compilador 1.3 – Interpretadores 1.4 – Automação."

Apresentações semelhantes


Anúncios Google