Você está na página 1de 19

Escola Superior de Ciências Náuticas

DEPARTAMENTO DE MAQUINAS

ENGENHARIA ELECTROMECÂNICA

Informática II

Docente: Leonardo Banze

Maputo, 02 de Fevereiro de 2022ss


Informatica II

Compildores

Curso: Engenharia Eletromecânica

Turma: 1ELM/2021

Discentes:

Fidal Sibia

Hamilton Joffrey Tivane

Maputo, 02 de Fevereiro de 2022ss


Objectivos

 Objectivo Geral

Conhecer o processo de especificação e implementação de linguagens de programação, a partir do


estudo dos conceitos, modelos, técnicas e ferramentas que compõem a Teoria das Linguagens
Formais e a Teoria de Compiladores.

 Objectivos Específicos

a) Adquirir uma visão geral sobre o Processo de Compilação sob o ponto de vista de
implementação.
b) Adquirir noções básicas sobre a Teoria das Linguagens Formais.
c) Saber especificar aspectos léxicos e sintáticos de linguagens através de autômatos e
gramáticas.
d) Conhecer critérios e características usados no projeto/avaliação de Linguagens de
Programação.
e) Conhecer as principais técnicas e ferramentas de apoio usadas na construção de
compiladores, sabendo usá-las na especificação e implementação de linguagens de
programação.
Indice
3. Linguagens de programação ....................................................................................................................... 7
5.1. Análise léxica .......................................................................................................................................... 11
5.2. Análise sintática .................................................................................................................................... 11
5.3. Análise semântica................................................................................................................................... 12
5.4. Geração de código intermediário........................................................................................................... 12
5.5. Otimização de código ............................................................................................................................. 13
5.6. Geração de código final.......................................................................................................................... 13
6. Tipos de compiladores ................................................................................................................................. 13
6.1. Compilador cruzado ............................................................................................................................... 13
6.2. Compilador Source-to-source ................................................................................................................ 14
6.3. Compilador Just-in-time (JIT) ................................................................................................................. 14
7. Ferramentas de construção dos compiladores ........................................................................................... 15
a. Scanner generators .................................................................................................................................... 15
b. Mecanismos de tradução de sintaxe.......................................................................................................... 15
c. Geradores de analisador ............................................................................................................................ 15
d. Geradores de código automáticos ............................................................................................................. 15
e. Mecanismos de fluxo de dados .................................................................................................................. 15
8. Diferenças entre compilador e interpretador ............................................................................................ 15
8.1. Vantagens e desvantagens dos compiladores ....................................................................................... 16
Vantagens e desvantagens dos interpretadores................................................................................................ 17
Indice de Figuras

Figura 1 - Linguagens de programação ........................................................................................................ 8


Figura 2 - Caracteristicas das Linguagens de Programação ....................................................................... 10
Figura 3 - Fazes da compilacao ................................................................................................................... 11
Figura 4 - Diferenças entre compilador e interpretador............................................................................... 15
1. Introdução

Os softwares para os primeiros computadores foram escritos principalmente em linguagem assembly por
muitos anos. As linguagens de alto nível de programação não foram inventadas até que os benefícios de ser
capaz de reutilizar software em diferentes tipos de CPUs passassem a ser significativamente maiores do que
o custo de se escrever um compilador. A capacidade de memória muito limitada dos primeiros
computadores também criava muitos problemas técnicos na implementação de um compilador.

No final da década de 1950, as linguagens de programação independentes de máquina foram propostas.


