• Nenhum resultado encontrado

TRABALHO Nº 4: Desenvolvimento de um Interpretador ou de um Compilador

N/A
N/A
Protected

Academic year: 2021

Share "TRABALHO Nº 4: Desenvolvimento de um Interpretador ou de um Compilador"

Copied!
9
0
0

Texto

(1)

TRABALHO Nº 4: Desenvolvimento de um Interpretador ou de um Compilador

A. Interpretador da Linguagem UAlg+

Pretende-se implementar um interpretador para uma linguagem de programação muito simples, designada por ualg+. Nesta linguagem é possível utilizar variáveis e constantes do tipo inteiro com sinal (representado em 32 bits). Podem também ser utilizadas variáveis do tipo array em que todos os elementos são inteiros representados por 32 bits com sinal. A linguagem aceita expressões aritméticas e operações relacionais, construções condicionais do tipo if e if-else, e construções while. Os programas na linguagem ualg+ são constituídos por uma única função (a função tem de devolver sempre um valor inteiro armazenado numa variável e pode ter ou não argumentos), não existem chamadas a funções, e os argumentos são sempre passados por valor. A linguagem ualg+ não deve diferenciar minúsculas de maiúsculas.

O primeiro elemento de um array é indexado com o valor 0. O número de elementos de cada array não necessita de ser definido estaticamente.

São apresentados na Figura 1 exemplos e algumas restrições da linguagem. A gramática de uma linguagem similar encontra-se representada em EBNF na secção 2.

A Figura 2 apresenta exemplos de programas em ualg+.

Para executar o interpretador deve introduzido o comando:

java ualg [-p|-b] programa.ualg

As opções –p e –b devem ser incorporadas para permitir a interpretação linha-a-linha (opção: –p) e a interpretação até encontrar uma instrução print (opção: –b). As funções com argumentos devem originar que o interpretador solicite ao utilizador a inserção via teclado do valor para cada um dos argumentos. O interpretador deve escrever no ecrã o valor retornado pela função.

(2)

Tipo Instruções e operações

Exemplo Operações aritméticas e lógicas *, /, +, -, <<,

>>, &, |, ^

a=2*b;

/*RHS com apenas uma operação */

Relacionais (Apenas utilizados como teste nas construções if, if-else, while)

==, !=, >, <,

>=, <=

If(a >= b) { ... }

/* Apenas utilizados no teste da condição pelas construções if, if-else, e while */

Construções condicionais If, if-else If(a == b) { c=2;

}

Construções cíclicas while While(a != 2) { a = a-1;

}

Atribuição = A=2;

A=b;

Imprimir a string e o valor da variável no ecrã (com mudança de linha)

print Print(“a: ”, a);

Ler inteiro do ecrã read A=read;

Arrays A[i], A[2], etc. A[i] = 2; // atribui ao elemento i do array A o valor 2

C=A[3]; // atribui a C o valor do 4º elemento do array A

A=[123]; // reserva memória para array com 123 elementos

Figura 1. Operações e construções suportadas pela linguagem ualg+.

Count(word) { cont=0;

n = 0;

While(n < 32) { teste = word & 1;

If(teste == 1) { cont = cont +1;

}

word = word >> 1;

n = n + 1;

}

return cont;

}

sqrt(vsqn) {

vsq=vsqn; asq=0; a=0;

tvsq=0; I=0;

While(I < 6) { nasq1 = asq + a;

nasq2 = nasq1 << 2;

nasq = nasq2 | 1;

sa = a << 1;

tvsq1 = tvsq << 2;

Vsq1 = vsq >> 10;

Vsq2 = vsq1 & 3;

tvsq = tvsq1 | vsq2;

vsq = vsq << 2;

if(nasq <= tvsq) { a = sa | 1;

asq = nasq;

} else { a = sa ;

asq = asq << 2 ; }

I = i+1;

} return a;

}

Max() { A=Read;

B=Read;

Max=a;

If(max < b) { Max = b;

}

Print(“max: “, max);

Return max;

} (a)

Max(a, b) { Max=a;

If(max < b) { Max = b;

}

Return max;

} (b) Conta nº de bits com valor

“1” no conteúdo da variável passada como argumento.

Calcula a raiz quadrada de um número inteiro sem sinal representado por 12 bits. Retorna o valor inteiro da raiz quadrada representado por 6 bits.

Dois programas para determinar o valor máximo de duas variáveis:

(a) versão com leitura/escrita de dados; (b) versão sem

leitura/escrita de dados.

Figura 2.Exemplo de programas na linguagem ualg+.

(3)

