• Nenhum resultado encontrado

Projeto de Linguagem de Programação

N/A
N/A
Protected

Academic year: 2021

Share "Projeto de Linguagem de Programação"

Copied!
64
0
0

Texto

(1)

Projeto de Linguagem de Programação

Aula 2: Fundamentos do processo de compilação

Prof. Joaquim Pessôa Filho

(2)

Sumário

1. Níveis de Linguagens de Programação

2.  Qualidades da Linguagem

3.  Tipos de Processadores de Linguagem

4.  Diagramas Tombstone

1.  Compiladores x Interpretadores

2.  Máquinas Reais e Abstratas

3.  Técnicas de Bootstrapping

(3)

Níveis de Linguagens de Programação

  O que é um programa escrito em código de máquina ou linguagem de máquina?

  É uma seqüência de instruções, sendo que, cada

instrução é uma cadeia de bits que é interpretada pela máquina para executar uma determinada operação.

  É fácil ler, escrever e editar um programa escrito em linguagem de máquina?

  Não, dessa forma, foram criadas notações simbólicas para facilitar a leitura, escrita e edição de programas.

(4)

Níveis de Linguagens de Programação

Exemplo:

(s × (s - a) × (s - b) × (s - c) ) onde s = ( a + b + c )/ 2

(5)

Níveis de Linguagens de Programação

Exemplo codificado em linguagem Assembly:

LOAD R1 a; ADD R1 b; ADD R1 c; DIV R1 #2;

LOAD R2 R1;

LOAD R3 R1; SUB R3 a; MULT R2 R3;

LOAD R3 R1; SUB R3 b; MULT R2 R3;

LOAD R3 R1; SUB R3 c; MULT R2 R3;

LOAD R0 R2; CALL sqrt

(6)

Níveis de Linguagens de Programação

Exemplo codificado em uma linguagem que apresenta uma notação similar à notação matemática já

conhecida:

let s = (a + b + c)/2

in sqrt (s * (s - a) * (s - b) * (s - c))

(7)

Qualidades da Linguagem

  A principal virtude de uma linguagem é a sua legibilidade, isto é, a facilidade que a linguagem

oferece para que um programador leia e compreenda um programa, com o grau de confiança necessário para alterá-lo.

  Também é desejável que a linguagem ofereça

facilidade de escrita de programas (redigibilidade).

Esta propriedade, entretanto, é colocada em outro plano, e é de certa forma conflitante com a

legibilidade.

(8)

Qualidades da Linguagem

(compilador ou interpretador)

  Eficiência do programa compilado

  Eficiência do processo de compilação

  Disponibilidade de ferramentas

  Disponibilidade de bibliotecas

(9)

Tradutores

  Um tradutor é um programa que aceita como entrada um texto na linguagem fonte e gera um outro texto semanticamente equivalente escrito na linguagem objeto.

  Exemplo:

  Tradutor de chinês para inglês - Linguagens Naturais (IA)

  Tradutor de Java para C

  Tradutor de Java para x86

  Um assembler x86 - Traduz a linguagem assembly x86 para código de máquina x86.

(10)

Assembler e Compilador

  Um assembler traduz uma linguagem assembly para o código de máquina correspondente, gerando uma instrução em código de máquina por instrução de entrada.

  Um compilador traduz uma linguagem de alto nível para um linguagem de baixo nível, gerando diversas instruções de código de máquina por comando de entrada.

(11)

Tipos de Processadores de Linguagens

  Assembler e Compilador são os tipos de tradutores mais conhecidos, mas existem também:

  Tradutores de alto nível (linguagem fonte e objeto são de alto nível). Ex: Java - C

  Disassembler (código de máquina para linguagem assembly)

  Decompiler (linguagem de baixo nível para linguagem de alto nível)

(12)

Linguagens

  Tradutores e outros processadores de linguagens são programas que manipulam programas

  Diferentes linguagens são envolvidas: a linguagem fonte, a linguagem objeto e a linguagem na qual o tradutor foi desenvolvido, chamada linguagem de implementação

(13)

Diagramas tombstone

  Serão usados para representar programas e

processadores de linguagens, e para expressar a manipulação de programas por processadores.

  Um programa é representado por:

  onde o programa P é expresso em uma linguagem L.

L

P

(14)

Diagramas tombstone

  Exemplos de diagramas representando programas:

x86 sort Java

sort

Basic

graph

(15)

Diagramas tombstone

  Todo programa roda em uma máquina. Uma máquina que executa código de máquina M e representada por:

  Exemplos de diagramas representando máquinas:

