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

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

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

Apresentações semelhantes


Apresentação em tema: "CES-41 COMPILADORES Capítulo I Introduçã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 1.1.1 – Definição Compilador é um software que
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) 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. 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 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) 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:
Escritos numa linguagem especializada Traduzidos (compilados) para uma linguagem de programação como C Compilados depois por um compilador similar ao de C Programas em Lex e Yacc são traduzidos para C 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 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

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

11 a) Pré-processador – realiza várias tarefas antes da compilação:
Inclusão de arquivos ao programa – Por exemplo, na Linguagem C: #include <math.h>: 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

12 Processamento de macros – para abreviar construções longas
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 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 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 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) Para fazer C = A + B Sendo A, B e C endereços de memória Instrução Significado LD A AC  Mem(A) ADD B AC  AC + Mem(B) ST C Mem(C)  AC

15 C1: CONST 1 C2: CONST 2 #include <stdio.h> 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

16 C1: CONST 1 C2: CONST 2 n: CONST 0 fat: CONST 0 i: CONST 0 #include <stdio.h> 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

17 C1: CONST 1 C2: CONST 2 n: CONST 0 fat: CONST 0 i: CONST 0 #include <stdio.h> 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

18 C1: CONST 1 C2: CONST 2 n: CONST 0 fat: CONST 0 i: CONST 0 inic: READ n Rótulo da 1ª instrução executável: inic #include <stdio.h> 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); Na realidade, a tradução de scanf é algo mais complexo: É uma chamada de subprograma

19 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 Rótulo da 1ª instrução executável: inic #include <stdio.h> 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);

20 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 JUMP loop Rótulo da 1ª instrução executável: inic #include <stdio.h> 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); “escrever” é o rótulo da instrução logo após JUMP

21 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 LD i ADD C1 JUMP loop Rótulo da 1ª instrução executável: inic #include <stdio.h> 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);

22 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 LD i ADD C1 JUMP loop escrever:WRITE fat Rótulo da 1ª instrução executável: inic #include <stdio.h> 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); Na realidade, a tradução de printf é algo mais complexo: É uma chamada de subprograma

23 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 LD i ADD C1 JUMP loop escrever:WRITE fat STOP END inic Rótulo da 1ª instrução executável: inic #include <stdio.h> 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);

24 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 LD i ADD C1 JUMP loop escrever:WRITE fat STOP END inic #include <stdio.h> 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); 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 LD i ADD C1 JUMP loop escrever:WRITE fat STOP END inic rótulo endereço endereço codop ender 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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 LD i ADD C1 JUMP loop escrever:WRITE fat STOP END inic rótulo endereço endereço codop ender 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Mnemônico Cod Op LD 1 ST 2 ADD 4 SUB 5 MULT 6 JUMP 11 JP 14 READ 15 WRITE 16 STOP 17

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 LD i ADD C1 JUMP loop escrever:WRITE fat STOP END inic rótulo endereço C1 C2 1 n 2 fat 3 i 4 endereço codop ender 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Mnemônico Cod Op LD 1 ST 2 ADD 4 SUB 5 MULT 6 JUMP 11 JP 14 READ 15 WRITE 16 STOP 17

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 LD i ADD C1 JUMP loop escrever:WRITE fat STOP END inic rótulo endereço C1 C2 1 n 2 fat 3 i 4 inic 5 endereço codop ender 1 2 3 4 5 15 6 7 8 9 10 11 12 13 14 16 17 18 19 20 Mnemônico Cod Op LD 1 ST 2 ADD 4 SUB 5 MULT 6 JUMP 11 JP 14 READ 15 WRITE 16 STOP 17

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 LD i ADD C1 JUMP loop escrever:WRITE fat STOP END inic rótulo endereço C1 C2 1 n 2 fat 3 i 4 inic 5 endereço codop ender 1 2 3 4 5 15 6 7 8 9 10 11 12 13 14 16 17 18 19 20 Mnemônico Cod Op LD 1 ST 2 ADD 4 SUB 5 MULT 6 JUMP 11 JP 14 READ 15 WRITE 16 STOP 17

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 LD i ADD C1 JUMP loop escrever:WRITE fat STOP END inic rótulo endereço C1 C2 1 n 2 fat 3 i 4 inic 5 loop 10 endereço codop ender 1 2 3 4 5 15 6 7 8 9 10 11 12 13 14 16 17 18 19 20 Mnemônico Cod Op LD 1 ST 2 ADD 4 SUB 5 MULT 6 JUMP 11 JP 14 READ 15 WRITE 16 STOP 17

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 LD i ADD C1 JUMP loop escrever:WRITE fat STOP END inic rótulo endereço C1 C2 1 n 2 fat 3 i 4 inic 5 loop 10 escrever ??? endereço codop ender 1 2 3 4 5 15 6 7 8 9 10 11 14 ??? 12 13 16 17 18 19 20 Mnemônico Cod Op LD 1 ST 2 ADD 4 SUB 5 MULT 6 JUMP 11 JP 14 READ 15 WRITE 16 STOP 17

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 LD i ADD C1 JUMP loop escrever:WRITE fat STOP END inic rótulo endereço C1 C2 1 n 2 fat 3 i 4 inic 5 loop 10 escrever ??? endereço codop ender 1 2 3 4 5 15 6 7 8 9 10 11 14 ??? 12 13 16 17 18 19 20 Mnemônico Cod Op LD 1 ST 2 ADD 4 SUB 5 MULT 6 JUMP 11 JP 14 READ 15 WRITE 16 STOP 17

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 LD i ADD C1 JUMP loop escrever:WRITE fat STOP END inic rótulo endereço C1 C2 1 n 2 fat 3 i 4 inic 5 loop 10 escrever 19 endereço codop ender 1 2 3 4 5 15 6 7 8 9 10 11 14 19 12 13 16 17 18 20 Mnemônico Cod Op LD 1 ST 2 ADD 4 SUB 5 MULT 6 JUMP 11 JP 14 READ 15 WRITE 16 STOP 17

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 LD i ADD C1 JUMP loop escrever:WRITE fat STOP END inic rótulo endereço C1 C2 1 n 2 fat 3 i 4 inic 5 loop 10 escrever 19 endereço codop ender 1 2 3 4 5 15 6 7 8 9 10 11 14 19 12 13 16 17 18 20 Mnemônico Cod Op LD 1 ST 2 ADD 4 SUB 5 MULT 6 JUMP 11 JP 14 READ 15 WRITE 16 STOP 17