A nota final terá em conta os pesos dados a cada uma das tarefas a realizar. A contribuição de cada tarefa na nota global é apresentada na Figura 3.

Cada grupo deve realizar uma apresentação do trabalho. No inicio da apresentação deverá ser entregue um pequeno relatório a descrever as opções tidas durante o desenvolvimento e as restrições do compilador. O relatório deve incluir em anexo o ficheiro de entrada do JJTree.

Tarefa Percentagem na nota

Analisador sintáctico sem geração da árvore sintáctica (inclui especificação da gramática no JavaCC)

15%

Criação da árvore sintáctica anotada utilizando o JJTree (para validação o interpretador deve imprimir no ecrã a árvore sintáctica e as anotações)

15%

Interpretação de sequências de instruções com expressões aritméticas. Incluir a leitura de valores pelo teclado dos argumentos da função e, a escrita do valor retornado pela função e a implementação das instruções read e print.

10%

Interpretação de instruções de código com arrays. 10%

Interpretação de estruturas condicionais (if, if-else) 10%

Interpretação de estruturas cíclicas (while) 10%

Opções de interpretação (opções –b e –p) 10%

Legibilidade e estrutura do código, apresentação do trabalho, etc. 20%

Melhor interpretador Bónus: 10%

Figura 3. Percentagem na nota final no trabalho de cada tarefa.

A.1 Gramática Inicial da Linguagem ualg+

De seguida é apresentada a gramática inicial da linguagem (esta gramática foi escrita de forma a ser o mais intuitiva possível e o mais próximo possível da gramática que deverá ser especificada no JavaCC):

IDENTIFIER = [a-z][a-z0-9]*

LITERAL = [0-9]+

STRING = “\““ [a-zA-Z0-9”:”” “]+ “\““

// os operadores têm o mesmo significado e precedência do que na linguagem Java

RELA_OP = “>“ | “<“ | “==“ | “!=“ | “>=” | “<=”

OTHER_OP = “*“ | “/“ | “&“ | “|“ | “<<” | “>>” | “^”

ADD_SUB = “+“ | “-“

(4)

LPAR = “(“

RPAR = “)”

VIRG = “,”

PVIRG = “;”

LCHAVETA = “{“

RCHAVETA = “}“

ASSIGN = “=“

WHILE = “while”

IF = “if”

ELSE = “else”

RETURN = “return”

PRINT= ”print”

READ= ”read”

Start → IDENTIFIER LPAR [Varlist] RPAR LCHAVETA Stmtlst RETURN IDENTIFIER PVIRG RCHAVETA

Varlist → IDENTIFIER ["[" "]"] {VIRG IDENTIFIER ["[" "]"]}

Stmtlst → {Stmt}

Stmt → Assign | While | If | Print Assign → Lhs ASSIGN Rhs PVIRG

Rhs → Term [(ADD_SUB | OTHER_OP) Term]

| "[" Index "]"

Lhs → IDENTIFIER ["[" Index "]"]

Term → IDENTIFIER ["[" Index "]"]

| [ADD_SUB] LITERAL

| READ

Index → IDENTIFIER | LITERAL Exprtest → LPAR Lhs RELA_OP Rhs RPAR

While → WHILE Exprtest LCHAVETA Stmtlst RCHAVETA If → IF Exprtest LCHAVETA Stmtlst RCHAVETA

[ELSE LCHAVETA Stmtlst RCHAVETA]

Print → PRINT LPAR STRING VIRG IDENTIFIER RPAR PVIRG

(5)

B. Compilador da Linguagem UAlg

Pretende-se implementar um compilador para uma linguagem de programação muito simples, designada por ualg. Nesta linguagem todas as variáveis e constantes são do tipo inteiro com sinal (representado em 32 bits). A linguagem aceita expressões aritméticas e operações relacionais, construções condicionais do tipo if e if-else, e construções while. Os programas na linguagem ualg são constituídos por uma única função (a função tem de devolver sempre um inteiro armazenado numa variável e pode ter ou não argumentos), não existem chamadas a funções, e os argumentos são sempre passados por valor. A linguagem ualg não deve diferenciar minúsculas de maiúsculas.

São apresentados na Figura 4 exemplos e algumas restrições da linguagem. A gramática de uma linguagem similar encontra-se representada em EBNF na secção 2.

A Figura 5 apresenta exemplos de programas em ualg.

Tipo Instruções e

operações Exemplo Operações aritméticas e lógicas *, /, +, -, <<,

>>, &, |, ^

a=2*b;

/*RHS com apenas uma operação */

Relacionais (Apenas utilizados como teste nas construções if, if- else, while)

