Você está na página 1de 11

INSTITUTO FEDERAL DE EDUCAÇÃO, CIÊNCIA E TECNOLOGIA DO TRIÂNGULO MINEIRO

CURSO DE ENGENHARIA DE COMPUTAÇÃO

DISCIPLINA DE COMPILADORES

PROJETO FINAL

Prezado aluno,

Este documento especifica o projeto final da disciplina de compiladores. Para realizá-lo os


alunos deverão se agrupar em trios. A implementação deverá ser feita em Java, utilizando
o NetBeans. A entrega do projeto deverá ser feita através do e-mail
rogerionepomuceno@iftm.edu.br, o qual deverá conter como assunto “Compiladores –
Projeto Final” e ter como corpo o nome completo dos alunos envolvidos.

Os seguintes itens serão avaliados:

1. Interface
2. Análise Léxica
3. Análise Sintática
4. Geração de Código
5. Interpretação do Código Gerado

Figura 1

A Figura 1 ilustra como deverá ser a interface com o usuário. Nela podemos visualizar o
menu, o qual é composto pelos itens:

1. Arquivo: novo, abrir, fechar, salvar, salvar como, imprimir e sair;


2. Editar: recortar, copiar, colar, limpar, selecionar tudo, localizar e substituir;
3. Executar: compilar e executar;
4. Janela: cascata, lado a lado e organizar tudo;
5. Ajuda: sobre.

Além do menu, podemos identificar pela figura as seguintes paletas:

1. Fonte: nela deverá ser editado o programa fonte;


2. Mensagens: nela deverão ser mostrados as mensagens de erro encontrados durante o
processo de compilação;
3. Itens Léxicos: nela deverão ser mostrados todos os itens léxicos reconhecidos;
4. Tabela de Símbolos: nela deverão ser mostrados todos os itens incluídos na tabela de
símbolos;
5. Código Objeto: nela deverá ser mostrado o código objeto gerado.

A BNF correspondente à gramática para a implementação encontra-se descrita a seguir, a


qual corresponde a uma simplificação e modificação da linguagem PASCAL, sendo
<programa> o ponto de entrada desta gramática.
Esquemas de Tradução – PASCAL SIMPLIFICADO

<programa> ::= program id {A1} <corpo> • {A30}


<corpo> ::= <declara> begin <sentencas> end
<declara> ::= var <dvar> <mais_dc> | 
<mais_dc> ::= ; <cont_dc>
<cont_dc> ::= <dvar> <mais_dc> | 
<dvar> ::= <variaveis> : <tipo_var>
<tipo_var> ::= integer
<variaveis> ::= id {A2} <mais_var>
<mais_var> ::= , <variaveis> | 
<sentencas> ::= <comando> <mais_sentencas>
<mais_sentencas> ::= ; <cont_sentencas>
<cont_sentencas> ::= <sentencas> | 
<var_read> ::= id {A5} <mais_var_read>
<mais_var_read> ::= , <var_read> | 
<var_write> ::= id {A6} <mais_var_write>
<mais_var_write> ::= , <var_write> | 
<comando> ::=
read ( <var_read> ) |
write ( <var_write> ) |
for id {A25} := <expressao> {A26} to {A27} <expressao> {A28}
do begin <sentencas> end {A29} |
repeat {A23} <sentencas> until ( <condicao> ) {A24} |
while {A20} ( <condicao> ) {A21} do begin <sentencas> end
{A22} |
if ( <condicao> ) {A17} then begin <sentencas> end {A18}
<pfalsa> {A19} |
id {A13} := <expressao> {A14}
<condicao> ::= <expressao> <relacao> {A15} <expressao> {A16}
<pfalsa> ::= else begin <sentencas> end | 
<relacao> ::= = | > | < | >= | <= | <>
<expressao> ::= <termo> <outros_termos>
<outros_termos> ::= <op_ad> {A9} <termo> {A10} <outros_termos> | 
<op_ad> ::= + | -
<termo> ::= <fator> <mais_fatores>
<mais_fatores> ::= <op_mul> {A11} <fator> {A12} <mais_fatores> | 
<op_mul> ::= * | /
<fator> ::= id {A7} | <intnum> {A8} | (<expressao>)
Observação sobre a sintaxe da Linguagem Pascal

