MAB 471 – Compiladores I

MAB 471 - Compiladores I

Fabio Mascarenhas

Apresentação

Está é a página da disciplina Compiladores I, MAB 471, do professor Fabio Mascarenhas, para o semestre de 2011.2. As aulas da disciplina são às segundas e quartas, das 15 às 17 horas, no LAB I do DCC.

Avaliação

A avaliação será feita pela média ponderada das notas dos quatro trabalhos práticos, com os pesos a seguir:

A média final é dada por (T1 + T2 + T3 + T4*2)/5. Aqueles que tiverem média final menor do que 7,0 e maior do que 3,0 deverão fazer uma prova final discursiva. A média da prova final com a média final (MF + PF)/2 deverá ser maior do que 5,0 para o aluno ser aprovado.

Trabalhos Práticos

Os trabalhos práticos correspondem às diferentes fases de um compilador da linguagem Gossip, uma linguagem orientada a objeto com tipagem dinâmica:

  1. Analisador léxico, usando JFlex
  2. Analisador sintático, usando JACC
  3. Analisador semântico
  4. Gerador de código assembler para a Lua Virtual Machine, usando código auxiliar fornecido pelo professor

Os trabalhos serão feitos em dupla. As mesmas duplas valerão para todos os quatro trabalhos, exceto em casos de trancamento ou abandono, que serão resolvidos caso a caso.

Analisador Léxico

Cada dupla deverá construir um analisador léxico completo para a linguagem Gossip. A classe do analisador deverá ser GossipScanner, e os tokens retornados pelo método getToken() deverão ter o tipo GossipToken definido por GossipToken.java. Teste seu scanner usando o driver GossipDriver.java. O arquivo exemplo.gossip não é um programa sintaticamente válido, mas exercita todos os tokens do scanner. Se quiser pode comparar a saída do seu scanner com a do scanner que eu gerei: GossipScanner.class.

A entrega do trabalho deverá ser feita até o dia 12/09/2011, uma segunda-feira, por email em formato zip. Trabalhos atrasados terão pontos descontados: 1 ponto para um dia de atraso, 2 pontos para dois dias, 4 pontos para três dias, 8 pontos para quatro dias de atraso.

Se tiver qualquer dúvida sobre a especificação da linguagem ou o funcionamento do scanner procure o professor antes de inventar.

Analisador Sintático

Cada dupla deverá construir um analisador sintático para a linguagem Gossip. O analisador não gerará uma árvore sintática, mas sim uma saída equivalente ao programa de entrada, com a precedência dos operadores tornada explícita via parênteses.

Não é preciso fazer a geração de mensagens de erro precisas, mas o analisador deve rejeitar programas sintaticamente inválidos. Use os seguintes arquivos para a construção do analisador:

Note que o analisador sintático usa a classe do analisador léxico, se achar que o seu tem bugs pode usar GossipScanner.class no lugar.

Dica importante: primeiro escreva todo o parser sem ações e certifique-se de que ele analisa sem erros todos os exemplos corretos e dá erro de sintaxe em todos os programas errados. Só depois adicione as ações montam o programa resultado.

Se quiser pode comparar a saída do seu parser com a do parser que eu gerei: GossipParser.class. A saída do seu não precisa ser idêntica, apenas ser um programa equivalente!

A entrega do trabalho deverá ser feita até o dia 12/10/2011, uma quarta-feira, por email em formato zip. Trabalhos atrasados terão pontos descontados: 1 ponto para um dia de atraso, 2 pontos para dois dias, 4 pontos para três dias, 8 pontos para quatro dias de atraso.

Se tiver qualquer dúvida sobre a especificação da linguagem ou o funcionamento do parser procure o professor antes de inventar.

A especificação JACC do meu analisador está aqui.

AST e Análise Semântica

Cada dupla deverá modificar a especificação de um parser simplificado de Gossip para gerar uma árvore sintática abstrata ao invés da saída atual. O projeto das classes que compõem a AST fica a cargo de cada dupla, sugiro que sigam os moldes da árvore sintática de TINY. O método toString dos nós da árvore sintática deve retornar uma representação textual daquele fragmento do programa usando a sintaxe de Gossip. Em particular, parser.output.toString() deve ser igual à saída atual do parser.

Cada dupla também deverá escrever um analisador semântico para Gossip que constrói e preenche as tabelas de símbolos de cada escopo e faz as checagens estáticas dadas na seção de Semântica Estática da página de Gossip. Use o padrão visitor nos moldes do analisador semântico de TINY para projetar a implementar a análise semântica de Gossip.

As tabelas de símbolos para variáveis devem associar cada variável com duas informações: qual o tipo de escopo em que ela existe (global, objeto ou local) e com um índice numérico que dá a ordem em que ela foi declarada no seu escopo (não se esqueça dos parâmetros, eles vivem no mesmo escopo local do corpo do método); a tabela de símbolos de classes deve associar cada classe com o nó da árvore sintática que corresponde à declaração daquela classe.

Use os seguintes arquivos como ponto de partida:

Alguns dos programas exemplo usa a classe Array, considerem que ela é uma classe pré-definida. Lembrem-se que não existe declaração de globais em Gossip, e toda variável não encontrada em nenhum dos nívels léxicos deve ser considerada uma global.

