implementac˘ao do tratamento de~...
Post on 13-Jul-2020
3 Views
Preview:
TRANSCRIPT
UNIVERSIDADE DO ESTADO DO AMAZONAS - UEA
ESCOLA SUPERIOR DE TECNOLOGIA
ENGENHARIA DE COMPUTACAO
LIDIA LIZZIANE SEREJO DE CARVALHO
IMPLEMENTACAO DO TRATAMENTO DE
VARIAVEIS E ERROS EM ERLANG NO
COMPILADOR JARAKI
Manaus
2012
LIDIA LIZZIANE SEREJO DE CARVALHO
IMPLEMENTACAO DO TRATAMENTO DE VARIAVEIS E ERROS EM
ERLANG NO COMPILADOR JARAKI
Trabalho de Conclusao de Curso apresentado
a banca avaliadora do Curso de Engenharia
de Computacao, da Escola Superior de
Tecnologia, da Universidade do Estado do
Amazonas, como pre-requisito para obtencao
do tıtulo de Engenheiro de Computacao.
Orientador: Prof. MSc. Jucimar Maia da Silva Junior
Manaus
2012
ii
Universidade do Estado do Amazonas - UEA
Escola Superior de Tecnologia - EST
Reitor:
Jose Aldemir de Oliveira
Vice-Reitor:
Marly Guimaraes Fernandes Costa
Diretor da Escola Superior de Tecnologia:
Mario Augusto Bessa de Figueiredo
Coordenador do Curso de Engenharia de Computacao:
Raimundo Correa de Oliveira
Coordenador da Disciplina Projeto Final:
Mario Augusto Bessa de Figueiredo
Banca Avaliadora composta por: Data da Defesa: 23/11/2012.
Prof. MSc. Jucimar Maia da Silva Junior (Orientador)
Prof. MSc. Raimundo Correa de Oliveira
Prof. MSc. Rodrigo Choji de Freitas
CIP - Catalogacao na Publicacao
C331i CARVALHO, Lıdia
Implementacao do Tratamento de Variaveis e Erros em Erlang no Compi-
lador Jaraki / Lıdia Carvalho; [orientado por] Prof. MSc. Jucimar Maia da
Silva Junior - Manaus: UEA, 2012.
61 p.: il.; 30cm
Inclui Bibliografia
Trabalho de Conclusao de Curso (Graduacao em Engenharia de Computa-
cao). Universidade do Estado do Amazonas, 2012.
CDU: 004.4’4
iii
LIDIA LIZZIANE SEREJO DE CARVALHO
IMPLEMENTACAO DO TRATAMENTO DE VARIAVEIS E ERROS EM
ERLANG NO COMPILADOR JARAKI
Trabalho de Conclusao de Curso apresentado
a banca avaliadora do Curso de Engenharia
de Computacao, da Escola Superior de
Tecnologia, da Universidade do Estado do
Amazonas, como pre-requisito para obtencao
do tıtulo de Engenheiro de Computacao.
Aprovado em: 23/11/2012BANCA EXAMINADORA
Prof. Jucimar Maia da Silva Junior, Mestre
UNIVERSIDADE DO ESTADO DO AMAZONAS
Prof. Raimundo Correa de Oliveira, Mestre
UNIVERSIDADE DO ESTADO DO AMAZONAS
Prof. Rodrigo Choji de Freitas, Mestre
UNIVERSIDADE DO ESTADO DO AMAZONAS
iv
Agradecimentos
A Deus pela vida e privilegio da graduacao
que me foi proporcionada. A minha famılia
por todo apoio e compreensao. Aos colegas e
amigos de jornada, professores e mestres, em
especial Professor Orientador Jucimar Junior
pelas correcoes, orientacoes e incentivo.
v
Resumo
Esse trabalho mostra a implementacao do modulo de manipulacao de variaveis e tipos
de dados e o tratamento de excecoes para o compilador Jaraki atraves do uso de dicionarios.
O Jaraki e um compilador que executa codigos-fonte da linguagem Java na maquina virtual
do Erlang.
Palavras Chave: Compiladores, Analisadores, Lexico, Sintatico, Semantico, Java, Er-
lang
vi
Abstract
This work presents the implementation of variable and data types handling module
and exceptions handling module for the Jaraki compiler through the use of dictionaries.
The Jaraki is a compiler that run source code of the Java language on the Erlang virtual
machine.
Key-words: Compilers, Analyzers, Lexical, Syntactic, Semantic, Java, Erlang
vii
Sumario
Lista de Tabelas x
Lista de Figuras xi
Lista de Codigos xii
1 Introducao 1
1.1 Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.1 Objetivos Especıficos . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 Trabalhos Relacionados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Justificativa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4 Metodologia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.5 Estrutura do Trabalho . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2 Referencial Teorico 5
2.1 Compiladores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2 Analise Lexica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3 Analise Sintatica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.4 Analise Semantica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.5 Tabela de Sımbolos e Manipulacao de Erros . . . . . . . . . . . . . . . . . 8
2.6 Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.6.1 Variaveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.7 Erlang . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.7.1 Caracterısticas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.7.2 Variaveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.7.3 Tipos de Dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.7.4 Operadores Aritmeticos . . . . . . . . . . . . . . . . . . . . . . . . 15
2.7.5 Atoms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
viii
2.8 Projeto Jaraki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3 Desenvolvimento 18
3.1 Analisadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.1.1 Leex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.1.2 Yecc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.2 Declaracao e Atribuicao de Variaveis . . . . . . . . . . . . . . . . . . . . . 19
3.2.1 Analise Lexica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.2.2 Analise Sintatica . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.2.3 Analise Semantica e Geracao de Codigo . . . . . . . . . . . . . . . . 24
3.3 Vetores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.3.1 Analise Lexica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.3.2 Analise Sintatica . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.3.3 Analise Semantica e Geracao de Codigo . . . . . . . . . . . . . . . . 32
3.4 Matrizes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.4.1 Analise Lexica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.4.2 Analise Sintatica . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.4.3 Analise Semantica e Geracao de Codigo . . . . . . . . . . . . . . . . 38
4 Testes 42
4.1 Processo de Compilacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
4.1.1 Arvore Sintatica do compilador Jaraki - JAST . . . . . . . . . . . . 43
4.1.2 Arvore Sintatica do Erlang - AST . . . . . . . . . . . . . . . . . . . 43
4.2 Teste 1 - Variaveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
4.3 Teste 2 - Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
4.4 Teste 3 - Char . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
4.5 Teste 4 - Vetores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.5.1 Bubblesort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.5.2 Quicksort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
4.6 Matrizes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
4.7 Erros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
4.8 Resumo do Tempo dos Testes . . . . . . . . . . . . . . . . . . . . . . . . . 55
5 Conclusoes 56
5.1 Trabalhos Futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Referencias Bibliograficas 58
ix
A Codigos de Testes 60
A.1 Estrutura dos Diretorios . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
x
Lista de Tabelas
2.1 Precedencia de Operadores Aritmeticos . . . . . . . . . . . . . . . . . . . . 11
2.2 Operadores Aritmeticos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.1 Bloco de Definicoes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.2 Sımbolos Terminais e Nao-Terminais . . . . . . . . . . . . . . . . . . . . . 24
3.3 Leex - Bloco de Definicoes do Vetor . . . . . . . . . . . . . . . . . . . . . . 30
4.1 Resumo dos tempos de testes . . . . . . . . . . . . . . . . . . . . . . . . . 55
xi
Lista de Figuras
2.1 Compilador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2 Fases de um Compilador . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3 Interacao do Analisador lexico e Sintatico . . . . . . . . . . . . . . . . . . . 7
2.4 Arvore Sintatica − id1 = id2 + id3 ∗ 60 . . . . . . . . . . . . . . . . . . . . 7
2.5 Compilador Jaraki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.1 Analisador Lexico Leex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.2 Dicionario de Processos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.3 Declaracao de Variaveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.4 Modulo ST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.5 Fluxograma - Insercao de Variaveis . . . . . . . . . . . . . . . . . . . . . . 27
3.6 Atribuicao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.7 Modulo Vector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.8 Declaracoes de Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.9 Array de Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.10 Modulo Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
3.11 Fluxo Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4.1 Tempo de Compilacao em Java - Calculo Media . . . . . . . . . . . . . . . 45
4.2 Tempo de Execucao em Java - Calculo Media . . . . . . . . . . . . . . . . 46
4.3 Tempo de Compilacao em Erlang - Calculo Media . . . . . . . . . . . . . . 46
4.4 Tempo de Execucao em Erlang - Calculo Media . . . . . . . . . . . . . . . 46
4.5 Tempo de Compilacao em Java - String . . . . . . . . . . . . . . . . . . . . 47
4.6 Tempo de Execucao em Java - String . . . . . . . . . . . . . . . . . . . . . 47
4.7 Tempo de Compilacao em Erlang - String . . . . . . . . . . . . . . . . . . 48
4.8 Tempo de Execucao em Erlang - String . . . . . . . . . . . . . . . . . . . . 48
4.9 Tempo de Compilacao em Java - Char . . . . . . . . . . . . . . . . . . . . 48
4.10 Tempo de Execucao em Java - Char . . . . . . . . . . . . . . . . . . . . . . 49
xii
4.11 Tempo de Compilacao em Erlang - Char . . . . . . . . . . . . . . . . . . . 49
4.12 Tempo de Execucao em Erlang - Char . . . . . . . . . . . . . . . . . . . . 49
4.13 Tempo de Compilacao e Execucao em Java - bubblesort . . . . . . . . . . . 50
4.14 Tempo de Compilacao em Erlang - bubblesort . . . . . . . . . . . . . . . . 51
4.15 Tempo de Execucao em Erlang - bubblesort . . . . . . . . . . . . . . . . . . 51
4.16 Tempo de Compilacao e Execucao em Java - quicksort . . . . . . . . . . . 51
4.17 Tempo de Compilacao em Erlang - quicksort . . . . . . . . . . . . . . . . . 52
4.18 Tempo de Execucao em Erlang - quicksort . . . . . . . . . . . . . . . . . . 52
4.19 Tempo de Compilacao Java - Matrizes . . . . . . . . . . . . . . . . . . . . 53
4.20 Tempo de Execucao em Java - Matrizes . . . . . . . . . . . . . . . . . . . . 53
4.21 Tempo de Compilacao em Erlang - Matrizes . . . . . . . . . . . . . . . . . 53
4.22 Tempo de Execucao em Erlang - Matrizes . . . . . . . . . . . . . . . . . . 54
4.23 Tempo de Compilacao Java - Erros . . . . . . . . . . . . . . . . . . . . . . 55
4.24 Tempo de Execucao em Java - Erros . . . . . . . . . . . . . . . . . . . . . 55
xiii
Lista de Codigos
2.6.1 Variaveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.6.2 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.6.3 Declaracao de Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.7.1 Erro de Atribuicao Unica . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.7.2 Atribuicao a uma nova variavel . . . . . . . . . . . . . . . . . . . . . . . . 14
2.7.3 Representacao de Caracteres . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.7.4 Representacao de Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.7.5 Atoms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.2.1 Codigo Java - Declaracao e Atribuicao de Variaveis . . . . . . . . . . . . . 20
3.2.2 EBNF - Declaracao de Variaveis e Atribuicao . . . . . . . . . . . . . . . . 20
3.2.3 Estrutura do arquivo jaraki lexer.xrl . . . . . . . . . . . . . . . . . . . . . . 22
3.2.4 Lista de Tokens Gerados pelo Leex . . . . . . . . . . . . . . . . . . . . . . 23
3.2.5 Estrutura do arquivo jaraki parser.yrl . . . . . . . . . . . . . . . . . . . . . 24
3.2.6 Arvore sintatica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.2.7 Codigo Erlang - Declaracao e Atribuicao de Variaveis . . . . . . . . . . . . 28
3.3.1 Codigo Java - Declaracao e Atribuicao de Variaveis envolvendo Vetores . . 29
3.3.2 EBNF - Vetores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.3.3 Modulo Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.3.4 Lista de Tokens Gerados pelo Leex . . . . . . . . . . . . . . . . . . . . . . 31
3.3.5 Estrutura do arquivo jaraki parser.yrl . . . . . . . . . . . . . . . . . . . . . 32
3.3.6 Arvore Sintatica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.3.7 Codigo Erlang - Vetor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.4.1 Codigo Java - Matriz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
xiv
3.4.2 EBNF - Matrizes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.4.3 Lista de Tokens Gerados pelo Leex . . . . . . . . . . . . . . . . . . . . . . 37
3.4.4 Estrutura do arquivo jaraki parser.yrl . . . . . . . . . . . . . . . . . . . . . 38
3.4.5 Arvore Sintatica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.4.6 Codigo Erlang - Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4.1.1 Codigo Java - Calculo Media . . . . . . . . . . . . . . . . . . . . . . . . . . 43
4.1.2 JAST - Calculo Media . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
4.1.3 AST do Erlang - Calculo Media . . . . . . . . . . . . . . . . . . . . . . . . 45
4.1.4 Codigo Erlang - Calculo Media . . . . . . . . . . . . . . . . . . . . . . . . 46
4.3.1 Codigo Java - String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
4.4.1 Codigo Java - Char . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
4.5.1 Codigo Java - Metodo de ordenacao bolha . . . . . . . . . . . . . . . . . . 50
4.5.2 Codigo Java - Algoritmo Quicksort . . . . . . . . . . . . . . . . . . . . . . 52
4.7.1 Codigo Java - Erro de Variaveis . . . . . . . . . . . . . . . . . . . . . . . . 54
Capıtulo 1
Introducao
Apesar de programadores vincularem variaveis a locais de memoria, existem muitos as-
pectos que permeiam esse conceito. Variaveis sao abstracoes para as celulas de memoria
da maquina em uma linguagem e pode ser caracterizada por 6 atributos (nome, endereco,
valor, tipo, tempo de vida e escopo) [Sebesta2011]. De acordo com Deitel, uma variavel
e uma posicao de memoria do computador onde um valor pode ser armazenado para uso
posterior em um programa [Deitel2010].
E crucial que uma linguagem suporte uma variedade de tipos de dados e estruturas.
Os tipos de dados de uma linguagem sao uma parte grande daquilo que determina o seu
estilo e seu uso. Juntamente com as estruturas de controle, formam o coracao de uma
linguagem [Sebesta2011].
A maioria das especificacoes das linguagens de programacao nao descreve como um
compilador deveria responder aos erros; tal tarefa e designada ao projetista do compilador.
Cada erro encontrado durante as fases de compilacao precisarao ser tratados de tal forma
que a compilacao possa continuar, permitindo que sejam detectados erros posteriores no
programa fonte [Aho2007].
Java e uma linguagem que foi anunciada em 1995 pela Sun atualmente utilizada para
desenvolver aplicativos de grande porte, aprimorar a funcionalidade de servidores da web,
fornecer aplicativos para dispositivos voltados para o consumo popular e para muitos outros
propositos. Sua programacao e orientada a objetos, permitindo implementar um design
orientado a objetos como um sistema funcional no mundo e disponibiliza concorrencia por
Objetivos 2
meio da linguagem e das APIs [Deitel2010].
Erlang e uma linguagem de programacao funcional projetada para sistemas complexos
tolerantes a falhas, desenvolvido originalmente no Laboratorio de Ciencia da computacao
da empresa sueca Ericsson Telecom. Por meio de um conjunto de processos paralelos que
podem interagir apenas por troca de mensagens, modela facilmente a programacao paralela.
Diferente de muitas linguagens, no Erlang, ha processos paralelos, mas sem bloqueios,
metodos sincronizados e memoria compartilhada. Fornece solucoes para problemas que
sao comumente encontrados em grandes sistemas durante a programacao simultanea de
tempo real [Armstrong2007].
O compilador Jaraki tem como principal objetivo compilar arquivos em Java na maquina
virtual do Erlang implementando partes inerentes a linguagem Java em Erlang.
1.1 Objetivos
Implementar o modulo de manipulacao de variaveis e o tratamento de excecoes para o
compilador Jaraki.
1.1.1 Objetivos Especıficos
Os objetivos especıficos sao:
• Manipular nomes, vinculacoes e escopos;
• Implementar tipos de dados;
• Implementar expressoes e sentencas de atribuicao;
• Implementar tratamento de excecoes e tratamento de eventos.
1.2 Trabalhos Relacionados
Outros trabalhos tambem implementam compiladores, como por exemplo uma simples
calculadora [Upadhyaya2011], que utiliza as ferramentas LEX e YACC para as analises
Justificativa 3
lexica e sintatica em linguagem C e tambem grandes projetos como Reia e Jython. A
linguagem Jython [Jython2012] e uma implementacao Java de Python que permite escrever
codigos em Python e rodar dentro da JVM (Java Virtual Machine), enquanto que Reia
[Reia2012] e uma linguagem de script como o Ruby para a maquina virtual do Erlang.
1.3 Justificativa
Diferente da linguagem Java, em Erlang nao existem variaveis globais e a atribuicao
a uma variavel e unica (single assignment), ou seja, uma vez que se atribui um valor a
mesma, este valor nao pode ser alterado. Verifica-se entao que matrizes, vetores e algu-
mas atribuicoes em Java, por exemplo, tornam-se um desafio quando vinculadas a uma
linguagem funcional.
Apesar de a maioria dos sistemas de computadores serem capazes de detectar certas
condicoes de erros [Sebesta2011], cada fase de compilacao pode apresentar erros especıficos
que devem ser retornados e tratados buscando a nao interrupcao da compilacao.
1.4 Metodologia
Para o desenvolvimento deste trabalho foram utilizados arquivos de testes envolvendo
cada etapa necessaria para a implementacao. Cada teste foi construıdo de forma incre-
mental, abrangendo todas as etapas de compilacao: analise lexica, sintatica, semantica e
geracao de codigo em Erlang.
1.5 Estrutura do Trabalho
Alem do capıtulo atual, este trabalho esta dividido em mais 4 capıtulos. O Capıtulo
2, referencial teorico, aborda os assuntos inerentes a estrutura de um compilador (analise
lexica, sintatica, semantica e geracao de codigo) e as linguagens envolvidas: Java e Erlang.
O Capıtulo 3, Desenvolvimento, descreve todas as etapas de implementacao do compilador
Jaraki dentro do escopo definido, expondo estruturas desenvolvidas e abordagens utiliza-
Estrutura do Trabalho 4
das para o mesmo. O objetivo do Capıtulo 4, Testes, e exemplificar, por meio de testes
realizados, a estrutura de codigo gerado em Erlang a partir de codigos fontes Java. Por
fim, o ultimo capıtulo refere-se a conclusao e trabalho futuros.
Capıtulo 2
Referencial Teorico
2.1 Compiladores
Um compilador e um programa que mapeia um programa escrito em uma determinada
linguagem e o traduz em um programa equivalente em outra linguagem, tendo como etapa
importante relatar erros ao usuario, como representado na Figura 2.1. Esse processo de
compilacao e dividido em duas partes: analise e sıntese [Aho2007].
Figura 2.1: Compilador
Na analise, o programa fonte e dividido em partes constituintes instituindo uma es-
trutura gramatical. O compilador utiliza essa estrutura para criar uma representacao
intermediaria do mesmo. E nessa fase que o compilador detecta se o programa fonte e sin-
taticamente formado ou semanticamente correto, devendo emitir mensagens informativas
ao usuario. A fase de analise tambem coleta informacoes sobre o programa fonte e as arma-
zena em uma estrutura de dados chamada tabela de sımbolos, que e passado juntamente
Análise Léxica 6
com a representacao intermediaria a etapa de sıntese [Aho2007].
A sıntese constroi partes do programa alvo a partir da representacao intermediaria e as
informacoes contidas na tabela de sımbolos [Aho2007].
Segundo Aho, conceitualmente, um compilador opera em fases e, na pratica, algumas
podem ser agrupadas e a representacao intermediaria entre elas nao precisa ser explicita-
mente construıda. Uma tıpica decomposicao de um compilador e mostrada na Figura 2.2.
A tabela de sımbolos, que armazena informacoes sobre o programa fonte (identificadores e
atributos), e usada em todas as fases de compilacao.
Figura 2.2: Fases de um Compilador
2.2 Analise Lexica
Um analisador lexico e essencialmente um “casamenteiro” de padroes. Ele busca uma
subcadeia de uma dada cadeia de caracteres que casa com um padrao dado, coleta carac-
teres em agrupamentos logicos e atribui codigos internos aos agrupamentos de acordo com
sua estrutura. Os agrupamentos de caracteres sao chamados lexemas e os codigos internos
de sımbolos (tokens). Os analisadores lexicos extraem lexemas de uma dada cadeia de
entrada e produzem os respectivos sımbolos [Sebesta2011].
Nessa fase, o programa fonte e mapeado e os caracteres lidos sao agrupados num fluxo
de tokens, no qual cada token representa uma sequencia de caracteres logicamente coesiva,
Análise Sintática 7
como, por exemplo, um identificador e palavra-chave. Cada token e passado para o parser
(analisador sintatico) a medida que o mesmo envia um comando “obter o proximo token”,
essa relacao pode ser observada na Figura 2.3 [Aho2007].
Figura 2.3: Interacao do Analisador lexico e Sintatico
2.3 Analise Sintatica
A analise hierarquica e chamada de analise gramatical ou analise sintatica. Envolve
o agrupamento dos tokens do programa fonte em frases gramaticais, que sao usadas pelo
compilador, a fim de sintetizar a saıda. Essas frases gramaticais do programa fonte sao
geralmente representadas por uma arvore gramatical como mostra a Figura 2.4 [Aho2007].
Figura 2.4: Arvore Sintatica − id1 = id2 + id3 ∗ 60
Os analisadores das linguagens de programacao constroem arvores de analise para os
programas de dados. A informacao necessaria para construir a arvore e criada durante
o processo de analise. As arvores de analise e as derivacoes incluem toda a informacao
sintatica necessaria para um processador da linguagem. Observa-se duas metas nessa fase:
Análise Semântica 8
verificar o programa de entrada para determinar se ele esta sintaticamente correto e pro-
duzir uma arvore de analise completa ou pelo menos esborcar sua estrutura [Sebesta2011].
2.4 Analise Semantica
A semantica de um programa e o seu “significado”, contrastando com sua sintaxe ou
estrutura. E ela que determina o seu comportamento durante a execucao [Louden2004].
A analise semantica pode ser dividida em duas categorias. A primeira e a analise de um
programa requerida pelas regras de linguagem de programacao, para verificar sua correcao
e garantir sua execucao. A segunda categoria e aquela efetuada por um compilador para
melhorar a eficiencia de execucao do programa traduzido. Esse tipo de analise e, em geral,
incluıdo nas discussoes sobre“otimizacao”, ou tecnicas de melhoria de codigo [Louden2004].
E nessa fase tambem que sao verificados erros semanticos no programa fonte e cap-
turados informacoes de tipo para a fase de geracao de codigo. Na verificacao de tipos, o
compilador checa se cada operador recebe os operandos que sao permitidos pela especifi-
cacao da linguagem fonte. Por exemplo, muitas definicoes nas linguagens de programacao
requerem que o compilador relate um erro a cada vez que um numero real seja usado como
ındice de um array [Aho2007].
2.5 Tabela de Sımbolos e Manipulacao de Erros
Uma tabela de sımbolos e uma estrutura de dados contendo um registro para cada
identificador (funcoes, variaveis, constantes e tipos de dados). Ela interage com quase todas
as fases de compilacao (analise lexica, sintatica e semantica), onde os mesmos fornecem
identificadores a tabela. As fases de otimizacao e geracao de codigo utilizam a informacao
da tabela para efetuar escolhas apropriadas para o codigo objeto.
Uma das funcoes mais importantes de um compilador e sua resposta a erros. Os erros
estaticos (ou em tempo de compilacao) devem ser detectados e reportados durante quase
todas as fases de compilacao. E importante que o compilador possa gerar mensagens de
erros inteligıveis e concluir a compilacao apos cada erro [Louden2004].
Java 9
As fases de analise sintatica e semantica tratam usualmente de uma ampla fatia dos erros
detectaveis pelo compilador. Erros de sintaxe ocorrem quando caracteres remanescentes
na entrada nao formam qualquer token da linguagem. Os erros, onde o fluxo de tokens
viole as regras estruturais (sintaxe) da linguagem, sao determinados pela fase de analise
sintatica.
2.6 Java
A linguagem Java evoluiu a partir das linguagens C e C++ e foi desenvolvida por
James Gosling. E uma linguagem de programacao orientada a objetos mais amplamente
utilizada do mundo. Uma das razoes para a sua popularidade e a sua independencia de
plataforma, tornando-a diferente da maioria das outras linguagens de programacao, que
exigem diferentes compiladores para diferentes sistemas operacionais [Hubbard2004].
A linguagem Java compila seu codigo-fonte para uma linguagem generica bytecode, que
e executada pela maquina cliente usando um programa chamado de Java Virtual Machine
(JVM). O sistema JVM e um interpretador, ou seja, traduz e executa cada instrucao em
bytecode separadamente, sempre que ela e necessaria [Hubbard2004].
Java tem um conjunto de classes predefinidas reutilizaveis. Essas classes sao agru-
padas em pacotes e, coletivamente, sao chamados de bibliotecas de classes Java ou Java
Application Programming Interface (Java API) [Java2012].
2.6.1 Variaveis
Pode ser caracterizada por um conjunto de propriedades, ou atributos. Uma variavel
e uma posicao de memoria onde seu valor pode ser armazenado para uso posterior do
programa. Variaveis em Java devem ser declaradas especificando um nome e um tipo de
dados antes de serem usadas. Sentencas de atribuicao tem como objetivo modificar o valor
de uma variavel, seu valor pode mudar durante a execucao de um programa [Deitel2010].
Os nomes de variavel number1 e number2 (Codigo 2.6.1) correspondem as posicoes de
memoria do computador. Cada variavel tem um nome, tipo, tamanho (em Bytes), valor,
escopo e tempo de vida. O nome e uma cadeia de caracteres que identifica um entidade
Java 10
1 // Declarac~ao2 int number1;3 float number2;4
5 // Atribuic~ao6 number1 = 1;7 number1 = 1 * 60 + 2;
Codigo 2.6.1: Variaveis
do programa. Linguagens como C, C++ e Java fazem distincao entre nomes em fontes
maiusculas e minusculas. Algumas palavras nao podem ser usadas como nomes. Essas,
chamadas de palavras reservadas, tem significado predefinidos como, por exemplo, os tipos
int e float [Sebesta2011].
Uma variavel pode ser definida tambem como local ou global, dependendo do seu escopo.
Se o escopo de uma variavel esta relacionado a um metodo, seu tempo de vida estara
limitado desde o ınicio da chamada ate o fim da execucao deste metodo. Dado uma
declaracao de variavel dentro do corpo de uma classe, seu tempo de vida estara relacionado
em toda execucao do programa.
O maioria dos programas realiza calculos aritmeticos e a linguagem Java aplica os
operadores aritmeticos em expressoes aritmeticas em uma sequencia precisa determinada
pelas seguintes regras de precedencia de operadores, que sao geralmente as mesmas seguidas
em algebra como mostra a Tabela 2.1 [Deitel2010]:
1. Operacoes de multiplicacao, divisao e modulos sao aplicadas primeiro. Se uma ex-
pressao contiver varias dessas operacoes, elas serao aplicadas da esquerda para a
direita. Os operadores de multiplicacao, divisao e modulo tem o mesmo nıvel de
precedencia.
2. As operacoes de adicao e subtracao sao aplicadas em seguida. Se uma expressao
contiver varias dessas operacoes, os operadores serao aplicados da esquerda para a
direita. Os operadores de adicao e subtracao tem o mesmo nıvel de precedencia.
Em Java, strings (sequencia de caracteres tratadas como uma unica unidade) sao re-
presentadas por meio da utilizacao da classe String, ou seja, uma string e um objeto
da classe String (Codigo 2.6.2). Os grupos de variaveis que contem valores do mesmo
tipo sao chamados de array. Eles tambem sao objetos, portanto, considerados tipos por
Erlang 11
Operadores AritmeticosOperador Operacao Ordem de Avaliacao(precedencia)
∗ Multiplicacao Avaliado primeiro. Se houver varios operadores desse tipo,/ Divisao eles sao avaliados da esquerda para a direita.% Resto+ Adicao Avaliado em seguida. Se houver varios operadores desse tipo,− Subtracao eles sao avaliados da esquerda para a direita.= Atribuicao Avaliado por ultimo.
Tabela 2.1: Precedencia de Operadores Aritmeticos
1 public class ExemploString {2
3 public static void main(String[] args) {4
5 String s = new String();6
7 s = "UEA";8
9 System.out.println(s);10
11 }12 }
Codigo 2.6.2: Strings
referencia [Deitel2010]. O numero de posicao de um array e chamado de ındice. Como
os outros objetos, os arrays sao criados com a palavra-chave new. Possui duas formas de
declaracao:
1 int[] c = new int[12];2
3 int[] n = {10, 20, 30, 40, 50};
Codigo 2.6.3: Declaracao de Array
A primeira declaracao cria um objeto array que contem 12 elementos int e armazena
a referencia do array na variavel c. Na segunda, o array e inicializado com 5 elementos
separados por vırgula com valores de ındice de 0− 4.
2.7 Erlang
Em meados da decada de 1980, o laboratorio de ciencia da computacao da Ericsson
teve a tarefa de investigar as linguagens de programacao adequadas para programar a
Erlang 12
proxima geracao de produtos de telecomunicacoes. Eles concluıram que ainda faltavam
caracterısticas necessarias para sistemas tao complexos e por isso criaram sua propria
linguagem, o Erlang [Cesarini2009].
2.7.1 Caracterısticas
Erlang possui as seguintes caracterısticas [Cesarini2009]:
• Linguagem Declarativa
Erlang e uma linguagem declarativa. Linguagens declarativas trabalham com o prin-
cipio de tentar descrever o que deve ser calculado, em vez de dizer como um valor
e calculado. Descrevem em alto nıvel uma aplicacao onde os programadores nao
especificam sequencias de operacoes como em uma linguagem imperativa.
• Concorrencia
Erlang tem um modelo de concorrencia baseado em processos com passagem de men-
sagem assıncrona. Cada processo em Erlang e executado em seu proprio espaco de
memoria, comunicando-se atraves de mensagens. Os mecanismos de concorrencia sao
leves (lightweight), ou seja, requerem pouca memoria, e demandam um esforco menor
para criar, destruir processos e passar mensagens entre eles.
• Propriedades de tempo Real
Erlang e destinada para programacao de sistemas de tempo real, onde sao obrigatorios
tempos de resposta em milissegundos. O gerenciamento de memoria em Erlang e
automatizado, com garbage collection implementado na base de cada processo. A
memoria e alocada automaticamente e desalocada quando nao usada. Portanto,
tıpicos erros de programacao relacionados ao gerenciamento de memoria nao podem
ocorrer.
• Robustez
Tem um conjunto simples, mas poderoso, de mecanismos para tratamentos de erros,
monitoramento de excecoes e bibliotecas construıdas para esse proposito, deixando
os programas com codigos mais curtos e faceis de entender.
Erlang 13
• Sistema Distribuıdo
Erlang tem suporte a programacao de sistemas distribuıdos incorporada na sintaxe
e semantica da linguagem e, como nao compartilha memoria, sistemas distribuıdos
podem facilmente ser construıdos. Aplicacoes que utilizam um unico processador
podem, sem dificuldade, serem portadas para rodar em uma rede de computadores.
• Integracao
Erlang pode facilmente fazer uso de programas escritos em outras linguagens de
programacao e podem ser interligados ao sistema de uma maneira tal que pareca ao
programador ter sido escrito em Erlang.
2.7.2 Variaveis
Variaveis sao usadas para armazenar valores de simples ou compostos tipos de dados.
Em Erlang, elas sempre iniciam com letra maiuscula, seguidas por letras maiusculas e
minusculas, inteiros e underscores. Nao devem conter outros tipos de caractere especial.
Variaveis em Erlang diferem da maioria das variaveis de linguagens convencionais de
programacao. A principal diferenca e que uma vez atribuıdo determinado valor a
uma variavel, ele nao podera ser alterado. Isso e chamado de atribuicao unica (single
assignment) [Cesarini2009]. Um erro de atribuicao unica ocorre quando uma variavel Var
recebe mais de uma vez determinado valor, como observado no Codigo 2.7.1.
1 %erl2
3 1>Var = 2.4
5 26
7 2>Var = Var * Var.8
9 **exception erro: no match of right hand side value 4
Codigo 2.7.1: Erro de Atribuicao Unica
Se for preciso computar ou manipular o valor de uma variavel, e necessario armazenar
os resultados em uma nova variavel (Codigo 2.7.2):
Outra caracterıstica das variaveis e que nao e necessario declara-las. A razao para que
isso ocorra e que Erlang tem um sistema de tipos dinamico. Os tipos e a viabilidade da
Erlang 14
1 %erl2
3 1>Var = 2.4
5 26
7 2>NovaVar = Var * Var.8
9 4
Codigo 2.7.2: Atribuicao a uma nova variavel
operacao sao determinados em tempo de execucao.
2.7.3 Tipos de Dados
Caracterısticas de alguns tipos de dados em Erlang:
Integer
Integers em Erlang sao usados para representar numeros inteiros. Eles podem ser
positivos ou negativos e serem expressos em outra base diferente de 10. A nocao de tamanho
maximo de inteiros em Erlang nao existe, ou seja, numeros arbitrariamente longos tambem
podem ser representados.
Float e Boolean
Floats em Erlang sao usados para representar numeros reais com ponto flutuante.
Nao existem tipos distintos de valores booleanos ou caracteres em Erlang. Em vez de
um tipo booleano, os atoms true e false sao usados em conjunto com operadores booleanos.
Caracteres e Strings
Caracteres sao representados por inteiros, e strings sao representados por lista de in-
teiros. A representacao de um caractere e dado precedido pelo sımbolo $, como mostrado
no Codigo 2.7.3.
Nao existe o tipo de dados string em Erlang. Strings sao indicadas por lista de valores
ASCII e representadas com o uso da notacao de aspas duplas (“ ”). Entao , a string
“Hello World” e na verdade a lista [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]. Uma
string vazia (“ ”) e equivalente a uma lista vazia [ ]. O Codigo 2.7.4 mostra o uso dessa
representacao.
Erlang 15
1 %erl2
3 1>$A.4
5 656
7 2>$A + 32.8
9 9710
11 3>$a.12
13 97
Codigo 2.7.3: Representacao de Caracteres
1 %erl2
3 1>[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100].4
5 "Hello World"6
7 2>[85, 69, 65].8
9 "UEA"10
11 3>[$H, $e, $l, $l, $o, $ , $W, $o, $r, $l, $d].12
13 "Hello World"
Codigo 2.7.4: Representacao de Strings
2.7.4 Operadores Aritmeticos
Operacoes com inteiros e floats em Erlang incluem adicao, subtracao, multiplicacao e
divisao. Operacoes envolvendo inteiros resultam somente em inteiros, exceto em casos de
divisao de ponto flutuante, onde o resultado e um float. Usando o operador div, o resultado
e um inteiro sem o resto da divisao. Os operadores podem ser observados na Tabela 2.2.
Operadores Aritmeticos
Tipo Descricao Tipo de Dados
+ Adicao Integer|Float− Subtracao Integer|Float∗ Multiplicacao Integer|Float/ Divisao por Ponto Flutuante Integer|Float
div Divisao por inteiro Integerrem Resto Integer
Tabela 2.2: Operadores Aritmeticos
Projeto Jaraki 16
2.7.5 Atoms
Em Erlang, atoms sao usados para representar diferentes valores de constantes nao
numericas. Atoms iniciam com letras minusculas ou sao delimitados por aspas simples.
Seu valor e o nome que lhe foi atribuıdo, como observado no Codigo 2.7.5.
1 %erl2
3 1>abc.4
5 abc6
7 2>‘usando espacos’.8
9 ‘usando espacos’10
11 3>‘Uea’.12
13 ‘Uea’14
15 4>‘1+2+3’.16
17 ‘1+2+3’
Codigo 2.7.5: Atoms
2.8 Projeto Jaraki
O projeto consiste no desenvolvimento de um compilador cujo fluxo de entrada sao
codigos-fontes em Java que passam por todos os processos de compilacao (analise lexica,
sintatica, semantica, tratamento de erros), gerando codigos na linguagem funcional Erlang
(Figura 2.5).
Figura 2.5: Compilador Jaraki
O projeto abrange o suporte as seguintes implementacoes:
• Tratamento de variaveis e erros;
Projeto Jaraki 17
• Estruturas de controle;
• Subprogramas, modulos e pacotes;
• Orientacao a objetos.
Dentro do escopo deste trabalho, o projeto Jaraki abrange o suporte a variaveis (di-
cionario, atribuicao, controle de escopo, vetores e matrizes) e o tratamento de erros de
compilacao e verificacoes de tipos de dados.
Capıtulo 3
Desenvolvimento
Este capıtulo apresenta as etapas de desenvolvimento do compilador chamado Jaraki, fer-
ramentas utilizadas nas analises, codigos-fontes, decisoes de projetos e outras estruturas de
implementacao.
3.1 Analisadores
Primeiramente, para o desenvolvimento tomou-se como base na geracao da analise lexica
e sintatica, respectivamente, as ferramentas Leex e Yecc, inerentes a linguagem Erlang, que
auxiliam nessas fases de construcao da arvore sintatica.
Leex e Yecc sao implementacoes da linguagem Erlang do Lex (gerador de analise lexica
ou tokenizer) e Yacc (Yet Another Compiler Compiler), respectivamente.
3.1.1 Leex
O gerador de analise lexica Leex, semelhante a Lex ou Flex, le e converte uma entrada
para um fluxo de tokens a ser analisado pelo parser. E um arquivo de extensao .xrl,
constituıdo em tres partes:
• Definitions: definicao de tokens da linguagem;
• Rules: extrai o token e a linha que o corresponde para ser utilizado posteriormente
na analise sintatica e semantica;
• Erlang Code: bloco que realiza verificacoes referentes a linguagem Erlang, por exem-
plo o unescape, que tem como funcao transformar os caracteres especiais que foram
“escapados” nos caracteres que eles de fato representam.
Declaração e Atribuição de Variáveis 19
A Figura 3.1 ilustra o processo da analise do fluxo de entrada ate a geracao de tokens
da linguagem. Primeiramente e necessario mapear as especificacoes de todos os padroes
da linguagem (leex.xrl) e, por meio do arquivo gerado em Erlang, obter a sequencia de
tokens.
Figura 3.1: Analisador Lexico Leex
3.1.2 Yecc
A arvore sintatica e gerada atraves do Yecc e dos tokens obtidos na analise lexica.
E um gerador de parser LALR-1 (lookahead LR) para o Erlang, similar ao Yacc. Assume
uma definicao de gramatica BNF como entrada, e produz um codigo Erlang para o parser
[Erlang2012b].
O arquivo Yecc de extensao .yrl, assim como o Leex, e dividido em blocos:
• Nonterminals: Identifica os sımbolos que derivam outras sentencas;
• Terminals : Identifica os sımbolos terminais;
• Rootsymbol : Indica o inıcio da primeira sentenca a ser analisada;
• Erlang Code: Mesma funcao que e apresentada no analisador lexico.
3.2 Declaracao e Atribuicao de Variaveis
Para a fase inicial de implementacao, no escopo de declaracao e atribuicao de variaveis,
definiu-se alguns codigos-fonte na linguagem Java.
Declaração e Atribuição de Variáveis 20
1 public class JarakiVar2 {3 public static void main(String [] Args)4 {5 int a, b = 4;6 int c;7 float d;8 c = 2;9 c = a / b * a + b;
10 }11 }
Codigo 3.2.1: Codigo Java - Declaracao e Atribuicao de Variaveis
O Codigo 3.2.1 contem declaracoes e atribuicoes simples de variaveis. Este codigo
servira como base nessa secao para exemplificar todo o processo do compilador Jaraki ate
a geracao de codigo.
E necessario observar que, para geracao de codigo em Erlang, esses tipos de declaracoes
e atribuicoes se tornam um desafio, visto que as variaveis iniciam com letras minusculas
e a atribuicao nao e unica. Essas e outros tipos de verificacoes tambem tiveram que ser
analisadas para a correta construcao do compilador.
A gramatica envolvendo a declaracao e atribuicao pode ser descrita em notacao EBNF
como observado no Codigo 3.2.2. A linha 1 define uma regra com declaracao de uma ou
mais variaveis, podendo ter ou nao atribuicao. A atribuicao tem um conjunto de regras
que definem a estrutura de uma atribuicao simples ou mesmo de expressoes aritmeticas
sendo que determinadas regras tratam da precedencia de operadores (linha 7 a 14).
1 <local_variable_declaration_statement> ::= (<type> | "identifier")2 <variable_list> {"," <variable_list>} ";"3
4 <variable_list> ::= "identifier" ["=" <element_value> ]5
6 <element_value_pair> ::= "identifier" "=" <element_value> ";"7
8 <element_value> ::= <bool_expr>9 <bool_expr> ::= <comparation_expr> | <comparation_expr> <bool_op> <bool_expr>
10 <comparation_expr> ::= <add_expr> | <add_expr> <comparation_op> <comparation_expr>11 <add_expr> ::= <mult_expr> | <mult_expr> <add_op> <add_expr>12 <mult_expr> ::= <modulus_expr> | <modulus_expr> <mult_op> <mult_expr>13 <modulus_expr> ::= <unary_expr> | <unary_expr> <modulus_op> <modulus_expr>14 <unary_expr> ::= <add_op> <literal> | <literal> | <bool_op> <literal>15 <literal> ::= "integer" | "float" | "identifier"16
17 <type> ::= "int_t" | "long_t" | "float_t" | "double_t" | "char_t" |18 "boolean_t" | "string_t"
Codigo 3.2.2: EBNF - Declaracao de Variaveis e Atribuicao
Declaração e Atribuição de Variáveis 21
Dicionario de Processos
Essa implementacao so foi possıvel por meio da criacao de um dicionario. Dicionarios
representam uma colecao de elementos onde cada elemento possui uma chave e um valor,
seu valor pode ser acessado atraves de uma chave unica. Essa necessidade surgiu para ar-
mazenamento do tipo, nome, escopo e valor das variaveis, visto que, durante a compilacao,
devem ser analisados alguns aspectos, dado as limitacoes da linguagem Erlang dentro desse
contexto, dentre eles:
• Uma nova chave no dicionario, para a variavel, deve ser criada apos cada leitura de
declaracao;
• O tipo se torna parte essencial da verificacao de erros;
• Tratar a variavel caso ela seja local ou global;
• Manipular variavel ao receber mais de uma atribuicao.
Dentre algumas abordagens pesquisadas para a implementacao do dicionario, utilizou-
se o dicionario de processos da linguagem Erlang. Ele mantem os dados durante toda a
execucao do programa. Esse dicionario e uma tabela hash, ou seja, nao e preciso varrer
todo a lista de chaves para encontrarmos um valor. O esquema da Figura 3.2 mostra que a
chave e o valor de cada elemento sao armazenados como tuplas. Essa abordagem e utilizada
tanto na analise semantica quanto no codigo gerado.
Figura 3.2: Dicionario de Processos
Os comandos basicos de manipulacao do dicionario de processos, respectivamente de
insercao, captura e eliminacao dos dados de uma chave sao:
• put(Chave, Valor);
• get(Chave);
• erase(Chave).
Declaração e Atribuição de Variáveis 22
3.2.1 Analise Lexica
A implementacao da analise lexica foi desenvolvida com a utilizacao da ferramenta
Leex e como ja mencionado, os tokens sao construıdos no bloco de definicoes. A Tabela 3.1
ilustra os tokens criados na declaracao e atribuicao de variaveis do Codigo 3.2.1.
Definicao LexemaInteger intFloat floatDigit [0− 9]Identifier [a− zA− Z][a− zA− Z0− 9]∗AttributionOp =AddOp ( \+ | -)MultOp ( \* | /)Comma ,Semicolon ;
Tabela 3.1: Bloco de Definicoes
As regras referentes a essas atribuicoes (Codigo 3.2.3) retornam tuplas para
a analise sintatica. Basicamente, a estrutura {token, {int_t, TokenLine,
list_to_atom(TokenChars)}} indica o nome, a linha e o atom correspondente a esse token
que a analise sintatica recebera como entrada.
A funcao list_to_atom(), propria do Erlang, converte cadeias de caracteres em atoms.
1 Definitions.2 ...3
4 Rules.5
6 {Integer} : {token, {int_t, TokenLine, list_to_atom(TokenChars)}}.7 {Float} : {token, {float_t, TokenLine, list_to_atom(TokenChars)}}.8
9 {Digit}+ : {token, {integer, TokenLine, list_to_integer(TokenChars)}}.10 {Identifier} : {token, {identifier, TokenLine, list_to_atom(TokenChars)}}.11
12 {AttributionOp} : {token, {list_to_atom(TokenChars), TokenLine}}.13 {AddOp} : {token, {add_op, TokenLine, list_to_atom(TokenChars)}}.14 {MultOp} : {token, {mult_op, TokenLine, list_to_atom(TokenChars)}}.15
16 {Comma} : {token, {list_to_atom(TokenChars), TokenLine}}.17 {Semicolon} : {token, {list_to_atom(TokenChars), TokenLine}}.18
19 Erlang Code.20 ...
Codigo 3.2.3: Estrutura do arquivo jaraki lexer.xrl
Declaração e Atribuição de Variáveis 23
Apos a definicao de todos os blocos da analise lexica (Definicoes, Regras e Codigo
Erlang), abrangendo todos os lexemas da linguagem Java, podem ser obtidos a lista de
tokens geradas pela ferramenta Leex, como mostra o esquema do Codigo 3.2.4.
1 [{public,1,public}, {class,1,class}, {identifier,1,’Hello’},2 {’{’,2}, ... , {’{’,4},3
4 {int_t,5,int},5 {identifier,5,a},6 {’,’,5},7 {identifier,5,b},8 {’=’,5},9 {integer,5,4},
10 {’;’,5},11 {int_t,6,int},12 {identifier,6,c},13 {’;’,6},14 {float_t,7,float},15 {identifier,7,d},16 {’;’,7},17 {identifier,8,c},18 {’=’,8},19 {integer,8,2},20 {’;’,8},21 {identifier,9,c},22 {’=’,9},23 {identifier,9,a},24 {mult_op,9,’/’},25 {identifier,9,b},26 {mult_op,9,’*’},27 {identifier,9,a},28 {add_op,9,’+’},29 {identifier,9,b},30 {’;’,9},31
32 {’}’,10},{’}’,11}]
Codigo 3.2.4: Lista de Tokens Gerados pelo Leex
3.2.2 Analise Sintatica
Com a lista de tokens apresentada no Codigo 3.2.4, sao reconhecidos os sımbolos ter-
minais e os que definem novas regras sao constituıdos sımbolos nao-terminais como estru-
turado na Tabela 3.2.
As regras (Codigo 3.2.5), assim como na analise lexica, tambem definem tuplas ou listas
de tuplas que caracterizam a arvore sintatica (obtida pelo Yecc). Um nao-terminal, como
exemplo a variable_list, pode gerar mais de uma regra.
A funcao unwrap() captura o terceiro elemento de uma tupla, por exemplo, na linha
5 a funcao recebe como parametro o token do primeiro elemento (identifier). No caso de
uma declaracao com atribuicao, a tupla {identifier, Linha ,b} sera contruıda como
Declaração e Atribuição de Variáveis 24
Terminals NonTerminalsint t local variable declaration statementfloat t element valueadd op typemult op variable listinteger element value pairidentifier add expr mult expr’,’ ’;’ ’=’ literal
Tabela 3.2: Sımbolos Terminais e Nao-Terminais
retorno da analise lexica. Entao, essa funcao retornara o identificador b. Essas e outras
implementacoes sao desenvolvidas no bloco do Erlang Code, na criacao de uma estrutura
mais simplificada e objetiva da arvore que sera lida na analise semantica.
1 local_variable_declaration_statement -> type variable_list ’;’ :2 {var_declaration, {var_type, ’$1’}, {var_list, ’$2’}}.3
4 variable_list -> identifier ’=’ element_value :5 [{{var, unwrap(’$1’)}, {var_value, ’$3’}}].6 variable_list -> identifier ’=’ element_value ’,’ variable_list :7 [{{var, unwrap(’$1’)}, {var_value, ’$3’}} | ’$5’].8 variable_list -> identifier :9 [{{var, unwrap(’$1’)},{var_value, undefined}}].
10 variable_list -> identifier ’,’ variable_list :11 [{{var, unwrap(’$1’)}, {var_value, undefined}} | ’$3’].12 ...13 literal -> integer : ’$1’.14 literal -> identifier : {var, line(’$1’), unwrap(’$1’)}.15
16 Erlang Code.17
18 unwrap({_, _, Value}) -> Value.
Codigo 3.2.5: Estrutura do arquivo jaraki parser.yrl
A arvore sintatica gerada a partir da linguagem Java (Codigo 3.2.1) e a saıda do Yecc e
sua estrutura e construıda no bloco de regras. Essas regras precisam ser bem definidas, por
isso as tuplas tiveram grande utilidade especificando cada bloco da estrutura da linguagem
como observado no Codigo 3.2.6. A arvore sintatica e nada mais que uma lista de tuplas
constituıdas a partir das regras e do gerador LALR-1.
3.2.3 Analise Semantica e Geracao de Codigo
Apos a analise lexica e sintatica, e na fase de analise semantica que sao verificados
os erros referentes a manipulacao de variaveis e, a partir da analise semantica, e obtido
Declaração e Atribuição de Variáveis 25
1 [{class,2 {1,{name,’Hello’},3 {parent,null},4 {body,[{method, {3, {return,{3,void}}, {name,main},5 {modifiers,[public,static]},6 [{3,{var_type,{3,{array,’String’}}},{parameter,’Args’}}],7 {block,4,8 [{var_declaration,9 {var_type,{5,int}},
10 {var_list, [{{var,a},{var_value,undefined}},11 {{var,b},{var_value,{integer,5,4}}}]}},12 {var_declaration,13 {var_type,{6,int}},14 {var_list,[{{var,c},{var_value,undefined}}]}},15 {var_declaration,16 {var_type,{7,float}},17 {var_list,[{{var,d},{var_value,undefined}}]}},18 {8,attribution,{var,c},{var_value,{integer,8,2}}},19 {9,attribution, {var,c}, {var_value, {op,9,’+’,20 {op,9,’/’, {var,9,a}, {op,9,’*’,{var,9,b},{var,9,a}}},{var,9,b}}}}]}}}]}}}]
Codigo 3.2.6: Arvore sintatica
tambem o codigo em Erlang. Na verdade, cria-se a estrutura da arvore sintatica do Erlang
(AST) com a ajuda do modulo proprio do Erlang chamado erl_syntax. Entao, o objetivo
e que haja todas as informacoes para a construcao dessa arvore.
Primeiramente, para a analise semantica, dado um corpo de uma funcao, percorre-se
toda a estrutura da arvore sintatica criada com o intuito de identificar tuplas de declaracoes
de variaveis, como pode ser visto na Figura 3.3. Essas tuplas foram criadas na analise
sintatica com a identificacao var_declaration, contendo tambem informacoes como linha,
tipo e uma ou mais variaveis que foram declaradas. E importante observar que podem
tambem ocorrer declaracoes envolvendo atribuicoes.
Figura 3.3: Declaracao de Variaveis
Declaração e Atribuição de Variáveis 26
Modulo ST
Varios arquivos foram utilizados para a melhor manipulacao e criacao da arvore. O mo-
dulo de manipulacao de variaveis, que possue relacao direta com dicionario de processos, e
chamado de modulo ST (Figura 3.4). Sendo uma tupla definida como declaracao de varia-
Figura 3.4: Modulo ST
veis (var_declaration), quando a arvore sintatica criada e percorrida, e feita a insercao
da chave no dicionario por meio da funcao insert_var_list. A funcao get_declared
verifica se a variavel ja foi declarada e, caso ja tenha sido, gera-se uma excecao, como
mostra o fluxograma da Figura 3.5. Para o tratamento de erros foi criado o modulo ja-
raki_exception. Esse modulo e chamado em quase todas as funcoes relacionadas as
variaveis para checagem de tipos. Nele e acoplado o retorno das verificacoes como saıda
para o compilador caso ocorra erros como os listados abaixo:
• Variaveis nao declaradas;
• Variaveis ja declaradas;
• Incompatibilidade de Tipos.
Padroes
Tuplas identificadas como atribuicao passam pelo modulo chamado gen_erl_code, es-
pecificamente na funcao match_statement, que casa esse tipo de padrao, ou seja, essa
Declaração e Atribuição de Variáveis 27
Figura 3.5: Fluxograma - Insercao de Variaveis
funcao tem como parametro esse tipo de estrutura de tupla. Como exemplo, a Figura 3.6
mostra uma atribuicao simples onde a tupla obtida pela arvore sintatica e de atribuicao.
Neste exemplo tambem observa-se que no codigo gerado para o Erlang tambem e
utilizado o modulo ST, ou seja, e contruıdo a AST desse modulo para manipularmos as
atribuicoes em tempo de execucao desse programa. A Figura 3.6 mostra a funcao cre-
Figura 3.6: Atribuicao
ate_attribution, que retorna a AST do Erlang e seu valor tambem e convertido para a
AST por meio da funcao match_attr_expr.
Apos essas e as demais construcoes da AST, o correspondente em Erlang do Codigo 3.2.1
e apresentado no Codigo 3.2.7.
Vetores 28
1 -module(jarakivar).2 -compile(export_all).3
4 main({{array, ’String’}, V_Args}) ->5 st:new(),6 st:get_new_stack({’JarakiVar’,7 {main, [{array, ’String’}]}}),8 st:put_value({{’JarakiVar’,9 {main, [{array, ’String’}]}},
10 "Args"},11 {{array, ’String’}, V_Args}),12 begin13 st:put_value({{’JarakiVar’,14 {main, [{array, ’String’}]}},15 "b"},16 {int, trunc(4)})17 end,18 st:put_value({{’JarakiVar’,19 {main, [{array, ’String’}]}},20 "c"},21 {int, trunc(2)}),22 st:put_value({{’JarakiVar’,23 {main, [{array, ’String’}]}},24 "c"},25 {int,26 trunc(st:get_value({’JarakiVar’,27 {main, [{array, ’String’}]}},28 "a")29 /30 (st:get_value({’JarakiVar’,31 {main, [{array, ’String’}]}},32 "b")33 *34 st:get_value({’JarakiVar’,35 {main, [{array, ’String’}]}},36 "a"))37 +38 st:get_value({’JarakiVar’,39 {main, [{array, ’String’}]}},40 "b"))}),41 st:destroy().
Codigo 3.2.7: Codigo Erlang - Declaracao e Atribuicao de Variaveis
3.3 Vetores
Para a implementacao de vetores foram considerados declaracoes instanciadas e com
array inicializado. O Codigo 3.3.1 mostra um exemplo do uso de vetores na linguagem
Java e servira como base nessa secao.
Varias questoes foram estudadas em relacao a essa implementacao, como diferenciar as
estruturas de declaracao, atribuicao, ındice do vetor, entre outros, mas o principal desafio
foi a passagem de vetor por referencia, que sera detalhada adiante na analise semantica.
A notacao EBNF para as regras dessa gramatica sao descritas no Codigo 3.3.2. A linha
1 define regras de declaracao de vetores para os casos de arrays instanciados (linha 8) e
Vetores 29
1 public class JarakiVetor2 {3 public static void main(String[] args) {4 int[] vet1 = {1, 2, 3};5 int[] vet2 = new int[3];6
7 vet2[2] = vet1[1] + 1;8 }9 }
Codigo 3.3.1: Codigo Java - Declaracao e Atribuicao de Variaveis envolvendo Vetores
arrays inicializados (linha 9). O acesso ao array esta vinculado na atribuicao e e descrito
como um literal. Sua estrutura, na linha 26, pode ser chamada dentro de outros escopos,
como por exemplo um print em Java.
1 <local_variable_declaration_statement> ::=2 <type> "[" "]" <array_declaration_list> {"," <array_declaration_list>} ";" |3 <type> <array_declaration_list2> {"," <array_declaration_list2>} ";"4
5 <array_declaration_list> ::= "identifier" [ "=" ("{" <array_initializer> "}" | <new_stmt>] )6 <array_declaration_list2> ::= "identifier" "[" "]" ["=" ( <new_stmt> | "{" <array_initializer> "}")]7
8 <new_stmt> ::= "new" type "[" ("integer" | "identifier" | length_stmt ) "]"9 <array_initializer> ::= <literal> [ "," <array_initializer> ]
10
11 <element_value_pair> ::= "identifier" "[" <element_value> "]" "=" <element_value> ";"12
13 <element_value> ::= <bool_expr>14 <bool_expr> ::= <comparation_expr> | <comparation_expr> <bool_op> <bool_expr>15 <comparation_expr> ::= <add_expr> | <add_expr> <comparation_op> <comparation_expr>16 <add_expr> ::= <mult_expr> | <mult_expr> <add_op> <add_expr>17 <mult_expr> ::= <modulus_expr> | <modulus_expr> <mult_op> <mult_expr>18 <modulus_expr> ::= <unary_expr> | <unary_expr> <modulus_op> <modulus_expr>19 <unary_expr> ::= <add_op> <literal> | <literal> | <bool_op> <literal>20 <literal> ::= "integer" | "float" | "identifier" | <array_access>21
22 <type> ::= "int_t" | "long_t" | "float_t" | "double_t" |23 "char_t" | "boolean_t" | "string_t"24
25 <length_stmt> ::= "identifier" "." "length"26 <array_access> ::= "identifier" "[" <element_value> "]"
Codigo 3.3.2: EBNF - Vetores
Modulo Array
O modulo do Erlang Array foi a abordagem utilizada na implementacao dos vetores. O
array, criado em Erlang, pode ter tamanho fixo ou pode crescer automaticamente, conforme
for necessario. Tambem pode ser definido um valor padrao para todos os ındices do vetor
[Erlang2012a].
Vetores 30
1 %erl2
3 1> A1 = array:new(2, {default, 0}).4 {array,2,0,0,10}5
6 2> A2 = array:set(0, 1, A1).7 {array,2,0,0,{1,0,0,0,0,0,0,0,0,0}}8
9 3> A3 = array:set(1, 2, A2).10 {array,2,0,0,{1,2,0,0,0,0,0,0,0,0}}11
12 4> A4 = array:set(2, 3, A3).13 ** exception error: bad argument14 in function array:set/315
16 5> A4 = array:get(1, A3).
Codigo 3.3.3: Modulo Array
Para exemplificar, os principais comandos do modulo Array sao mostrados no Co-
digo 3.3.3, onde A1 e um vetor de 3 posicoes (0 - 2), inicializado com valor 0. Para a
atribuicao foi utilizado a funcao set() com os parametros posicao, valor e o nome do vetor
criado, respectivamente. A funcao get() e utilizada para a captura de um ındice de um
vetor. Quando ocorre um acesso a uma posicao fora dos limites do vetor e retornado uma
mensagem de erro.
3.3.1 Analise Lexica
As principais definicoes do Codigo 3.3.1 relacionadas a estrutura do vetor podem ser
observadas na Tabela 3.3. As regras permanecem quase as mesmas, acrescentando-se ape-
nas o OpenBrackets, CloseBrackets e New. Alguns lexemas devem ser escapados, como
o sımbolo “[”, por pertencer a linguagem.
Definicao LexemaInteger intOpenBrackets \ [CloseBrackets \ ]Digit [0− 9]Identifier [a− zA− Z][a− zA− Z0− 9]∗AttributionOp =AddOp ( \+ | -)New new
Tabela 3.3: Leex - Bloco de Definicoes do Vetor
Vetores 31
Os tokens gerados por meio da ferramenta Leex para o Codigo 3.3.1 podem ser con-
sultados no Codigo 3.3.4. Os sımbolos da linguagem fonte, na sua maioria, sao retornados
para a analise lexica como a tupla {Sımbolo, Linha}.
1 [{public,1,public},2 ...3
4 {int_t,4,int},5 {’[’,4}, {’]’,4}, {identifier,4,vet1},6 {’=’,4}, {’{’,4},7 {integer,4,1},8 {’,’,4},9 {integer,4,2},
10 {’,’,4},11 {integer,4,3},12 {’}’,4}, {’;’,4},13 {int_t,5,int},14 {’[’,5}, {’]’,5}, {identifier,5,vet2},15 {’=’,5},16 {new,5,new},17 {int_t,5,int},18 {’[’,5}, {integer,5,3}, {’]’,5},19 {’;’,5},20 {identifier,7,vet2},21 {’[’,7},{integer,7,2}, {’]’,7},22 {’=’,7},23 {identifier,7,vet1},24 {’[’,7},25 {integer,7,1},26 {’]’,7},27 {add_op,7,’+’},28 {integer,7,1},29 {’;’,7}, {’}’,8}, {’}’,9}]
Codigo 3.3.4: Lista de Tokens Gerados pelo Leex
3.3.2 Analise Sintatica
Apesar da inicial dificuldade em se definir as regras e a melhor forma de descricao
das tuplas para o vetor, foram desenvolvidas no Yecc as regras, algumas expostas no
Codigo 3.3.5. Varias regras foram definidas para o vetor para abranger um grande numero
de codigos compilaveis do Java para o Erlang. Declaracoes do tipo int[ ] vetor tambem
podem ser escritas como int vetor[ ] porem, com significados diferentes. As regras
tambem dao suporte ao vetor.length(), que retorna o tamanho do vetor, oriundo do Java
A funcao make_array_type especifica que o tipo e tambem de um vetor, essencial para a
posterior checagem de tipos na analise semantica. No acesso a um vetor, o ındice pode ser
um element_value como indicado nas linha 25, ou seja, podem ser colocados expressoes
matematicas, estas que ja foram tratadas em algumas regras da analise sintatica explicado
Vetores 32
1 Rules2 ...3
4 local_variable_declaration_statement -> type ’[’ ’]’ array_declaration_list’;’:5 {var_declaration,6 {var_type, make_array_type(’$1’)},7 {var_list, ’$4’}}.8
9 array_declaration_list -> identifier:10 [{{var, unwrap(’$1’)},{var_value, undefined}}].11
12 array_declaration_list -> identifier ’,’ array_declaration_list:13 [{{var, unwrap(’$1’)}, {var_value, undefined}} | ’$3’].14
15 array_declaration_list -> identifier ’=’ ’{’ array_initializer ’}’:16 [{{var, unwrap(’$1’)}, {var_value, {array_initializer, ’$4’}}}].17
18 array_declaration_list -> identifier ’=’ new_stmt:19 [{{var, unwrap(’$1’)}, {var_value, ’$3’}}].20
21 new_stmt -> ’new’ type ’[’ integer ’]’:22 {new, array, {type, ’$2’}, {index, ’$4’}}.23
24 array_access ->25 identifier ’[’ element_value ’]’ :26 {{var, line(’$1’), unwrap(’$1’)}, {index, ’$3’}}.27
28 element_value -> bool_expr : ’$1’.29 ...30 literal -> array_access : ’$1’.31
32 Erlang code33
34 make_array_type({Line, PrimitiveType}) -> {Line, {array, PrimitiveType}}.
Codigo 3.3.5: Estrutura do arquivo jaraki parser.yrl
na sessao anterior. A arvore sintatica gerada pelo Yecc, no Codigo 3.3.6, contem a lista de
tuplas construıdas dado essas regras.
A atribuicao do array e identificada como array_attribution, ou seja, ele recebe uma
expressao. Como ja foi dito, a regra element_value deriva de expressoes aritmeticas e,
como pode ser observado, nas regras, um array tambem e derivado da mesma. Isso possibila
que ocorram qualquer tipo de expressoes envolvendo vetores e variaveis (Ex: a = vet[i],
vet[2] = a + 2).
3.3.3 Analise Semantica e Geracao de Codigo
Como ja foi descrito, a primeira estrutura a ser verificada e o armazenamento de va-
riaveis no dicionario. Na analise semantica, essa implementacao segue o mesmo fluxo ja
explicado na sessao anterior.
Em relacao ao vetor, o tratamento em termos de geracao de codigo se altera um pouco
Vetores 33
1 [{class,2 ...3 {block,3,4 {var_declaration,5 {var_type,{4,{array,int}}},6 {var_list,7 [{{var,vet1},8 {var_value,9 {array_initializer,
10 [{array_element,{integer,4,1}},11 {array_element,{integer,4,2}},12 {array_element,{integer,4,3}}]}}}]}},13 {var_declaration,14 {var_type,{5,{array,int}}},15 {var_list,16 [{{var,vet2},17 {var_value,18 {new,array,19 {type,{5,int}},20 {index,{integer,5,3}}}}}]}},21 {7,array_attribution,22 {{var,vet2},{index,{integer,7,2}}},23 {var_value,24 {op,7,’+’,25 {{var,7,vet1},{index,{integer,7,1}}},26 {integer,7,1}}}}]}}}]}}}]
Codigo 3.3.6: Arvore Sintatica
ja que o vetor deve ser passado por referencia, ou seja, em tempo de execucao o tratamento
para o tipo de variavel vetor e diferente. Algumas consideracoes foram feitas e a abordagem
escolhida foi a criacao de um modulo chamado Vector.
Modulo Vector
O modulo Vector acopla o modulo Array do Erlang. Por meio desse modulo e criado
um “endereco de memoria” para cada vetor criado. Diferente das variaveis, o retorno da
busca de um vetor no modulo ST deve retornar esse endereco.
A Figura 3.7 mostra o fluxo de criacao de um vetor instanciado com 10 posicoes. Quando
ele e criado, seu valor e o retorno do modulo Array do Erlang, ou seja, um array fixo com
10 posicoes inicializado com valores 0.
A primeira etapa dessa abordagem e atualizar um contador de vetores, onde isso e
feito para cada novo vetor. Basicamente, esse contador faz com que cada vetor tenha um
numero ligado a ele, que e unico. Depois que isso ocorre, o vetor e inserido no dicionario de
processos por meio do modulo ST com uma estrutura diferente da variavel, onde sua chave
e uma tupla {array_dict, Endereco} e seu valor o array que veio como parametro na
funcao new_vector. O retorno dessa funcao e o endereco, ou seja, um numero. Em tempos
Matrizes 34
Figura 3.7: Modulo Vector
de execucao isso se torna essencial para a passagem do vetor como parametro como ocorre
na linguagem Java.
Quando o vetor for do tipo inicializado, primeiramente devem ser feitas todas as in-
sercoes para estrutura array do Erlang e so depois e criado o array por meio da funcao
new_vector.
Declaracao de Array
A analise sintatica retorna uma unica ou uma lista de tuplas identificadas como
{var_declaration, ... } quando uma variavel e declarada, assim como o vetor. Essa
lista de variaveis podem conter uma atribuicao, um array instanciado, array inicializado
ou os tres. O que diferencia cada um e a identificacao do seu valor na tupla. O esquema na
(Figura 3.8) mostra como a funcao pode ser desmembrada apenas com essa identificacao.
Como o objetivo ao final da analise semantica e criar os elementos da AST, nao se
utiliza o modulo Array do Erlang nessa fase, mas foi criado o elemento AST do modulo
Vector que, em tempo de execucao estara vinculado a esse modulo.
O codigo gerado em Erlang dentro desse escopo e mostrado no Codigo 3.3.7.
3.4 Matrizes
Para a implementacao de matriz tambem foram considerados as matrizes instanciadas
e inicializadas, assim como, a atribuicao envolvendo matrizes, vetores e variaveis. O Co-
Matrizes 35
Figura 3.8: Declaracoes de Array
digo 3.4.1 mostra os dois tipos de declaracao e uma atribuicao simples com matrizes. Ele
sera utilizado como codigo-base nessa secao.
As matrizes tambem sao passadas por referencia e tambem utiliza a abordagem do
modulo Array do Erlang. Como a matriz e um vetor de vetor, a EBNF da sua gramatica
(Codigo 3.4.2) e similar ao que foi desenvolvido para o array. Praticamente, as alteracoes
foram feitas em relacao ao tipo, a inicializacao da matriz e algumas consideracoes inerentes
a estrutura da matriz.
3.4.1 Analise Lexica
Para a analise lexica, as principais definicoes ja foram descritas nas sessoes anteriores.
A lista de tokens gerados, com base no Codigo 3.4.1, pela ferramenta Leex sao descritas
no Codigo 3.4.3. As linhas 3 a 14 mostram os tokens gerados para a mat1 e, para a matriz
instanciada, mat2, nas linhas 15 a 22.
3.4.2 Analise Sintatica
Para a analise sintatica foram definidos tambem, assim como vetor, regras que tivessem
suporte para declaracoes como int[][] matriz ou int matriz[][], matriz.length(),
estruturas de acesso a matriz e atribuicoes envolvendo o mesmo. O tipo da matriz tambem
e tratada para verificacoes do modulo jaraki_exception na analise semantica. As regras
oriundas do Yecc sao vistas no Codigo 3.4.4. E importante observar que a estrutura e bem
similar ao vetor, onde tambem e passado um ındice para a analise semantica, sendo que
Matrizes 36
1 -module(jarakivetor).2 -compile(export_all).3 -import(vector, [new/1, get_vector/1]).4
5 main({{array, ’String’}, V_args}) ->6 st:new(),7 st:get_new_stack({’JarakiVetor’,8 {main, [{array, ’String’}]}}),9 st:put_value({{’JarakiVetor’,
10 {main, [{array, ’String’}]}},11 "args"},12 {{array, ’String’}, V_args}),13 begin14 begin15 st:put_value({{’JarakiVetor’,16 {main, [{array, ’String’}]}},17 "vet1"},18 {{array, int}, vector:new(array:from_list([1, 2, 3]))})19 end20 end,21 begin22 st:put_value({{’JarakiVetor’,23 {main, [{array, ’String’}]}},24 "vet2"},25 {int, vector:new_vector(3)})26 end,27 st:put_value({{’JarakiVetor’,28 {main, [{array, ’String’}]}},29 "vet2"},30 {{array, int},31 vector:set_vector(2,32 vector:access_vector(1,33 st:get_value({’JarakiVetor’,34 {main,35 [{array,’String’}]}},36 "vet1"))37 + 1,38 st:get_value({’JarakiVetor’,39 {main, [{array, ’String’}]}},40 "vet2"))}),41 st:destroy().
Codigo 3.3.7: Codigo Erlang - Vetor
1 public class JarakiMatriz {2 public static void main(String[] args) {3 int[][] mat1 = {{1, 2}, {3, 4}};4 int[][] mat2 = new int[2][2];5
6 mat1[0][0] = 9;7 }8 }
Codigo 3.4.1: Codigo Java - Matriz
a tupla {index, {row, LinhaMatriz}, {column, ColunaMatriz} } identifica o ındice
com a linha e coluna da matriz.
Tendo como consideracoes as regras definidas, a arvore gerada esta descrita no Co-
digo 3.4.5. Para cada linha da matriz e criado uma tupla identificada como {ma-
Matrizes 37
1 <local_variable_declaration_statement> ::=2 <type> "[" "]" "[" "]" <array_declaration_list> {"," <array_declaration_list>} ";" |3 <type> <array_declaration_list3> {"," <array_declaration_list3>} ";"4
5 <array_declaration_list> ::= "identifier" [ "=" ("{" <array_initializer> "}" | <new_stmt> )]6 <array_declaration_list2>::= "identifier" "[" "]" "[" "]" ["=" ( <new_stmt> | "{" <array_initializer> "}")]7
8 <new_stmt> ::= "new" type "[" ("integer" | "identifier" ) "]" "[" ("integer" | "identifier" ) "]"9 <array_initializer> ::= (<literal> | "{" <array_initializer> "}") {"," <array_initializer>}
10
11 <element_value_pair>::= "identifier" "[" <element_value> "]" "[" <element_value> "]" "=" <element_value> ";"12
13 <element_value> ::= <bool_expr>14 <bool_expr> ::= <comparation_expr> | <comparation_expr> <bool_op> <bool_expr>15 <comparation_expr> ::= <add_expr> | <add_expr> <comparation_op> <comparation_expr>16 <add_expr> ::= <mult_expr> | <mult_expr> <add_op> <add_expr>17 <mult_expr> ::= <modulus_expr> | <modulus_expr> <mult_op> <mult_expr>18 <modulus_expr> ::= <unary_expr> | <unary_expr> <modulus_op> <modulus_expr>19 <unary_expr> ::= <add_op> <literal> | <literal> | <bool_op> <literal>20 <literal> ::= "integer" | "float" | "identifier" | <array_access>21
22 <type> ::= "int_t" | "long_t" | "float_t" | "double_t" |23 "char_t" | "boolean_t" | "string_t"24
25 <length_stmt> ::= "identifier" "." "length"26 <array_access> ::= "identifier" "[" <element_value> "]" "[" <element_value> "]"
Codigo 3.4.2: EBNF - Matrizes
1 [{public,1,public},2 ...3 {int_t,3,int},4 {’[’,3}, {’]’,3},5 {’[’,3}, {’]’,3},6 {identifier,3,mat1}, {’=’,3},7 {’{’,3}, {’{’,3},8 {integer,3,1}, {’,’,3},9 {integer,3,2}, {’}’,3},
10 {’,’,3},11 {’{’,3},12 {integer,3,3}, {’,’,3},13 {integer,3,4}, {’}’,3},14 {’}’,3},15 {’;’,3},16 {int_t,4,int},17 {’[’,4}, {’]’,4},18 {’[’,4}, {’]’,4},19 {identifier,4,mat2},20 {’=’,4},21 {new,4,new}, {int_t,4,int},22 {’[’,4}, {integer,4,2}, {’]’,4},23 {’[’,4}, {integer,4,2}, {’]’,4},24 {’;’,4},25 {identifier,6,mat1},26 {’[’,6}, {integer,6,0}, {’]’,6},27 {’[’,6}, {integer,6,0}, {’]’,6},28 {’=’,6}, {integer,6,9}, {’;’,6},29 {’}’,7},30 {’}’,8}]
Codigo 3.4.3: Lista de Tokens Gerados pelo Leex
Matrizes 38
1 Rules2 local_variable_declaration_statement -> type ’[’ ’]’ ’[’ ’]’ array_declaration_list’;’:3 {var_declaration,4 {var_type, make_matrix_type(’$1’)},5 {var_list, ’$6’}}.6
7 array_declaration_list -> identifier:8 [{{var, unwrap(’$1’)},{var_value, undefined}}].9
10 array_declaration_list -> identifier ’,’ array_declaration_list:11 [{{var, unwrap(’$1’)}, {var_value, undefined}} | ’$3’].12
13 array_declaration_list -> identifier ’=’ ’{’ array_initializer ’}’:14 [{{var, unwrap(’$1’)}, {var_value, {array_initializer, ’$4’}}}].15
16 array_declaration_list -> identifier ’=’ new_stmt:17 [{{var, unwrap(’$1’)}, {var_value, ’$3’}}].18
19 new_stmt -> ’new’ type ’[’ integer ’]’ ’[’ integer ’]’:20 {new, array, {type, ’$2’}, {index, {row, ’$4’}, {column, ’$7’}}}.21
22 element_value_pair -> identifier ’[’ element_value ’]’ ’[’ element_value ’]’’=’23 element_value ’;’:24 {line(’$1’), array_attribution,25 {{var, unwrap(’$1’)},{index, {row, ’$3’}, {column, ’$6’}} },26 {var_value, ’$9’}}.27 array_access ->28 identifier ’[’ element_value ’]’ ’[’ element_value ’]’ :29 {{var, line(’$1’), unwrap(’$1’)},30 {index, {row, ’$3’}, {column, ’$6’} } }.31
32 element_value -> bool_expr : ’$1’.33 ...34 literal -> array_access : ’$1’.35
36 Erlang code37
38 make_matrix_type({Line, PrimitiveType}) -> {Line, {matrix, PrimitiveType}}.
Codigo 3.4.4: Estrutura do arquivo jaraki parser.yrl
trix_element, ...} com seus respectivos elementos (array_element).
3.4.3 Analise Semantica e Geracao de Codigo
Para a implementacao dessa estrutura de matrizes tambem foi utilizado o modulo array
do Erlang, apesar de que ele trata apenas vetores. A Figura 3.9, mostra a abordagem
utilizada onde e criado um vetor principal que indica as linhas da matriz e, para cada
posicao da linha, e criado um vetor indicando as colunas.
Para tratar e criar esse array de array foi criado um modulo chamado Matrix.
Matrizes 39
1 [{class,2 ...3 [{var_declaration,4 {var_type,{3,{matrix,int}}},5 {var_list,6 [{{var,mat1},7 {var_value,8 {array_initializer,9 [{matrix_element,
10 [{array_element,{integer,3,1}},11 {array_element,{integer,3,2}}]},12 {matrix_element,13 [{array_element,{integer,3,3}},14 {array_element,{integer,3,4}}]}]}}}]}},15 {var_declaration,16 {var_type,{4,{matrix,int}}},17 {var_list,18 [{{var,mat2},19 {var_value,20 {new,array,21 {type,{4,int}},22 {index,{row,{integer,4,2}},{column,{integer,4,2}}}}}}]}},23 {6,array_attribution,24 {{var,mat1},{index,{row,{integer,6,0}},{column,{integer,6,0}}}},25 {var_value,{integer,6,9}}}]}}}]}}}]
Codigo 3.4.5: Arvore Sintatica
Figura 3.9: Array de Array
Modulo Matrix
O modulo Matrix fornece todo o suporte para o codigo gerado, criando vetores, linhas
e colunas, dado a ordem da matriz. O exemplo da Figura 3.10 mostra um codigo gerado a
partir do codigo Java que instancia um vetor de ordem 2. Nota-se que a analise semantica
gera o vınculo com o modulo Matrix por meio da funcao creation_matrix. Fundamen-
talmente, essa funcao cria um vetor linha e um de coluna com valores iniciais iguais a zero.
Matrizes 40
Captura-se o tamanho do vetor linha para ser criado um vetor coluna para cada posicao.
Apos isso ocorrer, com o mesmo fluxo ja explicado para o vetor, e obtido um “endereco de
memoria” para essa matriz.
Figura 3.10: Modulo Matrix
O fluxo da Figura 3.11 mostra que, como a matriz de ordem 2 dada como exemplo
contem posicoes 0 e 1, o tamanho da linha e definido com valor 1. Posteriormente, com
o vetor de colunas ja criado, atualiza-se o vetor linha na posicao 0 com esse vetor. Caso
a posicao da linha ainda nao seja igual ao tamanho da linha, e chamada a mesma fun-
cao recursivamente com a posicao de linha agora incrementada. Nessa posicao tambem
atualiza-se o vetor linha, mas agora na posicao 1.
O modulo Matrix tambem atualiza valores em tempos de execucao para casos de atri-
buicao, dando todo o suporte basico das estruturas de matriz da linguagem Java. O
Codigo 3.4.6 foi gerado em Erlang tendo como base o codigo em Java dado como base
nessa secao e apresenta algumas dessas estruturas do modulo Matrix.
Matrizes 41
Figura 3.11: Fluxo Matrix
1 -module(jarakimatriz).2 -compile(export_all).3 -import(matrix, [new_matrix/1, creation_matrix/2]).4
5 main({{array, ’String’}, V_args}) ->6 st:new(),7 st:get_new_stack({’JarakiMatriz’,8 {main, [{array, ’String’}]}}),9 st:put_value({{’JarakiMatriz’,
10 {main, [{array, ’String’}]}},11 "args"},12 {{array, ’String’}, V_args}),13 begin14 begin15 st:put_value({{’JarakiMatriz’,16 {main, [{array, ’String’}]}},17 "mat1"},18 {{matrix, int},19 matrix:new_matrix(array:from_list([array:from_list([1, 2]),20 array:from_list([3, 4])]))})21 end22 end,23 begin24 st:put_value({{’JarakiMatriz’,25 {main, [{array, ’String’}]}},26 "mat2"},27 {int, matrix:creation_matrix(2, 2)})28 end,29 st:put_value({{’JarakiMatriz’,30 {main, [{array, ’String’}]}},31 "mat1"}, {{matrix, int},32 matrix:set_matrix(0, 0, 9,33 st:get_value({’JarakiMatriz’,34 {main, [{array, ’String’}]}},35 "mat1"))}),36 st:destroy().
Codigo 3.4.6: Codigo Erlang - Matrix
Capıtulo 4
Testes
Neste capıtulo constam alguns arquivos testes em java, a arvore gerada pelo compilador
Jaraki, a arvore abstrata do Erlang do codigo gerado e a comparacao dos tempos de compi-
lacao e execucao das linguagens envolvidas inerentes as principais implementacoes dentro
do escopo deste trabalho.
4.1 Processo de Compilacao
Para os processos de compilacao e execucao de cada teste contido neste capıtulo foram
utilizados o sistema operacional GNU/Linux 11.04 (natty), Kernel 2.6.38-15-generic e as
seguintes configuracoes de hardware:
• Computador: Hp Pavilion dv4
• Processador: Core i5 2.27GHz
• Memoria: 4GB
O comando time foi utilizado na compilacao e execucao de ambas as linguagens. Na
compilacao de testes da linguagem Java, foi usado o comando javac e, para execucao, o
comando java. Em Erlang foi criado um script para a compilacao e outro para a execucao
dos testes gerados, onde para cada teste deve ser escrito o comando ./jkc caminhoArquivo
e na execucao ./jk caminhoArquivo .
As versoes dos softwares de cada linguagem sao descritas abaixo:
• Java: 1.6.0 24
• Erlang: V5.8.4
Processo de Compilação 43
O Codigo 4.1.1 apresenta a estrutura base da utilizacao de variaveis em um codigo em
Java, nele e calculado a media de duas notas. Como a variavel media foi declarada como
inteiro, o resultado dessa operacao tambem devera ser inteiro.
1 public class Variaveis {2 public static void main(String args[]){3 int media, nota1, nota2;4 nota1 = 7;5 nota2 = 8;6 media = (nota1 + nota2)/2;7
8 System.out.println(media);9 }
10 }
Codigo 4.1.1: Codigo Java - Calculo Media
4.1.1 Arvore Sintatica do compilador Jaraki - JAST
A arvore criada a partir da analise sintatica da ferramenta Yecc para o compilador
Jaraki pode ser vista no Codigo 4.1.2. A JAST foi construıda a partir das regras da analise
sintatica para representar o parser do codigo em Java.
A arvore foi criada seguindo o modelo da arvore sintatica do Erlang, ou seja, a JAST
e constituıda por uma lista de tuplas que representam as principais construcoes como, por
exemplo, a declaracao e a atribuicao de variaveis.
A estrutura de declaracao inicia na linha 13, definida na tupla var_declaration, e para
a mesma sao capturados o tipo e todas as variaveis dessa declaracao, uma lista de variaveis.
A tupla que define a atribuicao da media inicia na linha 21 e a tupla {var_value,..} contem
toda a operacao, que e construıda dessa forma para facilitar o processo de analise semantica.
4.1.2 Arvore Sintatica do Erlang - AST
Parte da AST (Arvore Sintatica do Erlang) pode ser visualizada no Codigo 4.1.3. Por
meio dessa arvore pode ser construıdo a estrutura similar do codigo Java em Erlang. A
estrutura, nesse caso de declaracao, contruıda na analise semantica como suporte a decla-
racao de variaveis no Erlang e a implementacao do dicionario de processos do Erlang. A
linha 6, por exemplo, contem a tupla {remote,17,{atom,17,st},{atom,17,put_value}},
Teste 1 - Variáveis 44
1 [{class,2 {1,3 {name,’Variaveis’},4 {parent,null},5 {body,6 [{method,7 {2,8 {return,{2,void}},9 {name,main},
10 {modifiers,[public,static]},11 [{2,{var_type,{2,{array,’String’}}},{parameter,args}}],12 {block,2,13 [{var_declaration,14 {var_type,{3,int}},15 {var_list,16 [{{var,media},{var_value,undefined}},17 {{var,nota1},{var_value,undefined}},18 {{var,nota2},{var_value,undefined}}]}},19 {4,attribution,{var,nota1},{var_value,{integer,4,7}}},20 {5,attribution,{var,nota2},{var_value,{integer,5,8}}},21 {6,attribution,22 {var,media},23 {var_value,24 {op,6,’/’,25 {op,6,’+’,{var,6,nota1},{var,6,nota2}},26 {integer,6,2}}}},27 {8,println,[{identifier,8,media}]}]}}}]}}}]
Codigo 4.1.2: JAST - Calculo Media
que gera o codigo que chama o modulo ST e, por meio da funcao put_value, armazena a
variavel no dicionario, assim como, seu tipo, escopo e valor.
O Codigo 4.1.4 foi gerado pelo compilador Jaraki e contem a estrutura do codigo fonte
em Java com a utilizacao do dicionario de processos. Como o resultado do calculo da media
sera um valor float, o elemento trunc(linha 19) arrendonda o valor obtido.
Observando o codigo gerado, podemos visualizar a manipulacao das variaveis por meio
do modulo ST onde cada variavel declarada tem seu valor inserido (st:put_value) por
meio de uma chave e um valor. A chave, por exemplo para a variavel nota1 (linhas 10 a
12), e a tupla {Escopo, NomeVariavel} e o seu valor Tipo, ValorVariavel.
4.2 Teste 1 - Variaveis
Os tempos de compilacao e execucao, respectivamente, do codigo de calculo da media
em Java sao observados na Figura 4.1 e Figura 4.2.
O codigo gerado em Erlang tambem apresenta o mesmo resultado, porem com tempos
de compilacao (Figura 4.3) e execucao (Figura 4.4) diferentes.
Teste 2 - Strings 45
1 [{attribute,1,file,{"variaveis.erl",1}},2 ...,3 {string,14,"nota2"}]},4 {tuple,15,[{atom,15,int},{call,15,{atom,15,trunc},[{integer,15,8}]}]}]},5 {call,17,6 {remote,17,{atom,17,st},{atom,17,put_value}},7 [{tuple,17,8 [{tuple,17,9 [{atom,17,’Variaveis’},
10 {tuple,18,11 [{atom,18,main},12 {cons,18,13 {tuple,18,[{atom,18,array},{atom,18,’String’}]},14 {nil,18}}]}]},15 {string,18,"media"}]},16 {tuple,19,17 [{atom,19,int},18 {call,19,19 {atom,19,trunc},20 [{op,22,’/’,21 {op,21,’+’,22 {call,19,23 {remote,19,{atom,19,st},{atom,19,get_value}},24 [{tuple,19,25 [{atom,19,’Variaveis’},26 {tuple,20,27 [{atom,20,main},28 {cons,20,29 {tuple,20,[{atom,20,array},{atom,20,’String’}]},30 {nil,20}}]}]},31 {string,20,"nota1"}]},32 {call,21,33 {remote,21,{atom,21,st},{atom,21,get_value}},34 [{tuple,21,35 [{atom,21,’Variaveis’},36 {tuple,22,37 [{atom,22,main},38 {cons,22,39 {tuple,22,[{atom,22,array},{atom,22,’String’}]},40 {nil,22}}]}]},41 {string,22,"nota2"}]}},42 {integer,22,2}}]}]}]},43 ...,44 {call,26,{remote,26,{atom,26,st},{atom,26,destroy}},[]}]}]},45 {eof,27}]
Codigo 4.1.3: AST do Erlang - Calculo Media
Figura 4.1: Tempo de Compilacao em Java - Calculo Media
4.3 Teste 2 - Strings
O Codigo 4.3.1 mostra um arquivo teste que utiliza o tipo de variavel String. Esse
codigo contem concatenacao de strings e imprime as strings “UEA”e “UEA String”.
Teste 2 - Strings 46
1 -module(variaveis).2 -compile(export_all).3
4 main({{array, ’String’}, V_args}) ->5 st:new(),6 st:get_new_stack({’Variaveis’, {main, [{array, ’String’}]}}),7 st:put_value({{’Variaveis’,8 {main, [{array, ’String’}]}}, "args"},9 {{array, ’String’}, V_args}),
10 st:put_value({{’Variaveis’,11 {main, [{array, ’String’}]}}, "nota1"},12 {int, trunc(7)}),13 st:put_value({{’Variaveis’,14 {main, [{array, ’String’}]}}, "nota2"},15 {int, trunc(8)}),16
17 st:put_value({{’Variaveis’,18 {main, [{array, ’String’}]}}, "media"},19 {int, trunc((st:get_value({’Variaveis’,20 {main, [{array, ’String’}]}}, "nota1")21 + st:get_value({’Variaveis’,22 {main, [{array, ’String’}]}}, "nota2")) / 2)}),23 io:format("~p~n",24 [st:get_value({’Variaveis’,25 {main, [{array, ’String’}]}}, "media")]),26 st:destroy().
Codigo 4.1.4: Codigo Erlang - Calculo Media
Figura 4.2: Tempo de Execucao em Java - Calculo Media
Figura 4.3: Tempo de Compilacao em Erlang - Calculo Media
Figura 4.4: Tempo de Execucao em Erlang - Calculo Media
Teste 2 - Strings 47
1 public class String1 {2
3 public static void main(String[] args) {4 String u = "U";5 String e = "E";6 String a = "A";7 String uea, teste;8 uea = u + e + a;9 teste = uea + " " + "String";
10 System.out.println(uea);11 System.out.println(teste);12 }13 }
Codigo 4.3.1: Codigo Java - String
Observa-se na Figura 4.5 o tempo de compilacao em java de 0,706s. A Figura 4.6 mostra
a saıda, resultado da concatenacao de tres variaveis e tambem uma concatenacao direta
envolvendo strings, com tempo de execucao de 0,079s.
Figura 4.5: Tempo de Compilacao em Java - String
Figura 4.6: Tempo de Execucao em Java - String
O codigo em Erlang, apresentado no apendice, contem a estrutura criada, como su-
porte a strings com a utilizacao do dicionario de processos implementado. O sımbolo ++
representa a concatenacao de strings em Erlang.
A Figura 4.7 mostra o resultado da compilacao que gera o arquivo em Erlang, cujo
tempo e de 0,302s. Na execucao desse arquivo, Figura 4.8, a mesma saıda do algoritmo e
gerada com tempo de execucao de 0,169s.
Teste 3 - Char 48
Figura 4.7: Tempo de Compilacao em Erlang - String
Figura 4.8: Tempo de Execucao em Erlang - String
4.4 Teste 3 - Char
O Codigo 4.4.1 contem uma estrutura simples, referente ao uso do tipo char em java
tendo como saıda as duas variaveis declaradas como char.
1 public class Char1 {2 public static void main(String args []){3 char a = ’A’;4 char b = ’B’;5
6 System.out.println("Char: " + a);7 System.out.println("Char: " + b);8 }9
10 }
Codigo 4.4.1: Codigo Java - Char
A Figura 4.9 mostra o tempo de compilacao em Java de 0,724s e, na Figura 4.10,
podemos observar um tempo de execucao de 0,074s.
Figura 4.9: Tempo de Compilacao em Java - Char
Teste 4 - Vetores 49
Figura 4.10: Tempo de Execucao em Java - Char
O codigo gerado em Erlang, apresentado no apendice, contem a declaracao com atri-
buicao do char seguindo a estrutura da definicao do char em Erlang, onde por exemplo,
para a variavel “a” e armazenado no dicionario “$A”, ou seja, seu codigo em ASCII .
A Figura 4.11 apresenta o tempo de compilacao em Erlang de 0,316s e na execucao do
codigo gerado em Erlang foi obtido o mesma saıda em Java com tempo de execucao de
0,155s.
Figura 4.11: Tempo de Compilacao em Erlang - Char
Figura 4.12: Tempo de Execucao em Erlang - Char
4.5 Teste 4 - Vetores
Como exemplos para o suporte a vetores, 2 testes foram implementados em java.
4.5.1 Bubblesort
O primeiro codigo implementa o algoritmo do metodo de ordenacao bolha, bubblesort,
como mostra o Codigo 4.5.1, que percorre um vetor de inteiros comparando elementos
Teste 4 - Vetores 50
adjacentes.
1 public class BubbleSort {2 public static int[] bubbleSort(int[] vetor){3 int aux;4 int temp;5
6 for (int i = 0; i < vetor.length; i++) {7 for (int j = 0; j < vetor.length - 1; j++) {8 temp = j+1;9 if (vetor[j] > vetor[temp]) {
10 aux = vetor[j];11 vetor[j] = vetor[temp];12 vetor[temp] = aux;13 }14 }15 }16 return vetor;17 }18
19 public static void main(String[] args) {20 int[] vetor = {5,2,1,4,3};21 vetor = bubbleSort(vetor);22
23 for (int i = 0; i < vetor.length; i++) {24 System.out.print(vetor[i]+" ");25 }26 }27 }
Codigo 4.5.1: Codigo Java - Metodo de ordenacao bolha
O tempo de compilacao e execucao desse codigo em Java pode ser verificado na Fi-
gura 4.13, assim como a saıda dos elementos ordenados para o vetor de 5 elementos dado
como entrada.
Figura 4.13: Tempo de Compilacao e Execucao em Java - bubblesort
O Codigo em Erlang gerado a partir do codigo bubblesort em Java esta no apendice
deste trabalho e apresenta a mesma saıda de Java sendo que o tempo de compilacao em
Erlang e de 0.690s(Figura 4.14) e tempo de execucao de 0,77s (Figura 4.15).
Teste 4 - Vetores 51
Figura 4.14: Tempo de Compilacao em Erlang - bubblesort
Figura 4.15: Tempo de Execucao em Erlang - bubblesort
4.5.2 Quicksort
O segundo codigo desenvolvido na linguagem Java (Codigo 4.5.2) implementa o algo-
ritmo de ordenacao de vetores quicksort, que adota a estrategia de divisao e conquista.
O codigo em Java apresentou o tempo de compilacao e execucao para a entrada de
12 elementos e um vetor de 0,686s e 0,072s, respectivamente, como pode ser visto na
Figura 4.16.
Figura 4.16: Tempo de Compilacao e Execucao em Java - quicksort
Para o algoritmo quicksort em Erlang tambem foi obtido a mesma saıda como em Java,
mas com um tempo de compilacao(Figura 4.17) e execucao(Figura 4.18) de aproxidamente
0,382s e 0,156, respectivamente.
Matrizes 52
1 public class QuickSort {2 public static int[] quick_sort(int[] v,int ini, int fim) {3 int meio;4 if (ini < fim) {5 meio = partition(v, ini, fim);6 v= quick_sort(v, ini, meio);7 v = quick_sort(v, meio + 1, fim);8 }9 return v;
10 }11
12 public static int partition(int []v, int ini, int fim) {13 int pivo, topo;14 pivo = v[ini];15 topo = ini;16 for (int i = ini + 1; i < fim; i++) {17 if (v[i] < pivo) {18 v[topo] = v[i];19 v[i] = v[topo + 1];20 topo++;21 }22 }23 v[topo] = pivo;24 return topo;25 }26
27 public static void main(String[] args) {28 int[] vet = {8,5,2,7,1,10,4,3,6,50,9,25};29 int[] vet1;30 vet1 = quick_sort(vet, 0, vet.length);31
32 for(int i=0; i< vet.length; i++)33 System.out.print(vet1[i] + " ");34 }35 }
Codigo 4.5.2: Codigo Java - Algoritmo Quicksort
Figura 4.17: Tempo de Compilacao em Erlang - quicksort
Figura 4.18: Tempo de Execucao em Erlang - quicksort
4.6 Matrizes
O teste apresentado nesta secao e a de um algoritmo de multiplicacao de matrizes
de ordem 4, onde primeiramente sao inicializados dois vetores randomicamente (o codigo
Matrizes 53
completo, em Java e Erlang, foi inserido no apendice deste trabalho).
O tempo de compilacao em Java para esse algoritmo foi de 0,724s (Figura 4.19) e o de
execucao 0,080s.
A Figura 4.20 mostra o tempo de execucao, as duas matrizes geradas randomicamente
e a matriz resultado da multiplicacao das mesmas.
Figura 4.19: Tempo de Compilacao Java - Matrizes
Figura 4.20: Tempo de Execucao em Java - Matrizes
O codigo em Erlang gerado possui tempo de compilacao de 0,397s como mostra a
Figura 4.21.
Figura 4.21: Tempo de Compilacao em Erlang - Matrizes
Erros 54
Na Figura 4.22 verifica-se que o tempo de execucao em Erlang foi de 0,169 e a saıda
deste algoritmo foi similar ao de Java, sendo que as matrizes bases para a multiplicacao,
devido serem randomicamente geradas, tiveram resultados diferentes.
Figura 4.22: Tempo de Execucao em Erlang - Matrizes
4.7 Erros
O Codigo 4.7.1 mostra um exemplo de erros envolvendo variaveis com variaveis ja
decladadas e tambem variaveis nao declaradas.
1 public class TestandoErro {2
3 public static void main(String[] args) {4 int a;5 a = 10;6 int a;7
8 System.out.println(a);9 d = d + 1;
10 }11 }
Codigo 4.7.1: Codigo Java - Erro de Variaveis
Ao compilarmos o codigo, a linguagem Java tem como retorno dois erros (Figura 4.23)
e por isso nao gera codigo executavel.
Resumo do Tempo dos Testes 55
Figura 4.23: Tempo de Compilacao Java - Erros
Apos todos os tratamentos com a utilizacao do dicionario de processos, em Erlang,
tambem e gerado relatorio similar que contem os erros verificados no codigo, observados
na Figura 4.24, e ele tambem nao gera codigo executavel
Figura 4.24: Tempo de Execucao em Java - Erros
4.8 Resumo do Tempo dos Testes
A Tabela 4.1 mostra o resumo do tempo de compilacao e execucao de cada teste mos-
trado neste capıtulo para a linguagem Java e tambem para o Erlang.
Tempos Java (s) Tempos Erlang (s)Testes Compilacao Execucao Compilacao Execucao
Variaveis 0,729 0,078 0,291 0,227Strings 0,706 0,079 0,302 0,169Char 0,724 0,074 0,316 0,155Vetores - bubblesort 0,690 0,077 0,340 0,165Vetores - quicksort 0,686 0,072 0,382 0,156Matrizes 0,724 0,080 0,397 0,169
Tabela 4.1: Resumo dos tempos de testes
Capıtulo 5
Conclusoes
Neste trabalho foi desenvolvido o suporte a variaveis e erros para o compilador Jaraki tendo
como desafio portar a linguagem orientada a objetos Java na linguagem funcional Erlang.
Para a analise lexica e sintatica, foram utilizadas as ferramentas Leex e Yecc, inerentes
a linguagem Erlang, que auxiliaram nas fases de construcao da arvore sintatica. Com o
estudo da arvore sintatica do Erlang (AST), definiu-se as estruturas para a geracao de
codigo em Erlang. Em meio a esse processo, a arvore sintatica para o compilador Jaraki
foi criado (JAST), onde o mesmo foi essencial para a implementacao da analise semantica.
Dentro do escopo deste projeto, as principais dificuldades encontradas foram em re-
lacao a manipulacao de variaveis e abordagens envolvendo arrays. Para as variaveis, foi
implementado o dicionario de processos da linguagem Erlang com o intuito de armazenar o
escopo, tipo e outras caracterısticas ligadas a esse conceito, tanto para a analise semantica
como geracao de codigo. O dicionario elaborado tornou-se imprescindıvel tambem para o
tratamento e retorno do relatorio de erros. Essas estruturas tambem foram necessarias no
codigo gerado e, por isso, foram encapsuladas por meio de modulos. Outros modulos criados
envolvem vetores e matrizes, tendo como parte fundamental a implementacao da passagem
por referencia dos mesmos com a finalidade de obter estrutura similar a linguagem Java.
Alguns testes foram apresentados abrangendo as principais estruturas desenvolvidas
(tipos, declaracoes, atribuicoes, escopo, vetores, matrizes e erros), assim como os tempos
de compilacao e execucao tanto para a linguagem Java como para a linguagem Erlang.
Observa-se que os tempos de compilacao, em Erlang, foram menores para todos os testes
implementados comparados com a linguagem Java e para os tempos de execucao a lingua-
gem Java possui valores com um tempo menor. Estes resultados obtidos sao considerados
relevantes, visto que as estruturas e modulos implementados foram necessarios dadas as
Trabalhos Futuros 57
caracterısticas e conceitos diferentes em relacao a variaveis referentes a cada linguagem.
5.1 Trabalhos Futuros
Apesar da maioria das estruturas envolvendo variaveis terem sido desenvolvidas, algu-
mas implementacoes podem ser realizadas como trabalhos futuros. Por exemplo, a mani-
pulacao de variaveis globais e tambem outros tratamentos envolvendo erros. As variaveis
globais devem ser tratadas em conjunto com a implementacao da orientacao a objetos do
compilador Jaraki com o intuito de alcancar uma abordagem mais proxima da que ja foi
desenvolvida na linguagem Java. A referencia feita a manipulacao de erros esta vinculada
a criacao de mais arquivos de teste que simulem possıveis erros e tambem ao tratamento
de eventos.
Referencias Bibliograficas
[Aho2007] Aho, A. V. (2007). Compiladores: Princıpios, tecnicas e ferramentas. Person,
segunda edicao.
[Armstrong2007] Armstrong, J. (2007). Pragmatic Programming in Erlang. Pragmatic
Bookshelf.
[Cesarini2009] Cesarini, F., T. S. (2009). Erlang Programming. O’Reilly.
[Deitel2010] Deitel, P. (2010). Java Como Programar. Pearson Prentice Hall, oitava edicao.
[Erlang2012a] Erlang (2012a). Array. Disponıvel na url:
<http://www.erlang.org/doc/man/array.html/>. Acesso em: 15/11/2012.
[Erlang2012b] Erlang (2012b). Yecc. Disponıvel na url:
<http://www.erlang.org/doc/man/yecc.html/>. Acesso em: 05/10/2012.
[Hubbard2004] Hubbard, J. (2004). Colecao Schaum - Programacao com Java. Bookman,
segunda edicao.
[Java2012] Java (2012). The Java Language Specification. Disponıvel na url:
<http://docs.oracle.com/javase/specs/jls/se7/html/index.html/>. Acesso em:
05/11/2012.
[Jython2012] Jython (2012). The Jython Project. Disponıvel na url:
<http://www.jython.org/>. Acesso em: 25/02/2012.
[Louden2004] Louden, K. C. (2004). Compiladores: princıpios e praticas. Thomson Pio-
neira.
REFERÊNCIAS BIBLIOGRÁFICAS 59
[Reia2012] Reia (2012). Reia Language. Disponıvel na url: <http://reia-lang.org/>.
Acesso em: 25/02/2012.
[Sebesta2011] Sebesta, R. W. (2011). Conceitos de Linguagens de Programacao. Bookman,
nona edicao.
[Upadhyaya2011] Upadhyaya, M. (2011). Simple calculator compiler using lex and yacc.
Apendice A
Codigos de Testes
Os codigos-fontes mencionados no desenvolvimento deste trabalho e outros estao presentes
no CD que acompanha esta monografia.
A.1 Estrutura dos Diretorios
• /jaraki
– /ebin - bytecodes dos .erl
– /include - definicao de constantes
∗ jaraki define.hrl
– /src - codigo-fonte do compilador
∗ ast.erl - interface com o analisador sintatico
∗ core.erl - interface para converter jAST em eAST
∗ file lib.erl - biblioteca para suportar manipulacao de arquivos
∗ gen ast.erl - funcoes auxiliares para montar nos da eAST
∗ gen erl code.erl - principal modulo do analisador semantico
∗ helpers.erl - funcoes auxiliares diversas
∗ jaraki.erl - interface com usuario para compilar .java
∗ jaraki exception.erl - modulo que trata erros de compilacao
∗ jaraki lexer.erl - analisador lexico gerado
∗ jaraki lexer.xrl - codigo fonte para o leex gerar o analisador lexico
∗ jaraki parser.erl - analisador sintatico gerado
Estrutura dos Diretórios 61
∗ jaraki parser.yrl - codigo fonte para o yecc gerar o analisador sintatico
∗ jaraki utils.erl - funcoes para auxiliar o desenvolvimento do Jaraki
∗ loop.erl - biblioteca para suportar lacos
∗ matrix.erl - biblioteca para suportar matrizes
∗ oo lib.erl - biblioteca para suportar orientacao a objetos
∗ random lib.erl - biblioteca para suportar o uso da classe Random
∗ st.erl - funcoes para gerenciar a tabela de sımbolos
∗ vector.erl - biblioteca para suportar vetores
– /java src - testes utilizados durante o desenvolvimento
– jk - script para executar .erl gerado
– jkc - script para compilar .java
– Makefile - Makefile para compilar o compilador
• /testes
– MatrizTeste.java - codigo em java que efetua a multiplicacao de 2 matrizes
– string1.erl - codigo em Erlang que apresenta a manipulacao de variaveis do tipo
String
– char1.erl - codigo em Erlang que apresenta a manipulacao de variaveis do tipo
char
– bubblesort.erl - codigo em Erlang gerado que implementa o metodo de ordenacao
bolha
– quicksort.erl - codigo em Erlang gerado que implementa o algoritmo quicksort
– matrizteste.erl - codigo em Erlang gerado que efetua a multiplicacao de 2 ma-
trizes
• /videos - simulacao de testes
– apresentacao tcc.pdf - apresentacao de defesa da monografia
– tese.pdf - monografia
top related