M

PPC

x86

SPARC

(16)

Diagramas tombstone

  Um programa pode rodar em uma máquina se é expresso em código de máquina adequado:

M

P

M

(17)

Diagramas tombstone

  Exemplos de diagramas representando execuções de programas:

  Um desses diagramas tem um erro. Qual?

x86 sort x86

PPC sort PPC

PPC sort

x86

(18)

Diagramas tombstone

  Diagrama representando um tradutor S - T expresso em linguagem L:

onde S é linguagem fonte, T é a linguagem objeto e L a linguagem de implementação.

S → T

L

(19)

Diagramas tombstone

  Exemplos de diagramas representando tradutores:

  Observando os exemplos anteriores, separe-os em compilador, tradutor de alto nível e montador.

Java → x86 C

Java → x86 x86

Java → C C++

x86 ass. → x86

x86

(20)

S → T M S

P

M

T P

Deve ser igual Deve ser igual

Diagramas tombstone

Tradução de um programa fonte P expresso em linguagem S para um programa objeto expresso em linguagem T, usando um tradutor S - T que roda em uma máquina M.

(21)

Diagramas tombstone

O que representa esse diagrama?

Java → x86 x86

Java sort

x86

x86 sort

x86

sort

x86

(22)

Cross-Compiler

Quando utilizamos?

Java → PPC x86

Java sort

x86

PPC sort

PPC sort

download

PPC

(23)

Comportamento de um tradutor

  Pode rodar em uma máquina M se for expresso em código de máquina M

  O programa fonte deve ser expresso na linguagem fonte S do tradutor

  O programa objeto deve ser expresso na linguagem objeto T do tradutor

  O programa objeto é semanticamente equivalente ao programa fonte.

(24)

Passos ilegais

C → x86 x86

Java sort

x86

Java → x86 x86

Java sort

PPC

(25)

Compilação em dois passos

Um tradutor expresso em C ou Java pode rodar em qualquer máquina?

O que podemos fazer?

Tradução em dois passos.

Java → C x86

Java sort

x86

C sort

C → x86 x86

x86

sort

x86

(26)

Compilando um compilador

C → x86 x86 x86 Java → x86

C

Java → x86

x86

(27)

Interpretadores

  Em um ambiente interativo, interpretação é um método interessante de trabalho.

  Exemplos: interpretador Basic, interpretador Lisp, shell do UNIX e interpretador SQL

  Vantagens:

  Se o programador trabalha em um modo interativo, e deseja ver os resultados de cada instrução antes de entrar com a próxima instrução.

  Se o programa é utilizado uma vez e depois é descartado, portanto a velocidade não é tão importante.

  Se cada instrução for executada uma única vez

  Se as instruções têm um formato simples, podendo ser analisadas facil e eficientemente

(28)

Interpretadores

  Desvantagem:

  A interpretação de um programa fonte em uma linguagem de alto nível é 100 vezes mais lenta que a execução do programa equivalente em código de máquina.

  Não é adequada quando:

  O programa deve ser executado em produção (velocidade é importante)

  As instruções devem ser executadas freqüentemente

  As instruções estão em formatos mais complicados

(linguagens de alto nível) e portanto é necessário mais tempo para análise.

(29)

Diagrama tombstone

  Interpretador S expresso em uma linguagem L

  Exemplos de diagramas representado interpretadores:

S L

SQL x86

shell C Basic

x86

shell

SPARC

(30)

Diagramas tombstone

S

P

S

M M

(31)

Diagramas tombstone

  Qual dos diagramas está incorreto?

Lisp chess

Lisp x86 x86 Basic

graph Basic

x86 x86

Lisp chess

Basic

x86 x86

(32)

Máquinas Reais e Abstratas

  Suponha que um engenheiro de computação

projetou um conjunto de instruções e a arquitetura de uma nova máquina, chamada Ultima.

  Construir Ultima pode ser caro e tomar tempo.

Modificar o hardware para implementar mudanças de projeto também pode ter um alto preço.

  É possível que o engenheiro adie a construção do hardware até que tenha como testar o projeto?

  Ele pode escrever um interpretador para código de máquina Ultima (em C, por ex.).

(33)

Máquinas Reais e Abstratas

  Tradução de um interpretador para código de máquina M, usando o compilador C

C → M M

M

Ultima C

Ultima

M

(34)

Máquinas Reais e Abstratas

Ultima P

Ultima M M

Ultima Ultima

P

Mesma funcionalidade

(35)