Será responsabilidade de cada grupo bolar programas errados para testar os casos de falha da análise semântica. As mensagens de erro da análise semântica também devem ser precisas em relação ao tipo do erro e ao local em que ele foi detectado (linha e coluna).

A entrega do trabalho deverá ser feita até o dia 21/11/2011, uma segunda-feira, por email em formato zip. Trabalhos atrasados terão pontos descontados: 1 ponto para um dia de atraso, 2 pontos para dois dias, 4 pontos para três dias, 8 pontos para quatro dias de atraso.

Se tiver qualquer dúvida sobre a especificação da linguagem ou o funcionamento do parser procure o professor antes de inventar.

Geração de Código

Cada dupla deverá terminar o compilador Gossip escrevendo o gerador de código usando as informações presentes na página da linguagem. Vocês podem usar esse projeto Eclipse como base, procurando pelos comentários TODO. O resultado deve ser um compilador que lê um programa fonte Gossip e escreve um programa em assembler da LVM. Vocês devem usar o arquivo JAR executável assembler.jar para transformar os programas em assembler em binários executáveis pelo JAR executável gossip.jar. Por exemplo, se você compilou o programa exemplo.gossip para exemplo.asm deve montar e executá-lo com os seguintes comandos:

  java -jar assembler.jar exemplo.asm
  java -jar gossip.jar d.out

A entrega do trabalho deverá ser feita até o dia 11/12/2011, um domingo, por email. Trabalhos atrasados terão pontos descontados: 1 ponto para um dia de atraso, 2 pontos para dois dias, 4 pontos para três dias, 8 pontos para quatro dias de atraso. Como sempre, se tiver qualquer dúvida sobre o funcionamento da linguagem procure o professor.

Lista de Discussão

A lista de discussão para esta disciplina está no o Piazzza. Acessem esse link e sigam as instruções do site para se inscrever (usem seu email da UFRJ).

Livros

O livro texto da disciplina é o "Compiladores: princípios e práticas", de Kenneth C. Louden. Ele está disponível na biblioteca do CCMN.

"Crafting a Compiler with C" de Charles Fischer também tem uma boa cobertura dos aspectos práticos da construção de um compilador, e está disponível na biblioteca do CT e do NCE.

Um excelente livro para quem quiser se aprofundar mais sobre o tema é a segunda edição do "Engineering a Compiler", de Keith D. Cooper e Linda Torczon. Infelizmente ele não está disponível em nenhuma das bibliotecas da UFRJ.

Existe farto material online sobre construção de compiladores, incluindo livros completos. Um bem sintético e com ênfase em construção manual de scanners e parsers recursivos é o livro "Compiler Construction" de Niklaus Wirth, disponível em PDF aqui. Outro livro, mais detalhista, é o "Basics of Compiler Design" de Torben Mogensen, disponível nessa página.

Slides

Material Adicional

Compilador de expressões aritméticas

Os fontes para o compilador de expressões aritméticas mostrados na aula de 08/08/2011 estão aqui. Calc.java é o compilador, que lê expressões da entrada padrão e escreve o código assembler para LVM na saída padrão. Os scripts calc e calc.bat (para Windows) executam o compilador, gravando a saída dele em um arquivo calc.asm e depois montando e executando a saída.

Driver, tokens e especificação do analisador léxico para TINY

Especificação léxica de TINY

Palavras reservadas: if, then, else, end, repeat, until, read, write.

Operadores: +, -, *, /, =, <, (, ), ;, :=.

Números: um ou mais dígitos.

Identificadores: letras seguidas de letras, números ou _.

Comentários: cercados por chaves ({...}), não podem ser aninhados.

Parser Recursivo para TINY

O projeto Eclipse do parser recursivo feito na aula de 12/09/2011 está aqui.

Parser JACC para TINY

O project Eclipse do parser JACC feito na aula de 21/09/2011 está aqui.

AST e Análise Semântica para TINY (com declarações)

O projeto Eclipse da geração da AST e do analisador semântico para TINY feito nas aulas de 17, 19 e 24/10 está aqui.

Gerador de Código para TINY - Parte 1

O projeto Eclipse da primeira parte do gerador de código para TINY, feito na aula de 31/10, está aqui. Os slides mostrados em sala estão aqui.

Gerador de Código para TINY - Parte 2

O projeto Eclipse da segunda parte do gerador de código para TINY, feito na aula de 07/11, está aqui. Os slides foram atualizados.

Gerador de Código para TINY - Parte 3

O projeto Eclipse da terceira parte do gerador de código para TINY, feito na aula de 09/11, está aqui. Atentem para fact_func.tiny, um programa de teste que exercita as extensões que foram feitas à TINY nessa aula.

Gerador de Código para TINY - Final

O projeto Eclipse da quarta e última parte do gerador de código para TINY, feito na aula de 23/11, está aqui. Lembrem-se que foram adicionadas o comando break, declarações de arrays, atribuição a arrays, e indexação de arrays.

Contato

Podem entrar em contato pelo meu email que responderei assim que possível. Também tenho um horário de atendimento de alunos na minha sala, segundas e quartas de 17 às 18 horas. A sala é a E-2013 do DCC.


Last modified: Mon Dec 5 16:52:58 BRST 2011