==, !=, >, <,

>=, <= If(a >= b) { ... }

/* Apenas utilizados no teste da condição pelas construções if, if-else, e while */

Construções condicionais If, if-else If(a == b) { c=2;

}

Construções cíclicas while While(a != 2) { a = a-1;

}

Atribuição = A=2;

A=b;

Imprimir a string e o valor da variável no ecrã (com mudança de linha)

print Print(“a: ”, a);

Ler inteiro do ecrã read A=read;

Figura 4. Operações e construções suportadas pela linguagem ualg.

O compilador deve gerar uma rotina em código MIPS (utilização do simulador spim [3] para validar os resultados) [4] que implemente a funcionalidade descrita na função ualg existente no ficheiro de origem.

Para executar o compilador deve ser introduzido o comando:

java ualg [-o] programa.ualg

(6)

A opção –o deve ser considerada pelos alunos que consigam optimizar a geração do código:

● Utilização do menor número possível de espaço em memória para armazenar variáveis (atribuir o maior número possível de variáveis a registos do microprocessador);

Count(word) { cont=0;

n = 0;

While(n < 32) { teste = word & 1;

If(teste == 1) { cont = cont +1;

}

word = word >> 1;

n = n + 1;

}

return cont;

}

sqrt(vsqn) { vsq=vsqn;

asq=0;

a=0;

tvsq=0;

I=0;

While(I < 6) { nasq1 = asq + a;

nasq2 = nasq1 << 2;

nasq = nasq2 | 1;

sa = a << 1;

tvsq1 = tvsq << 2;

Vsq1 = vsq >> 10;

Vsq2 = vsq1 & 3;

tvsq = tvsq1 | vsq2;

vsq = vsq << 2;

if(nasq <= tvsq) { a = sa | 1;

asq = nasq;

} else { a = sa ;

asq = asq << 2 ; }

I = i+1;

} return a;

}

Max() { A=Read;

B=Read;

Max=a;

If(max < b) { Max = b;

}

Print(“max: “, max);

Return max;

} (a)

Max(a, b) { Max=a;

If(max < b) { Max = b;

}

Return max;

} (b)

Conta nº de bits com valor “1” no conteúdo da variável passada como argumento.

Calcula a raiz quadrada de um número inteiro sem sinal representado por 12 bits. Retorna o valor inteiro da raiz quadrada representado por 6 bits.

Dois programas para determinar o valor máximo de duas variáveis: (a) versão com leitura/escrita de dados;

(b) versão sem leitura/escrita de dados.

Figura 5.Exemplo de programas na linguagem ualg.

A nota final terá em conta os pesos dados a cada uma das tarefas a realizar. A contribuição de cada tarefa na nota global é apresentada na Figura 6.

Cada grupo deve realizar uma apresentação do trabalho. No inicio da apresentação deverá ser entregue um pequeno relatório a descrever as opções tidas durante o desenvolvimento e as restrições do compilador. O relatório deve incluir em anexo o ficheiro de entrada do JJTree.

(7)

Tarefa Percentagem na nota

Analisador sintáctico sem geração da árvore sintáctica (inclui

especificação da gramática no JavaCC) 20%

Criação da árvore sintáctica anotada utilizando o JJTree (para validação o compilador deve imprimir no ecrã a árvore sintáctica e as anotações)

20%

Geração de código para sequências de instruções com expressões

aritméticas. 10%

Geração de código para estruturas condicionais (if, if-else) 10%

Geração de código para estruturas cíclicas (while) 10%

Optimizações ao nível do código assembly gerado (opção do

compilador –o) 10%

Legibilidade e estrutura do código, apresentação do trabalho, etc. 20%

Melhor compilador Bónus: 10%

Figura 6. Percentagem na nota final no trabalho de cada tarefa.

B.1 Gramática Inicial da Linguagem ualg

De seguida é apresentada a gramática inicial da linguagem (esta gramática foi escrita de forma a ser o mais intuitiva possível e o mais próximo possível da gramática que deverá ser especificada no JavaCC):

IDENTIFIER = [a-z][a-z0-9]*

LITERAL = [0-9]+

STRING = “\““ [a-zA-Z0-9”:”” “]+ “\““

// os operadores têm o mesmo significado e precedência do que na linguagem Java

RELA_OP = “>“ | “<“ | “==“ | “!=“ | “>=” | “<=”

OTHER_OP = “*“ | “/“ | “&“ | “|“ | “<<” | “>>” | “^”

ADD_SUB = “+“ | “-“

LPAR = “(“

RPAR = “)”

VIRG = “,”