Máquinas Reais e Abstratas

  A velocidade é a mesma utilizando essa alternativa?

  Não pode ser usado para medir a velocidade

absoluta da máquina sendo emulada, mas pode ser usado para obter informações quantitativas como:

ciclos de contagem de memória, grau de paralelismo, e outras.

  Informações qualitativas também podem ser obtidas, como: quanto a arquitetura e o conjunto de

instruções satisfazem a necessidade dos programadores.

  Esse tipo de interpretador é chamado de emulador.

(36)

Interpretive Compiler

  JVM-code é uma linguagem intermediária orientada a Java.

  Fornece instruções poderosas que correspondem diretamente à operações Java, tais como: criação de objeto, chamada de métodos, e indexação de vetores.

  Portanto a tradução de Java para JVM-code é fácil e rápida.

  Instruções em JVM-code, embora poderosas,

possuem um formato simples como instruções em código de máquina, e fáceis de analisar.

  A interpretação de JVM-code é relativamente rápida:

apenas 10 vezes mais lenta que em código de máquina.

(37)

Interpretive Compiler

  JDK consiste de um tradutor de Java para JVM-code e de um interpretador de JVM-code, que rodam em uma máquina M

Java → JVM M

Java P

M

JVM

P JVM

P JVM

M M

(38)

Portabilidade

  O que significa portabilidade de um programa?

  Facilidade de executar o programa em qualquer máquina sem necessidade de alterações.

  A linguagem na qual o programa é escrito tem grande impacto na portabilidade

  Um programa escrito em Assembly não pode ser executado em outra máquina sem que seja

totalmente refeito.

  Um programa escrito em linguagem de alto nível é bastante portável. Só é necessário recompilá-lo para executá-lo em outra máquina.

(39)

Compiladores Portáveis

  Um processador de linguagem é um programa,

dessa forma, também é importante que seja portável.

  A maioria dos processadores de linguagens são escritos em linguagens de alto nível.

  Se temos um compilador escrito em linguagem de alto nível que compila código C para x86, temos ainda um problema, esse compilador pode ser alterado para uma outra máquina que não aceita código x86?

  Um compilador que gera linguagem intermediária é mais portável que um que gera código de máquina.

(40)

Exemplo

JVM M

Java → JVM JVM

M Java

P

JVM P

JVM P JVM

M M

  O interpretador de JVM-code é mais simples e menor que o compilador, dessa forma, escrevê-lo

novamente é uma tarefa mais fácil

(41)

Bootstrapping

  Quando a linguagem de implementação é a

linguagem fonte, o processador pode ser usado para processar ele mesmo.

  Um compilador portável pode ser obtido com a

técnica de bootstrap, resultando em um compilador de fato - que gera código de máquina.

  Primeiramente, escrevemos um tradutor de JVM- code para código de máquina M, em Java:

JVM → M

Java

(42)

Bootstrapping um Compilador Portável

Java → JVM JVM

JVM → M Java

JVM → M JVM

JVM M

M

(43)

Bootstrapping um Compilador Portável

JVM → M JVM

JVM → M JVM

JVM → M M

JVM M

M

Bootstrap

(44)

Bootstrapping um Compilador Portável

JVM → M M

Java → JVM JVM

Java → JVM M

M

(45)

Bootstrapping um Compilador Portável

Java → JVM M

P Java → JVM

M Java

P

M

JVM P

JVM → M M

M

(46)

Bootstrap Total

  Para que um programa seja portável ele deve ser escrito em uma linguagem de alto nível (L)

  Caso seja preciso gerar uma nova versão do

programa (corrigir algum problema, melhorá-lo, etc) será necessário editá-lo e recompilá-lo.

  Dessa forma, o programa é mantido enquanto houver um compilador disponível.

(47)

Bootstrap Total

  Para um compilador escrito em L, o mesmo problema pode ocorrer

  Exemplo:

C → x86 x86 x86 Java → x86

C

Java → x86

x86

(48)

Bootstrap Total

  Um compilador cuja linguagem fonte é S, expresso em linguagem L, só pode existir enquanto houver um compilador para L.

  Esse problema pode ser evitado usando a linguagem S para escrever o compilador.

  Caso seja necessário construir uma nova versão do compilador S, podemos utilizar o compilador

existente para compilar a nova versão.

(49)

Bootstrap Total

  O problema está em como compilar a primeira versão do compilador S.

  A idéia utilizada para resolver este problema é usar um subconjunto de S adequado para a escrita do primeiro compilador.

(50)

  Suponha que desejamos desenvolver um compilador Ada para código de máquina M:

Bootstrap Total

