Compiladores  
Aula 01 Introdução  
Edirlei Soares de Lima  
<edirlei.lima@universidadeeuropeia.pt>  
O que é uma Linguagem de  
Programação?  
Na programação de computadores, uma linguagem de  
programação serve como meio de comunicação entre o  
indivíduo que deseja resolver um determinado problema e o  
computador.  
A linguagem de programação deve fazer a ligação entre o  
pensamento humano (muitas vezes de natureza não  
estruturada) e a precisão requerida para o processamento  
pelo computador.  
O que é uma Linguagem de  
Programação?  
Uma linguagem de programação auxilia o programador no  
processo de desenvolvimento de software:  
Projeto;  
Implementação;  
Teste;  
Verificação;  
Manutenção do software;  
O que é uma Linguagem de  
Programação?  
Uma linguagem de programação é uma linguagem destinada  
para ser usada por uma pessoa para expressar um processo  
através do qual um computador possa resolver um problema.  
Os modelos/paradigmas de linguagens de programação  
correspondem a diferentes pontos de vista dos quais  
processos podem ser expressados.  
Exemplos: Imperativo, orientado a objeto, funcional, lógico  
O que é uma Linguagem de  
Programação?  
Para que se tornem operacionais, os programas escritos em  
linguagens de alto nível devem ser traduzidos para linguagem  
de máquina.  
O que é uma Linguagem de  
Programação?  
A conversão de um código em linguagem alto nível para  
linguagem de máquina é realizada através de sistemas  
especializados:  
Compiladores ou Interpretadores  
Esses sistemas recebem como entrada uma representação  
textual da solução de um problema (expresso em uma  
linguagem fonte) e produzem uma representação do mesmo  
algoritmo expresso em uma linguagem de máquina.  
Métodos de Implementação  
Arquitetura de Von Neumann:  
A linguagem de máquina de um computador é composta por um  
conjunto de macroinstruções;  
Métodos de implementação :  
Compilação;  
Interpretação Pura;  
Métodos Híbridos;  
Métodos de Implementação  
Processo de Compilação  
Um Compilador C é um programa que tem a finalidade de  
traduzir ou converter um programa Pf (fonte) escrito numa  
linguagem Lf (linguagem fonte) para um programa Po (objeto)  
escrito numa outra linguagem Lo (linguagem objeto).  
Entrada  
Pf/Lf  
Computador  
C/Lm  
Saída  
P0/L0  
Programa Fonte  
Compilador  
Programa Objeto  
Lm = L0  
Processo de Compilação  
Em geral, Lf é uma linguagem de alto nível como C, C++,  
PASCAL, etc. Lo não é necessariamente uma linguagem de  
máquina. Por exemplo, Lo pode ser uma Linguagem de  
montagem ("Assembly") La. Nesse caso, é necessário ter-se  
mais uma fase de tradução de La para a linguagem de  
máquina Lm do computador a ser utilizado para processar o  
programa objeto.  
Entrada  
Pf/Lf  
Computador Saída Intermediaria Computador  
Saída  
P0/Lm  
C /Lm  
P0/La  
C /Lm  
Programa Fonte  
Compilador  
Programa Objeto  
Compilador  
Montador  
Programa Objeto  
Processo de Compilação  
unidades léxicas  
Analisador  
Léxico  
Analisador  
Sintático  
Programa-fonte  
árvores sintáticas  
(opcional)  
Gerador de Código  
Intermediário e  
Analisador  
Tabela de Símbolos  
Otimização  
Semântico  
código  
intermediário  
linguagem de máquina  
Programa Objeto  
Gerador de Código  
Processo de Compilação  
Programa-fonte:  
O compilador vê o código como uma sequência de caracteres:  
Processo de Compilação  
unidades léxicas  
Analisador  
Léxico  
Analisador  
Sintático  
Programa-fonte  
árvores sintáticas  
(opcional)  
Gerador de Código  
Intermediário e  
Analisador  
Tabela de Símbolos  
Otimização  
Semântico  
código  
intermediário  
linguagem de máquina  
Programa Objeto  
Gerador de Código  
Processo de Compilação  
O Analisador Léxico reúne os caracteres do programa-fonte  
em unidades léxicas (tokens).  
Identificadores, palavras especiais, operadores, símbolos;  
Comentários são ignorados;  
Processo de Compilação  
unidades léxicas  
Analisador  
Léxico  
Analisador  
Sintático  
Programa-fonte  
árvores sintáticas  
(opcional)  
Gerador de Código  
Intermediário e  
Analisador  
Tabela de Símbolos  
Otimização  
Semântico  
código  
intermediário  
linguagem de máquina  
Programa Objeto  
Gerador de Código  
Processo de Compilação  
O Analisador Sintático utiliza as unidades léxicas (tokens) para  
construir estruturas hierárquicas chamadas de parse trees.  
A árvore é construída a partir das regras da gramática;  
Representam a estrutura sintática do programa.  
Processo de Compilação  
unidades léxicas  
Analisador  
Léxico  
Analisador  
Sintático  
Programa-fonte  
árvores sintáticas  
(opcional)  
Gerador de Código  
Intermediário e  
Analisador  
Tabela de Símbolos  
Otimização  
Semântico  
código  
intermediário  
linguagem de máquina  
Programa Objeto  
Gerador de Código  
Processo de Compilação  
O Analisador Semântico faz parte do Gerador de Código  
Intermediário e realiza a verificação de erros que não que não  
são verificados durante a análise sintática, como erros de tipo.  
O processo de verificação de tipos é realizado consultado a Tabela de  
Símbolos.  
Processo de Compilação  
O Gerador de Código Intermediário produz um programa em  
uma linguagem intermediaria entre o programa-fonte e saída  
final do compilador.  
As linguagens intermediarias se parecem muito com linguagens de  
montagem (e muitas vezes são linguagens de montagem (assembly)).  
Processo de Compilação  
unidades léxicas  
Analisador  
Léxico  
Analisador  
Sintático  
Programa-fonte  
árvores sintáticas  
(opcional)  
Gerador de Código  
Intermediário e  
Analisador  
Tabela de Símbolos  
Otimização  
Semântico  
código  
intermediário  
linguagem de máquina  
Programa Objeto  
Gerador de Código  
Processo de Compilação  
O Gerador de Código converte a versão do código intermediário  
do programa para um programa em linguagem de máquina  
equivalente.  
Interpretação Pura  
Na extremidade oposta dos métodos de implementação, os  
programas podem ser interpretados por outro programa  
chamado Interpretador.  
O interpretador age como uma simulação de software de  
uma máquina cujo ciclo buscar-executar lida com instruções  
de programa em linguagem de alto nível em vez de instruções  
de máquina.  
dados de entrada  
Programa-fonte  
Interpretador  
Resultados  
Interpretação Pura  
O método de interpretação pura tem a séria desvantagem de  
que a execução é de 10 a 100 vezes mais lenta que em  
sistemas compilados.  
Problema: a decodificação das instruções de alto nível é bem mais  
complexa do que as instruções em linguagem de máquina.  
A interpretação é um processo complexo em programas  
escritos em linguagens complexas, pois o significado de cada  
instrução deve ser determinado diretamente do programa-  
fonte em tempo de execução.  
Linguagens mais simples podem ser interpretadas mais facilmente.  
Exemplos: Lisp, Lua, JavaScript...  
Métodos Híbridos  
Alguns métodos de implementação são um meio-termo entre  
os compiladores e os interpretadores puros.  
Eles traduzem programas em linguagem de alto nível para  
uma linguagem intermediária projetada para permitir fácil  
interpretação.  
Esse método é mais rápido do que a interpretação pura porque as  
instruções da linguagem fonte são decodificadas somente uma vez.  
Essas implementações são chamadas de sistemas de  
implementação híbridos.  
Métodos Híbridos  
unidades léxicas  
Analisador  
Léxico  
Analisador  
Sintático  
Programa-fonte  
árvores sintáticas  
Dados de Entrada  
código  
intermediário  
Gerador de Código  
Intermediário  
Interpretador  
Resultados  
Métodos Híbridos  
As implementações iniciais de Java eram todas híbridas. Sua  
forma intermediária, chamada código de bytes, oferece  
portabilidade a qualquer máquina que tenha um interpretador  
de código de bytes e um sistema run-time associado.  
Leitura Complementar  
Aho, A. V., Lam, M. S., Jeffrey, R. S.  
Compiladores: Princípios, Técnicas e  
Ferramentas. 2ª edição, Pearson, 2007.  
ISBN: 978-8588639249.  
Capítulo 1: Introdução  
Sebesta, R. W. Conceitos de Linguagens de  
Programação. 9ª edição Editora Bookman,  
2
011. ISBN: 978-8577807918.  
Capítulo 1: Aspectos Preliminares  
Capítulo 2: Evolução das Principais Linguagens de  
Programação