A construção de programas poderá conter comentários, os quais são inicializados pelo


símbolo "{" e finalizados pelo símbolo "}". Qualquer seqüência de caracteres contidos
entre estes dois delimitadores deverão ser desconsiderados pelo compilador. Portanto,
durante a fase de análise léxica, torna-se viável desprezar todos os comentários. Isto pode
ser feito da seguinte forma:

Se NextCar = '{' então


Enquanto NextCar <> '}' faça
Chamar Ler
Fim faça
Chamar Ler
Fim se
Exemplo de um programa em PASCAL SIMPLIFICADO

{ Programa: Somatório }
{ Autor : Rogério Melo Nepomuceno }
{ Data : 21 de Setembro de 1999 }

Program Somatorio

Var
Ini, Fim, Conta, Soma : integer;
Begin
Ini := 0;
Fim := 0;
Soma := 0;
read( Ini, Fim );
For Conta := Ini To Fim do begin
Soma := Soma + Conta
End;
write( Soma );
End.
Estrutura da Tabela de Símbolos

Type
TEndereco = 0..TamanhoPilhaDados;
TRecTabSim = record of
Lexema : string;
Categoria: Ttoken;
Endereco : Tendereco;
end;
TTabSim = array[1..N] of TrecTabSim;

Tabela de Símbolos do Programa Exemplo

Lexema Categoria Endereco


'somatorio' program
'ini' var 0
'fim' var 1
'conta' var 2
'soma' var 3
Variáveis/Funções Públicas Utilizadas nas Ações Semânticas

S : integer // Variável cujo objetivo é determinar o


// endereço para uma variável na Pilha de
// Dados
R : integer // Variável cujo objetivo é determinar um
// endereço para um rótulo na Pilha de
// Código
GeraRotulo() : integer // Incrementar a variável R e devolver seu
// valor
GeraCode(Rot: inteiro; // Novo Rotulo a ser gerado
Inst: string; // Instrução a ser gerada
K: inteiro) // Constante ou endereço para a Pilha de
// Dados
<id>.Lexema: string // Lexema associado a um atributo
<id>.Token: Token // Classe léxica associada a um atributo
<id>.Addr: inteiro // Endereço do identificador na tabela de
// símbolos
TabSim: TtabSim // Tabela de Símbolos
TabRes: TtabRes // Tabela de Símbolos Reservados
Ações Semânticas

{A1} TabSim[<id>.addr].Categoria := program


