desenvolvimento de um interpretador - DEEI

Propaganda
UNIVERSIDADE DO ALGARVE
Faculdade de Ciências e Tecnologia
Disciplina de Compiladores
Relatório do Trabalho Prático 3:
DESENVOLVIMENTO DE UM
INTERPRETADOR
Discentes:
Renato Santos nº 24143
Ricardo Cruz nº 22937
Introdução
O objectivo deste nosso trabalho é elaborar um interpretador para uma linguagem de
programação muito simples, a que se irá dar o nome de MiniJava, e que é um
subconjunto da linguagem Java. Nesta linguagem é possível utilizar variáveis e
constantes dos tipos lógico e inteiro (de 32 bits) com sinal. Podem também ser
utilizadas variáveis do tipo array de inteiros. A linguagem aceita expressões aritméticas
e lógicas e operações relacionais simples, construções condicionais do tipo if-else, e
construções while.
Definição dos tokens
Foram dados os seguintes tokens com as respectivas expressões regulares
ID = [A-Za-z][A-Za-z0-9_]*
INT_LIT = [0-9]+
TRUE = “true”
FALSE = “false”
INT = “int”
BOOL = “boolean”
NEW = “new”
IF = “if”
ELSE = “else”
WHILE = “while”
PRINT = “System.out.println”
PARSEINT = “Integer.parseInt”
CLASS = “class”
PUBLIC = “public”
STATIC = “static”
VOID = “void”
MAIN = “main”
STRING = “String”
LENGTH = “length”
ARGS = “args”
DOT = “.”
OCURV = “(”
CCURV = “)”
OBRACE = “{”
CBRACE = “}”
OSQUARE = “[”
CSQUARE = “]”
OP = “&&” | “<” | “+” | “-” | “*”
NOT = “!”
ASSIGN = “=”
SEMIC = “;”
COMMENT = “//[^\n]*”
Gramática
Inicialmente foi dada a seguinte gramática:
Program CLASS ID OBRACE PUBLIC STATIC VOID -> MAIN OCURV STRING
OSQUARE CSQUARE ARGS CCURV OBRACE { VarDecl }
{ Statement } CBRACE CBRACE
VarDecl -> Type ID SEMIC
Type-> INT OSQUARE CSQUARE | BOOL | INT
Statement ->OBRACE { Statement } CBRACE
Statement -> IF OCURV Exp CCURV Statement ELSE Statement
Statement -> WHILE OCURV Exp CCURV Statement
Statement->PRINT OCURV Exp CCURV SEMIC
Statement->ID ASSIGN Exp SEMIC
Statement->ID OSQUARE Exp CSQUARE ASSIGN Exp SEMIC
Exp->Exp OP Exp
Exp-> Exp OSQUARE Exp CSQUARE
Exp->INT_LIT | ID | TRUE | FALSE
Exp->NEW INT OSQUARE Exp CSQUARE
Exp->OCURV Exp CCURV
Exp->NOT Exp
Exp->Exp DOT LENGTH
Exp->ARGS DOT LENGTH
Exp->PARSEINT OCURV ARGS OSQUARE Exp CSQUARE CCURV
Após esta gramática efectuamos algumas alterações às regras para permitir a análise
descendente. Assim sendo, tivemos de implementar novas regras de forma a eliminar a
recursividade á esquerda e ambiguidade nas regras:
Exp->Exp OP Exp
Exp-> Exp OSQUARE Exp CSQUARE
Exp->Exp DOT LENGTH
Consultando [2] na página 52, efectuámos as alterações gramaticais lá indicadas e
obtivemos a seguinte gramática:
Program -> CLASS ID OBRACE PUBLIC STATIC VOID -> MAIN OCURV STRING
OSQUARE CSQUARE ARGS CCURV OBRACE { VarDecl } { Statement } CBRACE
CBRACE
VarDecl -> Type ID SEMIC
Type-> INT OSQUARE CSQUARE | BOOL | INT
Statement ->OBRACE { Statement } CBRACE
Statement -> IF OCURV Exp CCURV Statement ELSE Statement
Statement -> WHILE OCURV Exp CCURV Statement
Statement->PRINT OCURV Exp CCURV SEMIC
Statement->ID ASSIGN Exp SEMIC
Statement->ID OSQUARE Exp CSQUARE ASSIGN Exp SEMIC
Exp->(INT_LIT | ID | TRUE | FALSE) Exp’
Exp->NEW INT OSQUARE Exp CSQUARE Exp’
Exp->OCURV Exp CCURV Exp’
Exp->NOT Exp Exp’
Exp->ARGS DOT LENGTH Exp’
Exp->PARSEINT OCURV ARGS OSQUARE Exp CSQUARE CCURV Exp’
Exp’-> OP Exp Exp’
>
Exp’-> OSQUARE Exp CSQUARE Exp’
Exp’->DOT LENGTH Exp’
Exp’->E
Código Implementado
Neste trabalho infelizmente não nos foi possível a realização de todas as
funcionalidades inicialmente previstas. Implementámos apenas a elaboração da análise
sintáctica da gramática e a impressão da árvore sintáctica correspondente. Já as
interpretações pedidas não conseguimos implementar.
Criámos um ficheiro Minijava.jjt que contém a implementação dos tokens e das regras
da gramática modificada.
Para compilar o código implementado usa-se em primeiro lugar o comando:
jjtree Minijava.jjt
Para de seguida gerar o código Java com o JavaCC:
javacc Minijava.jj
E por último compilar o código Java gerado:
Javac *.java
Para correr o programa deve-se especificar o ficheiro a analisar na linha de comandos:
java Minijava <input.java>
Todos os ficheiros produzidos são enviados juntamente com este relatório.
Testes
Foram criados quatro ficheiros de teste:
2 válidos: contador.java, maximo.java
2 inválidos: contador2.java, maximo2.java
No contador.java tentámos utilizar a gramática para a elaboração de um programa que
imprime no ecrã uma listagem de números inteiros que se inicia em 0 e termina em 10.
No maximo.java é um programa que dados dois números á escolha do utilizador ele
indica qual o maior número dos dois números inseridos.
No contador2.java foi alterada a expressão “ numero= numero +1 “ para “ numero++ “ e
verificamos que o programa irá dar erro pelo facto de esta expressão não estar de acordo
com a gramática existente, o que não é aceite pela gramática.
No maximo2.java tentámos fazer algo como if ( num1 <= num2 ) mas tal não é
permitido pela nossa gramática.
Devidos às limitações descritas no ponto anterior não podemos interpretar os ficheiros
de teste criados. Testámos apenas se a análise sintáctica de cada um dos ficheiros dá
erro ou não. Verificámos que ambos os ficheiros válidos completavam a análise
sintáctica e imprimiam a respectiva árvore sintáctica. Já os dois ficheiros inválidos
deram erro de sintaxe.
Bibliografia
[1] http://w3.ualg.pt/%7Ejmcardo/ensino/compiladores/
[2] Andrew W. Appel. Modern Compiler Implementation in Java, Cambridge
University Press, 2002.
[3] http://www.engr.mun.ca/~theo/JavaCC-Tutorial/
Download