Posteriormente, vários compiladores experimentais foram desenvolvidos.
O primeiro compilador foi escrito por Grace Hopper, em 1952, para a linguagem de programação A-0.
Antes de 1957, foram desenvolvidos esforços e várias contribuições ao desenvolvimento de linguagens de
alto nível foram feitas. Entre Este, o desenvolvimento da Short Code (UNIVAC), Speedcoding no IBM
701, o Whirlwind, o BACAIC e o PRINT. A equipe de desenvolvimento do FORTRAN liderada por John
Backus na IBM é geralmente creditada como tendo introduzido o primeiro compilador completo em 1957
(embora tenha ocorrido simultaneamente o desenvolvimento do algebraic translator de Laning e Zierler. O
COBOL é um exemplo de uma linguagem da primeira geração que compilava em múltiplas arquiteturas,
em 1960.

Em muitos domínios de aplicação a ideia de usar uma linguagem de alto nível rapidamente ganhou força.
Por causa da funcionalidade de expansão apoiada por linguagens de programação recentes e a complexidade
crescente de arquiteturas de computadores, os compiladores tornaram-se mais e mais complexos. Os
primeiros compiladores foram escritos em linguagem assembly.
O primeiro compilador de auto-hospedagem - capaz de compilar seu próprio código-fonte em uma
linguagem de alto nível - foi criado para o Lisp por Tim Hart e Levin Mike no MIT (Massachusetts Institute
of Technology) em 1962.
2. Compiladores
Um compilador é um programa de computador (ou um grupo de programas) que, a partir de um código
fonte escrito em uma linguagem compilada, cria um programa semanticamente equivalente, porém escrito
em outra linguagem, código objeto. Classicamente, um compilador traduz um programa de uma linguagem
textual facilmente entendida por um ser humano para uma linguagem de máquina, específica para um
processador e sistema operacional. Atualmente, porém, são comuns compiladores que geram código para
uma máquina virtual que é, depois, interpretada por um interpretador. Ele é chamado compilador por razões
históricas; nos primeiros anos da programação automática, existiam programas que percorriam bibliotecas
de sub-rotinas e as reunia, ou compilava, as subrotinas necessárias para executar uma determinada tarefa.
O nome "compilador" é usado principalmente para os programas que traduzem o código fonte de uma
linguagem de programação de alto nível para uma linguagem de programação de baixo nível (por exemplo,
Assembly ou código de máquina). Contudo alguns autores citam exemplos de compiladores que traduzem
para linguagens de alto nível como C. Para alguns autores um programa que faz uma tradução entre
linguagens de alto nível é normalmente chamado um tradutor, filtro ou conversor de linguagem. Um
programa que traduz uma linguagem de programação de baixo nível para uma linguagem de programação
de alto nível é um descompilador. Um programa que faz uma tradução entre uma linguagem de montagem
e o código de máquina é denominado montador (assembler). Um programa que faz uma tradução entre o
código de máquina e uma linguagem de montagem é denominado desmontador (disassembler).
Se o programa compilado pode ser executado em um computador cuja CPU ou sistema operacional é
diferente daquele em que o compilador é executado, o compilador é conhecido como um compilador
cruzado.

3. Linguagens de programação
Podemos definir uma linguagem comumente chamada de língua ou idioma como um meio de
comunicação entre pessoas. Em programação definimos a linguagem como o meio de comunicação entre
o pensamento humano e as ações de um computador.
Todo o software executado em um computador foi escrito em alguma linguagem e antes que ele possa
executar instruções diretamente no processador, um outro programa deve ser utilizado para traduzir essa
linguagem em um formato que possa ser entendido e executado pelo computador, esse programa é
chamado de compilador.
As linguagens de programação são projetadas para permitir que seres humanos expressem processos
computacionais em uma sequência de operações, tal como ler um arquivo e imprimir o seu conteúdo em
algum dispositivo, numa impressora por exemplo.
Os programas executados no computador são sequências de 0 e 1 que representam valores inteiros, ponto
flutuante, strings, etc., ou ainda instruções que indicam o que o computador deve fazer. A memória do
computador é dividida em partes que possuem endereços únicos, todo o programa armazenado na
memória é executado pela CPU que possui registradores que guardam dados temporários utilizados em
operações.
Pense na seguinte situação: para somar o número armazenado no endereço de memória $000011 com o
número armazenado no endereço de memória $000012 é necessário:
 copiar o conteúdo da memória $000011 para um registrador A;
 copiar o conteúdo da memória $000012 para um registrado B;
 somar o conteúdo de A e B e copiar o resultado para o endereço de memória $000013.
Esse processo certamente é muito mais complexo do que simplesmente executar o comando c = a + b em
uma determinada linguagem de programação.
Uma linguagem de programação é considera de alto nível quando sua representação está próxima do
domínio da aplicação e do problema a ser resolvido. Os computadores por sua vez possuem sua própria
linguagem denominada de baixo nível ou linguagem de máquina.
O processo de tradução de uma linguagem de alto nível para linguagem de baixo nível é feito atra vés de
softwares conhecidos como compiladores e tem como entrada uma linguagem fonte, alto nível, e como
saída uma linguagem-objeto, baixo nível.

Figura 1 - Linguagens de programação

Na imagem acima podemos ver um diagrama que representa o processo de compilação, onde a entrada
é um programa fonte e a saída é um programa objeto. Posteriormente, outros processos estão envolvidos
na compilação, como por exemplo, o Ligador e o Carregador que criam o programa executável e
auxiliam a sua execução.
As linguagens de programação podem ser classificadas em 5 gerações:
 1ª linguagens de máquina – baixo nível.
 2ª linguagens simbólicas ou montagem (Assembly) – baixo nível.
 3ª linguagens orientadas a usuário – alto nível.
 4ª linguagens orientadas a aplicação – alto nível.
 5ª linguagens de conhecimento – alto nível.
Cada vez mais os compiladores e as linguagem de programação assumem tarefas que antes eram de
responsabilidade do programador, como por exemplo, gerenciamento de memória, verificação de tipos
e execução paralela.
Através das linguagens de programação, consegue-se:
 Facilidades para se escrever programas;
 Diminuição do problema de diferenças entre máquina;
 Facilidade de depuração e manutenção de programas;
 Melhoria da interface homem/máquina;
 Redução no custo e tempo necessário para o desenvolvimento de programas;
Os primeiros passos para tornar a linguagem mais inteligível por humanos ocorreu na década de 50 com
o desenvolvimento de linguagens simbólicas ou assembly. As instruções em Assembly representavam
mnemônicos das instruções de máquina, mais tarde surgiram ferramentas conhecidas como macro
assemblers que permitiam abreviaturas parametrizadas de uma sequência de instruções Assembly.
O surgimento das linguagens de programação como o FORTRAM e Cobol influenciaram o
desenvolvimento de compiladores pois permitiam que construções de alto nível fossem possíveis de
serem escritas de forma mais fácil. Posteriormente, com o surgimento de novas linguagem de
programação com recursos cada vez mais inovadores, os compiladores se tornaram ferramentas muito
mais sofisticadas.
Os programadores que utilizam linguagem de baixo nível têm mais controle sobre a execução de seus
programas e podem produzir um código mais eficiente, mas esses programas são difíceis de serem
escritos e executados em outras máquinas.
Com a evolução dos compiladores os programas escritos em linguagens de alto nível puderam ser
otimizados para que fossem tão eficientes quanto programas escritos em linguagens de baixo nível.
Linguagens de alto nível possuem recursos como laços, tipos de dados, controle de fluxo, etc. que
facilitam a escrita de programas. Esses recursos são traduzidos para linguagens de baixo nível e
executadas diretamente nos processadores através de instruções de máquina.
A criação de uma linguagem de programação depende do domínio da aplicação a que ela se propõe e
isso também é um motivador para o surgimento de novas linguagens. Embora muitas tenham surgido
com propósitos específicos, é comum uma linguagem ter muitas características e ser empregada em
vários domínios de aplicação.
4. Caracteristicas das Linguagens de Programação
Normalmente, o código fonte é escrito em uma linguagem de programação de alto nível, com grande
capacidade de abstração, e o código objeto é escrito em uma linguagem de baixo nível, como uma sequência
de instruções a ser executada pelo microprocessador.
O processo de compilação é composto de análise e síntese. A análise tem como objetivo entender o código
fonte e representá-lo em uma estrutura intermediária. A síntese constrói o código objecto a partir desta
representação intermediária.
A análise pode ser subdividida ainda em análise léxica, análise sintática, análise semântica e geração de
código intermediário. É também conhecida como front end. A síntese pode ter mais variações de um
compilador a outro, podendo ser composta pelas etapas de optimização de código e geração de código final
(ou código de máquina), sendo somente esta última etapa é obrigatória. É também conhecida como back
end.

Figura 2 - Caracteristicas das Linguagens de Programação

Em linguagens híbridas, o compilador tem o papel de converter o código fonte em um código chamado
de byte code, que é uma linguagem de baixo nível. Um exemplo deste comportamento é o do compilador
da linguagem Java que, em vez de gerar código da máquina hospedeira (onde se está executando o
compilador), gera código chamado Java Bytecode.
Um compilador é chamado de Just-in-time compiler (JIT) quando seu processo de compilação acontece
apenas quando o código é chamado. Um JIT pode fazer otimizações às instruções a medida que as compila.
Muitos compiladores incluem um pré-processador. Que é um programa separado, ativado pelo compilador
antes do início do processo de tradução. Normalmente é responsável por mudanças no código fonte
destinadas de acordo com decisões tomadas em tempo de compilação. Por exemplo, um programa
em C permite instruções condicionais para o pré-processador que podem incluir ou não parte do código
caso uma assertiva lógica seja verdadeira ou falsa, ou simplesmente um termo esteja definido ou não.
Tecnicamente, pré-processadores são muito mais simples que compiladores e são vistos, pelos
desenvolvedores, como programas à parte, apesar dessa visão não ser necessariamente compartilhada pelo
usuário.
Outra parte separada do compilador que muitos usuários vêem como integrada é o linker, cuja função é unir
vários programas já compilados de uma forma independente e unificá-los em um programa executável. Isso
inclui colocar o programa final em um formato compatível com as necessidades do sistema operacional
para carregá-lo em memória e colocá-lo em execução.

5. Fazes da compilacao

Figura 3 - Fazes da compilacao

5.1. Análise léxica


A análise léxica é a primeira fase do compilador. A função do analisador léxico, também
denominado scanner, é ler o código-fonte, caractere a caractere, buscando a separação e identificação dos
elementos componentes do programa-fonte, denominados símbolos léxicos ou tokens. É também de
responsabilidade desta fase a eliminação de elementos "decorativos" do programa, tais como espaços em
branco, marcas de formatação de texto e comentários. Existem disponíveis uma série de geradores
automáticos de analisadores léxicos, como por exemplo, o lex. O objetivo dos geradores automáticos é
limitar o esforço de programação de um analisador léxico especificando-se apenas os tokens a ser
reconhecidos.

5.2. Análise sintática


A análise sintática, ou análise gramatical é o processo de se determinar se uma cadeia de símbolos léxicos
pode ser gerada por uma gramática. O analisador sintático é o cerne do compilador, responsável por verificar
se os símbolos contidos no programa fonte formam um programa válido, ou não. No caso de analisadores
sintáticos top-down, temos a opção de escrevê-los à mão ou gerá-los de forma automática, mas os
analisadores bottom-up só podem ser gerados automaticamente. A maioria dos métodos de análise sintática,
cai em uma dessas duas classes denominadas top-down e bottom-up. Entre os métodos top-down os mais
importantes são a análise sintática descendente recursiva e a análise sintática preditiva não-recursiva. Entre
os métodos de análise sintática bottom-up os mais importantes são a análise sintática de precedência de
operadores, análise sintática LR canônico, análise sintática LALR e análise sintática SLR. Existem
disponíveis uma série de geradores automáticos de analisadores sintáticos, como por exemplo, o Yacc,
o Bison e o JavaCC.

5.3. Análise semântica


As análises léxica e sintática não estão preocupadas com o significado ou semântica dos programas que elas
processam. O papel do analisador semântico é prover métodos pelos quais as estruturas construídas pelo
analisador sintático possam ser avaliadas ou executadas. As gramáticas livres de contexto não são
suficientemente poderosas para descrever uma série de construções das linguagens de programação, como
por exemplo regras de escopo, regras de visibilidade e consistência de tipos. É papel do analisador semântico
assegurar que todas as regras sensíveis ao contexto da linguagem estejam analisadas e verificadas quanto à
sua validade. Um exemplo de tarefa própria do analisador semântico é a checagem de tipos de variáveis em
expressões. Um dos mecanismos comumente utilizados por implementadores de compiladores é
a Gramática de Atributos, que consiste em uma gramática livre de contexto acrescentada de um conjunto
finito de atributos e um conjunto finito de predicados sobre estes atributos.

5.4. Geração de código intermediário


Na fase de geração de código intermediário, ocorre a transformação da árvore sintática em uma
representação intermediária do código fonte. Esta linguagem intermediária é mais próxima da linguagem
objeto do que o código fonte, mas ainda permite uma manipulação mais fácil do que se código assembly ou
código de máquina fosse utilizado. Um tipo popular de linguagem intermediária é conhecido como código
de três endereços. Neste tipo de código uma sentença típica tem a forma X := A op B , onde X, A e B são

operandos e op uma operação qualquer. Uma forma prática de representar sentenças de três endereços é
através do uso de quádruplas (operador, argumento 1, argumento 2 e, resultado). Este esquema de
representação de código intermediário é preferido por diversos compiladores, principalmente aqueles que
executam extensivas otimizações de código, uma vez que o código intermediário pode ser rearranjado de
uma maneira conveniente com facilidade. Outras representações de código intermediário comumente
usadas são as triplas, (similares as quádruplas exceto pelo fato de que os resultados não são nomeados
explicitamente) as árvores, os grafos acíclicos dirigidos(DAG) e a notação polonesa.

5.5. Otimização de código


A otimização de código é a estratégia de examinar o código intermediário, produzido durante a fase de
geração de código com objetivo de produzir, através de algumas técnicas, um código que execute com
bastante eficiência. O nome optimizador deve sempre ser encarado com cuidado, pois não se pode criar um
programa que leia um programa P e gere um programa P´ equivalente sendo melhor possível segundo o
critério adotado. Várias técnicas e várias tarefas se reúnem sob o nome de Optimização. Estas técnicas
consistem em detectar padrões dentro do código produzido e substituí-los por códigos mais eficientes. Entre
as técnicas usadas estão a substituição de expressões que podem ser avaliadas durante o tempo de
compilação pelos seus valores calculados, eliminação de subexpressões redundantes, desmembramento de
laços, substituição de operações (multiplicação por shifts), entre outras. Uma das técnicas de optimização
mais eficazes e independente de máquina é a otimização de laços, pois laços internos são bons candidatos
para melhorias. Por exemplo, em caso de computações fixas dentro de laços, é possível mover estas
computações para fora dos mesmos reduzindo processamento.

5.6. Geração de código final


A fase de geração de código final é a última fase da compilação. A geração de um bom código objeto é
difícil devido aos detalhes particulares das máquinas para os quais o código é gerado. Contudo, é uma fase
importante, pois uma boa geração de código pode ser, por exemplo, duas vezes mais rápida que um
algoritmo de geração de código ineficiente. Nem todas as técnicas de optimização são independentes da
arquitetura da máquina-alvo. Optimizações dependentes da máquina necessitam de informações tais como
os limites e os recursos especiais da máquina-alvo a fim de produzir um código mais compacto e eficiente.
O código produzido pelo compilador deve se aproveitar dos recursos especiais de cada máquina-alvo.
Segundo Aho, o código objeto pode ser uma sequência de instruções absolutas de máquina, uma sequência
de instruções de máquina relocáveis, um programa em linguagem assembly ou um programa em outra
linguagem.

6. Tipos de compiladores
6.1. Compilador cruzado
É um compilador que consegue criar códigos executáveis para plataformas diferentes da que está sendo
executado. Um exemplo disso seria a criação de um APK (formato de arquivo padrão do android) a partir
de um programa no Windows 10. Existem também outros pontos positivos desse método:
 criação de programas para sistemas embutidos, já que eles não tem muitos recursos. Um exemplo
disso seria um microondas que contém um computador com pouco processamento e contém uma
série de equipamentos como um touchpad, sensor na porta, um alto falante, uma tela digital para
mostrar o tempo e o controlador da máquina de esquentar a comida. Tudo isso deve ser controlado
por um pequeno computador que não é muito poderoso para conter todo um ambiente de
desenvolvimento, logo, é mais simples utilizar a compilação cruzada nesses casos;
 compilação para várias máquinas. Por exemplo, para uma empresa que precisa de suporte para
várias versões de um sistema operacional ou até mesmo vários sistemas operacionais.

6.2. Compilador Source-to-source


Um método de tradução de uma linguagem de alto nível para alguma outra linguagem de alto nível.
Nesse processo, é aferido todos os mesmos processos de compilação e temos como resultado final o código
de alguma outra linguagem. Um exemplo disso é o famoso TypeScript, que basicamente converte todo o
seu código, de maneira automatizada, para o JavaScript.

Lista de programas que fazem uso desse padrão de compilação:

6.3. Compilador Just-in-time (JIT)


Possivelmente, é um dos compiladores mais famosos. Você já deve ter ouvido falar nele enquanto estudava
Java, .NET ou até Python. É um método de compilação que converte o código dessas linguagens para
um código de meio termo chamado bytecode. Nesse caso, o código não é entendido pela máquina em si
e é preciso contar com uma máquina virtual para a execução desse código. Também pode ser conhecido
como um interpretador.
Com isso, temos o programa rodando logo após o início da compilação e é comum que o código gerado
anteriormente contribua para a compilação final. Como o código será compilado várias vezes, esse método
não é muito bom em fazer otimizações, já que se perde muito tempo nesse processo.
7. Ferramentas de construção dos compiladores
Existem diversos tipos de ferramentas nos compiladores, todos introduzidos em tecnologias relacionadas
ao computador. Esses instrumentos são criados a partir de uma linguagem específica ou feitos a partir de
um algoritmo e acabam implementando algum componente do compilador
a. Scanner generators
Serve para gerar analisadores léxicos a partir da entrada de dados, que são as descrições
de várias expressões regulares baseadas nos tokens da linguagem. Em resumo, ele gera um autômato finito
para reconhecer a expressão regular. Um exemplo disso é o programa Lex.
b. Mecanismos de tradução de sintaxe
É uma ferramenta para gerar códigos intermediários com três formatos de endereço na sua entrada,
que contém uma árvore de análise. Esses mecanismos têm rotinas que percorrem a árvore e, em seguida,
produzem o código intermediário. Sendo nesse caso, cada nó é associado a uma ou mais traduções.
c. Geradores de analisador
Ele produz analisadores de sintaxe (parsers) a partir da entrada que é baseada em uma descrição
gramatical de linguagem de programação, até mesmo uma gramática livre de contexto. É muito útil, pois a
fase de análise de sintaxe é muito complexa e consomem mais tempo manual e de compilação. Alguns
desses programas são o PIC e o EQM.
d. Geradores de código automáticos
O código de máquina é gerado a partir de uma linguagem intermediária, sendo que cada operação deve
obedecer a um conjunto de regras e, se não ocorrer erros, é gerado o código final. Nesse processo se utiliza
uma comparação de templates entre as linguagens para que ocorra a substituição das instruções do código
intermediário para o código de máquina.
e. Mecanismos de fluxo de dados
Usado na otimização do código. Aqui, as informações são coletadas a partir do usuário e do código
intermediário. Logo após, é feita a análise do fluxo de dados para que seja mostrado como os valores são
transmitidos de um lugar do código para outro.
8. Diferenças entre compilador e interpretador

\
Figura 4 - Diferenças entre compilador e interpretador
Um compilador é um programa que traduz o código escrito em uma linguagem de alto nível para
código de máquina. Em resumo, traduz o código legível para os seres humanos e converte para a linguagem
binária que o processador entende. Além disso, o compilador deve obedecer as regras de sintaxe da
linguagem, no caso, se ocorrer algum erro você deve corrigi-los.
Alguns exemplos de linguagens que utilizam compiladores:
 Java;
 C++;
 Switch;
 C#;
 Rust.
O interpretador também é um programa, porém, ele não tem o processo de traduzir todo o programa
em um arquivo para conseguir rodar, e sim, ele inclui cada instrução da sua linguagem de alto nível
no código de máquina. Com isso, o papel de tradução é feito de uma maneira muito mais dinâmica e que
consegue incluir alguns tipos de código, tais como, scripts, códigos pré-compilados e o próprio código
fonte.

Alguns exemplos de linguagens que utilizam interpretadores:


 PHP;
 JavaScript;
 Lisp;
 Matlab;
 Perl.

8.1.Vantagens e desvantagens dos compiladores


Vantagens dos compiladores:
 o código já é traduzido para a linguagem de máquina, com isso, se obtém um tempo menor de
execução;
 a confiabilidade do código final, já que os processos do compilador são bem severos e conseguem
validar e otimizar muito bem o código.
Desvantagens dos compiladores:
 você não pode mudar o código sem ter que recompilar todo o programa;
 mesmo com diversas otimizações, o compilador acaba sofrendo com o seu tempo de finalização do
código;
 outro problema que podemos ter é no suporte de várias versões de um programa que é gerado a
partir do mesmo compilador.
Vantagens e desvantagens dos interpretadores
Vantagens dos interpretadores:
 são fáceis de usar, especialmente para iniciantes;
 a execução é linha por linha, sendo assim fica mais fácil de encontrar o erro;
 nenhum código intermediário, por tanto, utiliza a memória de maneira mais inteligente.
Desvantagens dos interpretadores:
 o tempo de execução é muito grande, devido a forma de que se é traduzido;
 para ser executado deve-se ter um programa correspondente ao interpretador;
 menos seguro.
9. Conclusão
No presente trabalho concluimos que: O compilador é um tradutor que transforma uma determinida fonte
de uma linguagem de alto nivel para um objecto de baixo nivel e que por sua vez obdece uma determinada
estrutura e são observadas duas etapas a fase de análise e sintese.
Os compiladores obedecem formas de implementação muito coensas para a obtenção dos resulatados onde
as funcionalidades são executadas simultaneamente e/ou agrupadas em fases de forma a obter os melhores
resultados.
10. Referencias
https://www.dca.fee.unicamp.br/~eleri/ea876/04/cap3.pdf
https://blog.betrybe.com/tecnologia/compilador-o-que-e/#4
https://johnidm.gitbooks.io/compiladores-para-humanos/content/part1/introduction-and-overview-about-
compilers.html

Você também pode gostar