GeraCode(_, 'INPP', _)
S := -1
R := 0
{A2} se <id>.Token = id então
se TabSim[<id>.addr].categoria <> var então
S := S + 1
GeraCode(_, 'AMEM', 1)
TabSim[<id>.addr].Categoria := var
TabSim[<id>.addr].Addr := S
Senão
Erro('Tentativa de redeclaração de Identificador: ' +
<id>.Lexema)
fim se
senão
Erro('Identificador Esperado)
fim se
{A3} Indice := BuscaRes(<id>.Lexema)
se Indice <> -1 então
<id>.Token := id
senão
<id>.Token := TabRes[Indice].Token
fim se
<id>.Addr := InsTabSim(<id>.Lexema, <id>.Token)
{A4} <id>.Token := intnun
{A5} se TabSim[<id>.addr].categoria = var então
GeraCode(_, 'LEIT', _)
GeraCode(_, 'ARMZ', TabSim[<id>.addr].Endereco)
senão
Erro('Variável não declarada')
fim se
{A6} se TabSim[<id>.addr].categoria = var então
GeraCode(_, 'CRVL', TabSim[<id>.addr].Endereco)
GeraCode(_, 'IMPR', _)
senão
Erro('Variável não declarada')
fim se
{A7} se TabSim[<id>.addr].categoria = var então
GeraCode(_, 'CRVL', TabSim[<id>.addr].Endereco)
senão
Erro('Variável não declarada')
fim se
{A8} GeraCode(_, 'CRCT', <id>.Lexema)
{A9} OpAd := <op_ad>.Lexema
{A10} caso OpAd seja
'+': GeraCode(_, 'SOMA', _)
'-': GeraCode(_, 'SUBT', _)
fim caso
{A11} OpMul := <op_mul>.Lexema
{A12} caso OpMul seja
'*': GeraCode(_, 'MULT', _)
'/': GeraCode(_, 'DIVI', _)
fim caso
{A13} se TabSim[<id>.addr].categoria = var então
Addr := <id>.addr
senão
Erro('Variável não declarada')
fim se
{A14} GeraCode(_, 'ARMZ', TabSim[Addr].Endereco)
{A15} Rel := <relacao>.Lexema
{A16} caso Rel seja
'=' : GeraCode(_, 'CMIG', _)
'<' : GeraCode(_, 'CMME', _)
'>' : GeraCode(_, 'CMMA', _)
'<=': GeraCode(_, 'CMEG', _)
'>=': GeraCode(_, 'CMAG', _)
'<>': GeraCode(_, 'CMDG', _)
fim caso
{A17} RotElse := GeraRotulo()
RotEnd := GeraRotulo()
GeraCode(_, 'DSVF', RotElse)
{A18} GeraCode(_, 'DSVS', RotEnd)
GeraCode(RotElse, 'NADA', _)
{A19} GeraCode(RotEnd, 'NADA', _)
{A20} RotWhile := GeraRotulo()
RotEnd := GeraRotulo()
GeraCode(RotWhile, 'NADA', _)
{A21} GeraCode(_, 'DSVF', RotEnd)
{A22} GeraCode(_, 'DSVS', RotWhile)
GeraCode(RotEnd, 'NADA', _)
{A23} RotRepeat := GeraRotulo
GeraCode(RotRepeat, 'NADA', _)
{A24} GeraCode(_, 'DSVF', RotRepeat)
{A25} se TabSim[<id>.addr].categoria = var então
Addr := <id>.addr
senão
Erro('Variável não declarada')
fim se
{A26} GeraCode(_, 'ARMZ', TabSim[Addr].Endereco)
{A27} RotFor := GeraRotulo
RotEnd := GeraRotulo
GeraCode(RotFor, 'NADA', _)
GeraCode(_, 'CRVL', TabSim[Addr].Endereco)
{A28} GeraCode(_, 'CMEG', _)
GeraCode(_, 'DSVF', RotEnd)
{A29} GeraCode(_, 'CRVL', TabSim[Addr].Endereco)
GeraCode(_, 'CRCT', 1)
GeraCode(_, 'SOMA', _)
GeraCode(_, 'ARMZ', TabSim[Addr].Endereco)
GeraCode(_, 'DSVS', RotFor)
GeraCode(RotEnd, 'NADA', _)
{A30} GeraCode(_, 'PARA', _)
Tradução do Programa Exemplo

Addr Mnemônico Operando Código Equivalente


0 INPP Program Somatorio;
1 AMEM 1var Ini, // Endereço 0
2 AMEM 1 Fim, // Endereço 1
3 AMEM 1 Conta, // Endereço 2
4 AMEM 1 Soma : integer; // Endereço 3
5 CRCT 0Begin
6 ARMZ 0Ini := 0;
7 CRCT 0
8 ARMZ 1 Fim := 0;
9 CRCT 0
10 ARMZ 2 Conta := 0;
11 LEIT Read(
12 ARMZ 0 Ini
13 LEIT ,
14 ARMZ 1 Fim);
15 CRVL 0 For
16 ARMZ 2 Conta := Ini
17 FOR: NADA
18 CRVL 1 To
19 CMEG Fim
20 DSVF 30 (END) Do Degin
21 CRVL 3 Soma :=
22 CRVL 2 Soma
23 SOMA + Conta
24 ARMZ 3 ;
25 CRVL 0 INCREMENTO
26 CRCT 1 DA
27 SOMA VARIÁVEL DE
28 ARMZ 0 CONTROLE
29 DSVS 17 (FOR) End
30 END: NADA ;
31 CRVL 3 Write(
32 IMPR Soma);
33 PARA End;

Você também pode gostar