Construção de Compiladores.
Primeiro Semestre de 2004.
Prof. José de Oliveira Guimarães.
Segundo Trabalho.
Prazo de Entrega: 20 de Maio.
Entregue este trabalho com a folha de capa disponível na página da disciplina.
Siga as observações sobre correção de trabalhos disponíveis neste site.
Faça um
compilador para a seguinte gramática:
Program
::= VarDecList CompositeCommand
VarDecList
::= “var” VarDec { “,” VarDec } “;”
VarDec
::= Type Id
CompositeCommand
::= Command { Command }
Command
::= “read” Id | “write” OrExpr | RepeatCommand
| WhileCommand | IfCommand | AssignmentCommand
Type
::= “int” | “bool”
AssignmentCommand
::= Id “=” OrExpr
RepeatCommand
::= “repeat” CompositeCommand “until”
OrExpr
WhileCommand
::= “while” OrExpr “do” CompositeCommand “endwhile”
IfCommand
::= “if” OrExpr “then” CompositeCommand
[ “else” CompositeCommand ] “endif”
OrExpr
::= AndExpr [ "||" AndExpr ]
AndExpr
::= RelExpr [ "&&" RelExpr ]
RelExpr
::= AddExpr [ RelOp AddExpr ]
AddExpr
::= MultExpr { AddOp MultExpr }
MultExpr
::= SimpleExpr { MultOp SimpleExpr }
SimpleExpr
::= Number | "true" | "false" |
| '(' OrExpr ')' | "!"
SimpleExpr | AddOp SimpleExpr
| Id
RelOp
::= '<' | '<=' | '>' | '>='| '==' | '<>'
AddOp
::= '+'| '-'
MultOp
::= '*' | '/' | '%'
Number
::= ['+'|'-'] Digit { Digit }
Digit
::= '0'| '1' | ... | '9'
Qualquer coisa depois de // até o final da linha é considerado comentário. Você pode pegar o analisador léxico
e parte do sintático (as expressões) já pronto (e que pode necessitar de correções ― ele não foi testado). Todas as regras de expressões, começando com OrExpr, foram tomadas do compilador 10. Contudo, fizemos algumas modificações em relação a este compilador: não há chamada de função em SimpleExpr, and e or são representados por ||
e && e não há caracteres literais nesta gramática. Você pode copiar toda a análise sintática e a ASA para expressões deste compilador. Falta fazer a análise semântica.
Um programa na linguagem descrita acima poderia ser
var int i, int n, bool ok;
read n
i = 1
repeat
write i*i
i = i + 1
until i > 10
read n
i = 2
ok = true
while i < n do
if n/i == 0 || (n – 1)%i == 0
then
ok = false
endif
i = i + 1
endwhile
if ok then write 1 else write 0 endif
Algumas observações:
1.
{
e } representam repetição de zero ou mais vezes;
2.
qualquer item entre [ e ] é opcional;
3.
Number
representa constantes inteiras positivas. Variáveis booleanas podem conter true ou false;
4.
identificadores
devem ser compostos por qualquer quantidade de letras e números, começando por letra;
5.
números podem ter qualquer número de dígitos, mas devem estar entre 0 e 32767;
6.
o
compilador deve construir a ASA e gerar código a partir dela, em C. A geração de código deve ser feita para um arquivo. Você pode (deve !) utilizar a classe Main do compilador 9. Ela já faz a entrada e saída para arquivos;
7.
a
leitura da entrada deve ser feita de um arquivo;
Naturalmente, o compilador deve fazer a análise semântica. Deve ser conferido:
- se uma variável está sendo redeclarada;
- se uma variável utilizada em algum lugar foi declarada;
- se, em uma atribuição, a variável da esquerda é do mesmo tipo da expressão da direita;
- se o operador (+, -, ou, etc) é compatível com os operandos: operadores aritméticos com inteiros e operadores booleanos (e, ou, nao) com valores booleanos;
- se o tipo da expressão do “if”, “while” e “repeat”-“until”
é bool;
- se leia e
escreva escrevem e lêem inteiros.
Veja como são feitas estas conferências nos compiladores 9 e 10.
O trabalho pode ser em grupo de até duas pessoas.