Construção de Compiladores.
Primeiro Semestre
de 2007.
Prof. José de Oliveira Guimarães.
Segundo Trabalho.
Prazo de Entrega:
21 de Maio, segunda-feira, até às 12 h.
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 ::= [ “var” VarDec { VarDec } ]
CompositeCommand
CompositeCommand ::= “{” Command {
Command } “}”
Command ::= “read” Id
| “print” OrExpr
| WhileCommand | ForCommand |
IfCommand
| AssignmentCommand |
CompositeCommand
VarDec ::= Id “:” Type
Type ::= “integer” | “boolean”
AssignmentCommand ::= Id “=” OrExpr
WhileCommand ::= “while” “(“ OrExpr
“)” Command
ForCommand ::= “for” “(“ Id “;” OrExpr
“;” OrExpr “)” Command
IfCommand ::= “if” “(“ OrExpr “)” Command
[ “else” Command ]
OrExpr ::= AndExpr [ "or"
AndExpr ]
AndExpr ::= RelExpr [ "and"
RelExpr ]
RelExpr ::= AddExpr [ RelOp AddExpr ]
AddExpr ::= MultExpr { AddOp MultExpr }
MultExpr ::= SimpleExpr { MultOp
SimpleExpr }
SimpleExpr ::= Number | "true"
| "false" |
| '(' OrExpr ')' | "not"
SimpleExpr | AddOp SimpleExpr
| Id
RelOp ::= '<' | '<=' | '>' |
'>='| '==' | '<>'
AddOp ::= '+'| '-'
MultOp ::= '*' | '/' | '%'
Number
::= Digit { Digit }
Digit
::= '0'| '1' | ... | '9'
Algumas observações
sobre a gramática:
1. {
e } representam repetição de zero ou mais vezes;
2. qualquer item entre [ e ] é opcional;
3. Number
representa constantes inteiras
positivas.
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. qualquer
coisa depois
de // até o final
da linha é considerado comentário.
Você
pode pegar o analisador
sintático das expressões já pronto
(e que necessita possivelmente de correções
― não foram testados). 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 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.
Algumas observações sobre a
linguagem:
1. variáveis
booleanas podem conter true ou
false;
2. variáveis
minúsculas e maiúsculas são consideradas diferentes. Todas as palavras-chave
são minúsculas;
3. o
escopo de uma variável é do ponto de declaração ao final do programa;
4. a
variável do comando “for(i; expr1; expr2)”
inicia-se com expr1 e é
incrementada de 1 a
cada passo até expr2. A variável e as expressões devem ser inteiras.
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. A leitura
da entrada deve ser
feita de um arquivo;
Um
programa na linguagem
descrita acima poderia
ser
var n : integer
i : integer
ok : boolean
{
read n
for(i; 1, n)
print i
read n
ok = true
while ( i < n ) {
if ( n/i == 0 or (n – 1)%i == 0 )
ok = false
i = i + 1
}
if ( ok ) print 1 else print 0
}
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 (and, or, not) com valores
booleanos. O menos e mais unário só se aplicam a inteiros;
- se os tipos da variáveis e expressões de um comando “for”
são todos inteiros;
- se o tipo da expressão do “if” e
“while” é bool;
- se leia e escreva escrevem e lêem inteiros.
Veja como são feitas
estas conferências nos
compiladores 9 e 10.