Segundo Trabalho.
Prazo de Entrega: 18 de Maio.
Entregue este trabalho com a folha de correção disponível
na página da disciplina.
Nesta página, veja as observações sobre correção
de trabalho.
Faça um compilador para a seguinte gramática:
Program ::= FunList
FunList ::= FunDec | FunDec FunList
FunDec ::= '(' "fun" IDENT '(' ParamList
')' Expr ')'
ParamList ::= | IDENT ParamList
Expr ::= Number | IDENT | '(' OperCall
')'
OperCall ::= Oper Expr Expr | IDENT
ArgList
ArgList ::= | Expr ArgList
Oper ::= '+' | '-' | '*' | '/' | '>'
| '>=' | '<' | '<='
| '==' | '!='
Um programa poderia ser
(fun previous (n) (- n 1) )
(fun fat(n) (if (> n 1) (* n (fat
(- n 1))) 1))
(fun first() (fat (previous 6)))
Algumas observações:
* há uma função pré-definida chamada "if"
que toma três parâmetros :
(if expr exprThen
exprElse)
Esta função retorna exprThen se expr é true e
exprElse se expr é false;
* a execução do programa é a chamada da função
"first" sem parâmetros, que obrigatoriamente deve ser definida no
programa. O resultado da chamada a first é impresso na saída
padrão;
* a análise semântica deve ser feita. Deve ser conferido
se o número de argumentos passados a uma função é
igual ao número de parâmetros que ela declara, entre outras
coisas. Não termine a execução do programa ao sinalizar
um erro semântico;
* os parâmetros são todos inteiros e todas as funções
retornam inteiros;
* identificadores devem ser compostos por qualquer quantidade de letras
e números, começando por letra;
* números podem ter qualquer número de dígitos,
mas devem estar entre 0 e 32767;
* 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;
* a leitura da entrada deve ser feita de um arquivo;
* possivelmente alguns alunos serão chamados para esclarecimentos
sobre o seus respectivos trabalhos.
A tradução do programa acima para C deve ser:
#include <stdio.h>
/* esta funcao sempre deve ser incluída
*/
int ifExpr( int expr, int exprThen,
int exprElse ) {
if ( expr )
return exprThen;
else
return exprElse;
}
int previous( int n ) {
return (n - 1);
}
int fat(int n) {
return ifExpr( (n > 1),
(n*fat((n
- 1))), 1);
}
int first() {
return fat(previous(6));
}
void main() {
printf("%d\n", first() );
}
O trabalho pode ser individual. Neste caso, o trabalho é aquele
descrito acima. Se for em grupo, este deve ter no máximo duas pessoas
e o trabalho deve ter as seguintes extensões:
1. variáveis e funções devem ter tipos:
(fun int previous
(int n) (- n 1) )
(fun char greater(
char ch1 char ch2 )
(if (>= ch1 ch2)
ch1 ch2 ) )
Os tipos permitidos são int e char. Sobre char apenas são
permitidas as operações de comparação. Naturalmente,
faça todas as conferências semânticas associadas
a tipos. Um caráter deve ser representado como em Java;
2. quando houver um erro sintático, deve-se tentar continuar
a compilação. Isto é, deve-se saltar todos os tokens
até que se encontre um ponto de continuação, que pode
ser um ')' ou a declaração de uma nova função.