



Estude fácil! Tem muito documento disponível na Docsity
Ganhe pontos ajudando outros esrudantes ou compre um plano Premium
Prepare-se para as provas
Estude fácil! Tem muito documento disponível na Docsity
Prepare-se para as provas com trabalhos de outros alunos como você, aqui na Docsity
Os melhores documentos à venda: Trabalhos de alunos formados
Prepare-se com as videoaulas e exercícios resolvidos criados a partir da grade da sua Universidade
Responda perguntas de provas passadas e avalie sua preparação.
Ganhe pontos para baixar
Ganhe pontos ajudando outros esrudantes ou compre um plano Premium
Comunidade
Peça ajuda à comunidade e tire suas dúvidas relacionadas ao estudo
Descubra as melhores universidades em seu país de acordo com os usuários da Docsity
Guias grátis
Baixe gratuitamente nossos guias de estudo, métodos para diminuir a ansiedade, dicas de TCC preparadas pelos professores da Docsity
As noções básicas sobre o desenho e implementação de linguagens de programação durante um semestre. Aborda conceitos essenciais para o desenvolvimento de linguagens de programação e a resolução de problemas computacionais. O texto também explora a diferença entre interpretadores e compiladores, e os seus respectivos usos e vantagens.
Tipologia: Esquemas
1 / 6
Esta página não é visível na pré-visualização
Não perca as partes importantes!
Esta unidade curricular pretende transmitir ao longo de um semestre as noções fundamentais sobre o desenho e implementação de linguagens de programação. Muitos dos conceitos estudados são essenciais, não só no de- senvolvimento de linguagens de programação, mas também na resolução de problemas de forma computacional [Win06]. Pretende-se ao mesmo tempo aprofundar o conhecimento acerca do funcionamento de linguagens de progra- mação já existentes através do conhecimento profundo dos seus mecanismos de construção.
If you don’t understand interpreters, you can still write programs; you can even be a competent programmer. But you can’t be a master. (Hal Abelson, in prefácio de [FW08])
Durante esta unidade curricular serão apresentados os componentes fun- damentais de construção de linguagens de programação, o seu modelo de execução, verificação e transformação, tendo como foco uma linguagem de alto nível de abstracção. Ao longo de um semestre serão desenvolvidos de forma incremental algoritmos interpretadores, que serão os veículos privilegi- ados para a aprendizagem da semântica de linguagens, dos sistemas de tipos e das técnicas de compilação. Nesta primeira versão das notas de apoio serão descritos brevemente os tópicos abordados em aula, algum código de apoio, e alguns apontadores para outros recursos de estudo e aprofundamento de conhecimentos. Nesta primeira aula descreve-se a arquitetura geral dos interpretadores e compiladores e a sua utilidade no contexto de um sistema de software. Estes tópicos podem ser mais explorados na bibliografia recomendada (nomeada- mente em [AP02, AVAU06]).
Luís Caires, João Costa Seco ICL 2012-2013^31
compiler
Source Program int f(int x) { }^ return^ x+1;
Executable program movl movl %edi,-4(%rbp), -4(%rbp) %eax addl movl $1,%eax, %eax -12(%rbp) movl movl -12(%rbp),%eax, -8(%rbp) %eax movl popq -8(%rbp),%rbp %eax ret
machine
Input data 1001010101010101 (^00101010101001010101010101010101) (^01010101011010111101011010111010) 0110001110101001
Output data 1001010101010101 (^00101010101001010101010101010101) (^01010101011010111101011010111010) 0110001110101001
Figura 1: Compilador
1 Interpretadores / compiladores
Qual a diferença entre um compilador e um interpretador? o que é uma lin- guagem máquina? ou uma linguagem intermédia? o que é um JIT compiler? Cada uma destas ferramentas tem a sua utilidade específica e contexto de utilização adequado. Os interpretadores e compiladores são essencialmente programas cujo comportamento (ou output) não está estabelecido à partida, o seu resultado é definido através de um programa dado como input, escrito numa linguagem de programação. São programas cujos dados são outros programas. Dentro desta categoria encontram-se ainda programas como ferramentas de verifica- ção de programas, ambientes de desenvolvimento, etc. Invariavelmente, os dados de entrada de um compilador e de um interpre- tador é um programa expresso numa linguagem de programação (linguagem fonte). O mais usual é um programa ser expresso por intermédio de um texto, podendo ser expresso de outras formas, usando linguagens visuais por exemplo. Embora a maioria dos conceitos sejam genéricos, no contexto desta unidade curricular focamos em linguagens expressas em texto. A distinção entre interpretadores e compiladores faz-se essencialmente a nível da forma de execução e interação que proporcionam. Existe depois uma miríade de alternativas e combinações sobre as verificações que são fei- tas sobre o código, e sobre a eficiência na execução, e na produtividade da atividade de programação. Os compiladores, cuja interação é representada na Figura 1, transformam
Luís Caires, João Costa Seco ICL 2012-2013^32
compiler
Source Program int f(int return x) x+1;{ }
intermediate language define readnone entry: i32 ssp @f(i32 { %x) nounwind }^ %0^ ret^ =^ i32add^ %0nsw^ i32^ %x,
virtual machine
Input data (^10010101010101010010101010100101) (^01010101010101010101010101101011) (^11010110101110100110001110101001)
Output data (^10010101010101010010101010100101) (^01010101010101010101010101101011) (^11010110101110100110001110101001)
Just in time compiler
Executable code movl movl %edi,-4(%rbp), -4(%rbp) %eax addl movl $1,%eax, %eax -12(%rbp) movl movl -12(%rbp),%eax, -8(%rbp) %eax movl popq -8(%rbp),%rbp %eax ret
Figura 3: Interpretador com compilador JIT
A flexibilidade oferecida pela utilização de um interpretador (da lingua- gem intermédia) é aproveitada no caso das linguagens Java e C# para pos- sibilitar a portabilidade de código. No caso de linguagens como OCaml, Haskell ou Scala, à flexibilidade dada pelo modo interpretação, acrescenta uma verificação de tipos completa e optimizações como a utilização de tail recursion. Na sua estrutura interna, os compiladores e interpretadores partilham alguns componentes, nomeadamente no seu front-end. Na Figura 4, são des- critos os blocos que tipicamente compõem o processo de transformação feito por um interpretador. Os dois primeiros blocos, análise lexicográfica e sintá- tica, transformam o formato de entrada (texto) numa representação interna do programa (tipo de dados) que pode ser mais facilmente tratado por um algoritmo (esta representação será o tema da próxima aula). Essa represen- tação, que pode ou não ser analisada e anotada, é depois interpretada. A arquitetura interna de um compilador é composta por um front-end como aquele descrito para os interpretadores, e por mais duas camadas. Uma camada intermédia e uma camada de saída. A camada intermédia
Luís Caires, João Costa Seco ICL 2012-2013^37
Análise Lexicográfica
Source Program int f(int x) { }^ return^ x+1;
Output data (^10010101010101010010101010100101) (^01010101010101010101010101101011) Análise Sintática^11010110101110100110001110101001
Análise Semântica
tokens
AST
AST anotada
Input data 1001010101010101 (^00101010101001010101010101010101) (^01010101011010111101011010111010) 0110001110101001
Interpretador
Figura 4: Arquitetura de um interpretador
de um compilador típico, faz o tratamento de uma linguagem intermédia. Esta divisão entre front-end e back-end, com um ponto comum numa ca- mada intermédia, permite com uma única ferramenta, criar uma família de compiladores. Compilando e integrando um conjunto de linguagens, e po- dendo produzir código de qualquer destas linguagens para um conjunto de processadores. A Figura 5 mostra os principais blocos que compõem um compilador. Os componentes do front-end de um compilador são basicamente os mesmos do que os de um interpretador. A diferença começa na geração de código numa linguagem intermédia que permite normalmente a realização de operações de análise e optimização de código, e que é agnóstica quanto ao processador para o qual se vai gerar código nativo. O back-end do processador pode então gerar código específico para diferentes processadores, tirando partido das particularidades de cada um.