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.
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.
Os trabalhos práticos correspondem às diferentes fases de um compilador da linguagem Gossip, uma linguagem orientada a objeto com tipagem dinâmica:
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.
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.
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.
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.
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.
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).
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.
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.
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.
O projeto Eclipse do parser recursivo feito na aula de 12/09/2011 está aqui.
O project Eclipse do parser JACC feito na aula de 21/09/2011 está aqui.
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.
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.
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.
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.
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.
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.