Construção de Compiladores.
Primeiro Semestre de 2004.
Prof. José de Oliveira Guimarães.
Segundo Trabalho.
Prazo de Entrega: 14 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
::= “variavel” VarDec { “,” VarDec }
VarDec
::= Type Id
CompositeCommand
::= “inicio” Command { Command } “fim”
Command
::= “leia” Id | “escreva” OrExpr | CompositeCommand
| ParaCommand | EnquantoCommand |
SeCommand
| AtribuicaoCommand
Type
::= “inteiro” | “booleano”
AtribuicaoCommand
::= Id “=” OrExpr
ParaCommand
::= “para” Id “=” OrExpr “ate” OrExpr “faca” Command
EnquantoCommand
::= “enquanto” OrExpr “faca” Command
SeCommand
::= “se” OrExpr “entao” Command [
“senao” Command ] “fimse”
OrExpr
::= AndExpr [ "ou" AndExpr ]
AndExpr
::= RelExpr [ "e" RelExpr ]
RelExpr
::= AddExpr [ RelOp AddExpr ]
AddExpr
::= MultExpr { AddOp MultExpr }
MultExpr
::= SimpleExpr { MultOp SimpleExpr }
SimpleExpr
::= Number | "verdadeiro" | "falso" |
| '(' OrExpr ')' | "nao"
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 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, os tipos booleanos são “verdadeiro” e “falso” e não há caracteres literais nesta produção. Você pode copiar toda a análise sintática e a ASA para expressões deste compilador. A análise sintática, já adaptada para esta gramática de expressões modificada, está aqui. Falta fazer a análise semântica.
Um programa na linguagem descrita acima poderia ser
variavel inteiro i, inteiro n, booleano ok
inicio
leia n
para i = 1 ate
n faca
escreva i*i
leia n
i = 2
ok = verdadeiro
enquanto i < n faca
inicio
se n/i == 0
entao
ok = falso
fimse
i = i + 1
fim
se ok entao escreva 1 senao escreva 0
fimse
fim
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 verdadeiro ou falso;
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 “se” e “enquanto” é booleana;
- se a variável e as expressões do comando “para to faca” são todas inteiras;
- 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.