PVIRG = “;”

LCHAVETA = “{“

RCHAVETA = “}“

ASSIGN = “=“

WHILE = “while”

IF = “if”

ELSE = “else”

RETURN = “return”

(8)

PRINT= ”print”

READ= ”read”

Start → IDENTIFIER LPAR [Varlist] RPAR LCHAVETA Stmtlst RETURN IDENTIFIER PVIRG RCHAVETA

Varlist → IDENTIFIER {VIRG IDENTIFIER}

Stmtlst → {Stmt}

Stmt → Expr1 | Expr3 | Expr4 | Print Expr1 → IDENTIFIER ASSIGN Rhs PVIRG Rhs → Term [(ADD_SUB | OTHER_OP) Term]

Term → IDENTIFIER | ([ADD_SUB] LITERAL) | READ Expr3 → WHILE Exprtest LCHAVETA Stmtsimple RCHAVETA Expr4 → IF Exprtest LCHAVETA Stmtsimple RCHAVETA

Expr4 → IF Exprtest LCHAVETA Stmtsimple RCHAVETA ELSE LCHAVETA Stmtsimple RCHAVETA

Print → PRINT LPAR STRING VIRG IDENTIFIER RPAR PVIRG

Exprtest → LPAR IDENTIFIER RELA_OP (IDENTIFIER | ([ADD_SUB] LITERAL)) RPAR Stmtsimple → {Expr1 | Expr4 | Expr3 | Print}

(9)

C. Algumas Dicas

Antes de começarem a especificar a gramática no JavaCC devem verificar se a gramática é não-ambígua e não tem recursividade à esquerda. No caso de não se verificar alguma destas propriedades, a gramática deve ser modificada e só depois é que deve ser especificada no JavaCC.

As linguagens ualg/ualg+ não devem diferenciar minúsculas de maiúsculas. Para isso devem atribuir o valor verdadeiro à opção IGNORE_CASE do JavaCC:

options {

IGNORE_CASE=true;

}

Lembrem-se que cada símbolo não-terminal da gramática pode ser um procedimento no ficheiro descritivo da gramática.

Durante a fase de validação do analisador gramatical podem utilizar uma makefile que execute o compilador com vários programas teste (programas em ualg/ualg+ que permitam verificar se determinadas construções da linguagem estão a ser aceites pelo analisador gramatical). Esta abordagem permite automatizar o teste da gramática e é por isso útil para testar o analisador sempre que forem feitas alterações na descrição JavaCC da gramática.

D. Documentação e Ferramentas de Suporte

Compilador e Interpretador:

1. JavaCC: Java Compiler Compiler™ (JavaCC) - The Java Parser Generator JavaCC: https://javacc.dev.java.net/

2. Oliver Enseling, “Build your own languages with JavaCC”, Copyright © 2003 JavaWorld.com, an IDG company, http://www.javaworld.com/javaworld/jw-12- 2000/jw-1229-cooltools_p.html

Compilador:

3. Spim: http://www.cs.wisc.edu/~larus/spim.html

4. Rever as primeiras 3 aulas teóricas (“Da linguagem alto-nível ao código assembly”).

Referências

Documentos relacionados

Local de realização da avaliação: Centro de Aperfeiçoamento dos Profissionais da Educação - EAPE , endereço : SGAS 907 - Brasília/DF. Estamos à disposição

(2014) através da World Values Survey. A preocupação com o meio ambiente, bem como a pouca importância dada ao “ter” são características dos que tendem a

Os candidatos reclassificados deverão cumprir os mesmos procedimentos estabelecidos nos subitens 5.1.1, 5.1.1.1, e 5.1.2 deste Edital, no período de 15 e 16 de junho de 2021,

Desta maneira, observando a figura 2A e 2C para os genótipos 6 e 8, nota-se que os valores de captura da energia luminosa (TRo/RC) são maiores que o de absorção (ABS/RC) e

Após a realização de todas as atividades teóricas e práticas de campo, pode-se concluir que não há grande erosão do conhecimento popular e tradicional de plantas medicinais, que

Se for bem sucedido você recupera pontos de vida iguais a quantidade de pontos neste poder (mais bônus se tiver).. Campo de Força : Faça um

Feitiço do Segredo: deposita um segredo numa pessoa de confiança, essa pessoa fica deposita um segredo numa pessoa de confiança, essa pessoa fica sendo o &#34;Fiel do sendo o

- Remover as pastilhas usadas e retornar todo o parafuso de regulagem em seguida montar uma pastilha nova do lado da roda, empurrando com a mão a pinça no sentido do cilindro de