Ada-S → M C

v1

M

Ada-S → M M

v1

M

C → M

(51)

Bootstrap Total

  Podemos utilizar o compilador resultante para testar programas escritos em Ada-S

  Entretanto, o compilador poderá ser mantido enquanto tivermos um o compilador C

  Dessa forma, podemos desenvolver o compilador usando a própria linguagem Ada-S

Ada-S → M Ada-S

v2

Ada-S → M M

Ada-S → M M

v2

M

v1

(52)

Bootstrap Total

  Com isso podemos compilar e testar os programas em Ada-S sem precisar do compilador C

  Finalmente, modificamos o compilador Ada-S para compilar programas em Ada

Ada → M Ada-S

v3

Ada-S → M M

Ada → M M

v3

M

v2

(53)

Bootstrap Parcial

  Suponha que exista um compilador que roda em uma máquina HM (host machine) e desejamos

utilizar este compilador em uma outra máquina TM (target machine).

  Para que esse compilador possa gerar código de máquina TM é necessário alterar grande parte do compilador, que é responsável pela geração de código (50%).

  Se o compilador é expresso utilizando sua própria linguagem fonte, estamos falando do processo de Bootstrap Parcial.

(54)

Bootstrap Parcial

Ada → HM Ada

Ada → HM HM

  Supondo que temos os seguintes tradutores:

  E desejamos um compilador que roda na máquina TM e gera código de máquina TM

(55)

  Primeiramente, modificamos o gerador de código para gerar código de máquina TM

Bootstrap Parcial

Ada → TM

Ada

(56)

  Produzimos assim um cross-compiler. Como podemos testá-lo?

Bootstrap Parcial

Ada → TM

Ada Ada → HM HM

Ada → TM HM

HM

(57)

Bootstrap Parcial

Ada → TM HM

Ada P

HM

TM P

TM P

download

TM

(58)

  Após testar o compilador gerado podemos utilizá-lo para compilar ele mesmo, de forma que gere código de máquina TM.

Bootstrap Parcial

Ada → TM

Ada Ada → TM HM

Ada → TM TM

HM

(59)

Bootstrapping para melhorar a eficiência

  O que pode ser usado para medir a eficiência de um programa?

  Quando estamos avaliando um compilador, o que deve ser considerado?

  Eficiência do próprio compilador

  Eficiência dos programas que ele gera

(60)

Bootstrapping para melhorar a eficiência

Ada → M

slow

Ada

Ada → M

slow

M

slow

v1 v1

  Suponha que tenhamos:

  Modificamos a versão 1 para que gere código de máquina Mfast

Ada → M

fast

Ada

v2

(61)

Bootstrapping para melhorar a eficiência

Ada → M

fast

Ada Ada → M

slow

M

slow

Ada → M

fast

M

slow

M

v2 v2

v1

(62)

Bootstrapping para melhorar a eficiência

Ada → M

fast

M

slow

Ada P

M

M

fast

P

M

fast

P M

v2

(63)

Bootstrapping para melhorar a eficiência

Ada → M

fast

Ada Ada → M

fast

M

slow

Ada → M

fast

M

fast

M

v2 v3

v2

(64)

Bootstrapping para melhorar a eficiência

Ada → M

fast

M

fast

Ada P

M

M

fast

P

M

fast

P M

v3

Referências

Documentos relacionados

Em seguida, ainda fazendo uso da palavra e condicionada à celebração do Aditamento a ser oportunamente aprovado pela Assembléia Geral de Debenturistas, o Diretor

O motor deve sempre funcionar na rotação máxima para evitar vibra- ções anormais na máquina.. Mantenha as mãos e os pés afastados da(s)

• linguagens de montagem: precisam de um programa montador para gerar linguagem de máquina. • linguagens de alto nível: precisam de um compilador para traduzi-las para uma

•  Compilador lê todo o código-fonte e converte-o para linguagem de máquina (código-objeto);.. Compiladores

Posteriormente, o mesmo autor, Viveiros de Castro, pro- pôs o termo perspectiva, para estabelecer que, muito resumidamente, tudo depende da posição singular de onde o

(Incluído na listagem das certificações UL/cUL: bitola do fio: AWG 30-12 Utilize somente condutores de cobre para 60/75 °C). 0,5 Nm

Se você quiser, que ninguem mais entre no grupo, mude de privado para bloqueado. Ninguem pode perdir mais permissão

Percebe-se que no zoológico a mulher procura punição para o que está sentido, como explica Sousa Filho (1995) que a existência de mitos sobre castigos, em todas