35 Endereço inicial da execução: 5
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 LD i ADD C1 JUMP loop escrever:WRITE fat STOP END inic rótulo endereço C1 C2 1 n 2 fat 3 i 4 inic 5 loop 10 escrever 19 endereço codop ender 1 2 3 4 5 15 6 7 8 9 10 11 14 19 12 13 16 17 18 20 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 gerado pelo Assembler é o programa-objeto O programa-objeto foi montado a partir do endereço zero da RAM Esse programa é guardado num arquivo (extensão obj) endereço codop ender 1 2 3 4 5 15 6 7 8 9 10 11 14 19 12 13 16 17 18 20 Endereço inicial da execução: 5

37 Esse local depende da disponibilidade da RAM
O local para execução é estabelecido pelo sistema operacional do computador Esse local depende da disponibilidade da RAM E se o local não for o endereço zero (por exemplo, endereço 3000)? endereço codop ender 1 2 3 4 5 15 6 7 8 9 10 11 14 19 12 13 16 17 18 20 Endereço inicial da execução: 5

38 Isso tem de ser corrigido antes da execução
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 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 endereço codop ender 3000 1 3001 2 3002 3003 3004 3005 15 3006 3007 3 3008 3009 4 3010 5 3011 14 19 3012 3013 6 3014 3015 3016 3017 3018 11 10 3019 16 3020 17 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 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) 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 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

41 1.2 – Estrutura de um Compilador
1.2.1 – Componentes de um compilador 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

42 O processo não precisa ser sequencial

43 load i j Exemplo Programa-fonte (caracteres) 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; while ( i < n ) = + j ; Sequência de átomos i n j int - - - while i < n = + j Árvore sintática Tabela de símbolos Código objeto load i R1: sub n JZ R2 JP R2 add j st i J R1 R2: R1: T1 = i < n JF T1 R2 T2 = i + j i = T2 JUMP R1 R2: R1: T1 = i < n JF T1 R2 i = i + j JUMP R1 R2: Código intermediário Exemplo

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

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

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

47 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) A validade da posição dos átomos é verificada

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

50 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 Coleta informações de tipos para a fase de síntese

52 a laranja apanhou o homem
Exemplo: frase sem sentido: a laranja apanhou o homem 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: A expressão de um comando while deve ser do tipo lógico Erro: O operador de uma atribuição deve ser “:=”

54 1.2.3 – A fase de síntese Depois da análise, a fase de síntese constrói o programa objeto São realizadas três tarefas: Geração do código intermediário Otimização do código intermediário 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 transformação da primeira estrutura para a segunda deve ser aliviada passando por uma fase intermediária Fazendo analogia com metamorfose na vida animal: Ovo  Lagarta  Borboleta Ovo  Girino  Sapo

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

57 O código intermediário deve ser fácil de:
Ser produzido 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 Visa simplificar o código intermediário Visa tornar o programa executável mais rápido Visa economia de memória

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

60 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 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

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) O código objeto pode também receber otimizações 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 Tratamento de erros a) Tabela de símbolos Guarda informações sobre todos os identificadores usados em um programa

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

64 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: int a; float X[7][5][4]; a nome var tipo int tipovar
eharray X nome var tipo real tipovar sim eharray 3 ndim 7 5 4 dims 1 2

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

67 int fff (int m, int n) {float a, b; - - - - - }
Exemplo em C: int fff (int m, int n) {float a, b; } n nome var tipo int tipovar b nome var tipo real tipovar m nome var tipo int tipovar a nome var tipo real tipovar fff func int 2 nome tipo tipofun nparam List param List Var Loc

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 sintática pode armazenar seu tipo e outras informações Análise semântica faz consultas à tabela 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 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 Existem erros léxicos, sintáticos e semânticos

70 Exemplos: 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 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

71 linguagem-fonte e máquina-alvo
1.2.5 – Outra decomposição de um compilador Compilador é uma interface entre: linguagem-fonte e máquina-alvo Frente ou front-end : parte do compilador dependente da linguagem-fonte 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 Criação e consultas à tabela de símbolos Geração do código intermediário Muita otimização do código intermediário Tratamento de erros léxicos, sintáticos e semânticos

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

74 Uma única linguagem para código intermediário
Essa decomposição facilita a criação de compiladores de: Mesma linguagem-fonte para várias máquinas-alvos Várias linguagens-fontes para mesma máquina-alvo L M1 M2 Mi M L1 L2 Lj 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 L M1 M2 Mi M L1 L2 Lj

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 L M1 M2 Mi M L1 L2 Lj


Carregar ppt "CES-41 COMPILADORES Capítulo I Introdução."

Apresentações semelhantes


Anúncios Google