interpretador de linguagens de consulta relacionais

44
Interpretador de Linguagens de Consulta Relacionais Aluno: Andr´ e Suzuki Veiga Komatsu Orientador: Prof. Marcelo Finger ao Paulo - 2011

Upload: others

Post on 23-Oct-2021

3 views

Category:

Documents


0 download

TRANSCRIPT

Interpretador de Linguagens de Consulta

Relacionais

Aluno: Andre Suzuki Veiga KomatsuOrientador: Prof. Marcelo Finger

Sao Paulo - 2011

Sumario

I Parte Objetiva 3

1 Introducao 31.1 Motivacao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.2 Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.3 Organizacao da Monografia . . . . . . . . . . . . . . . . . . . . . 4

2 Linguagens Formais e Automatos 62.1 Alfabetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.2 Linguagens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.3 Linguagens Regulares . . . . . . . . . . . . . . . . . . . . . . . . 72.4 Automatos Finitos . . . . . . . . . . . . . . . . . . . . . . . . . . 82.5 Linguagens Livres de Contexto . . . . . . . . . . . . . . . . . . . 92.6 Arvores Sintaticas . . . . . . . . . . . . . . . . . . . . . . . . . . 102.7 Automatos com Pilha . . . . . . . . . . . . . . . . . . . . . . . . 12

3 Analisadores Sintaticos 143.1 Analisador Recursivo Descendente . . . . . . . . . . . . . . . . . 153.2 Analisador LL . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

3.2.1 Conflitos LL(1) . . . . . . . . . . . . . . . . . . . . . . . . 173.3 Analisador LR . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

4 O Interpretador de Consultas 204.1 As Linguagens de Consulta . . . . . . . . . . . . . . . . . . . . . 20

4.1.1 SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204.1.2 Algebra Relacional . . . . . . . . . . . . . . . . . . . . . . 214.1.3 Calculo Relacional de Tuplas e de Domınio . . . . . . . . 23

4.2 A Interpretacao das Consultas do Usuario . . . . . . . . . . . . . 254.3 A Traducao das Linguagens de Consulta . . . . . . . . . . . . . . 264.4 MySQL, Java e Swing . . . . . . . . . . . . . . . . . . . . . . . . 314.5 Principais Funcionalidades . . . . . . . . . . . . . . . . . . . . . . 324.6 A Interface Grafica . . . . . . . . . . . . . . . . . . . . . . . . . . 33

5 Resultados - O programa em funcionamento 37

6 Melhorias Possıveis 38

7 Bibliografia 40

II Parte Subjetiva 41

8 Desafios e Frustracoes 41

1

9 Disciplinas Relevantes 42

10 Conceitos Utilizados 42

11 Planos Futuros 43

12 Agradecimentos 43

2

Parte I

Parte Objetiva

1 Introducao

1.1 Motivacao

Banco de Dados (ou Base de Dados) e uma colecao de dados, organizada demodo a facilitar o armazenamento e acesso para programas que utilizem essesdados. Existem diversos modelos de organizacao desses dados, como modelosnavegacionais, hierarquicos, baseado em redes e orientados a objetos. O modelomais utilizado atualmente e o modelo relacional, proposto por Edgar F. Coddem 1970 [4]. Para permitir que diversas aplicacoes possam acessar esses dadossem precisar conhecer as estruturas envolvidas no seu armazenamento, surgiuum intermediario entre os dados e as aplicacoes, chamado Sistema Gerenciadorde Banco de Dados (SGBD). Um SGBD, alem de abstrair os dados para asaplicacoes, fornece varios servicos, como acesso concorrente aos dados, segurancae recuperacao em caso de falha.

Como todas as operacoes das aplicacoes sobre a estrutura de armazenamentodos dados passa pelo SGBD, e como os mais diversos tipos de aplicacoes po-dem estar interessadas em acessar esses dados, o acesso a eles e uniformizado,utilizando linguagens de consultas. Por ser a unica forma de acessar os dados,e importante aprender como utilizar essas linguagens para expressar consultasque obtenham o resultado esperado.

Linguagens de consulta geralmente sao parecidas com linguagens de pro-gramacao de alto nıvel, mas com uma menor expressividade. Elas possuemapenas a expressividade necessaria para realizar consultas ao SGBD. Podemosencarar os dados em um banco de dados de varias formas: uma colecao de tu-plas, uma colecao de colunas, uma colecao de tabelas, uma colecao de objetos,etc. Dessa forma, dependendo do SGBD e do modelo utilizado, a linguagemde consulta muda, podendo ser radicalmente diferente de outras linguagens deconsulta que realizam as mesmas tarefas. Dessa forma, assim como em pro-gramacao, nao e tao importante aprender uma linguagem de consulta especıfica:o mais importante e aprender como escrever consultas de modo geral. De possedesse conhecimento, e possıvel, sem muitas dificuldades, realizar consultas nasmais diversas linguagens.

1.2 Objetivos

O principal objetivo desse trabalho e a implementacao de um Interpretador deLinguagens de Consultas Relacionais, que fornecera ao usuario a possibilidadede realizar consultas em quatro linguagens diferentes: SQL, Algebra Relacional,Calculo Relacional de Domınio e Calculo Relacional de Tuplas. Todas essas lin-guagens sao baseadas em logica de predicados de primeira ordem e algebra de

3

conjuntos. Alem disso, Algebra Relacional e Calculo Relacional sao equivalentesem se tratando de expressividade. SQL e mais expressivo que as outras lingua-gens, devido as funcoes de agregacao. SQL e Algebra Relacional sao linguagensprocedurais, enquanto que o Calculo Relacional e uma linguagem declarativa.Como essas linguagens possuem caracterısticas diferentes, o seu aprendizadocontribui para um melhor entendimento sobre a logica envolvida na realizacaode uma consulta.

O interpretador usara o MySQL para a execucao das consultas e para oarmazenamento dos dados dos usuarios. O usuario escrevera uma consulta noprograma e essa consulta sera traduzida para a variante SQL utilizada peloMySQL. Essa consulta traduzida e entao passada ao MySQL, que a executae devolve o resultado ao programa. Dessa forma, o programa consiste de tresmodulos principais: Interface Grafica, por onde o usuario interage com o pro-grama; gerenciador de conexao com o MySQL, que realiza a conversa entreo programa e o MySQL; e os tradutores, que transformam as linguagens deconsultas utilizadas pelo usuario em consultas SQL.

Uma alternativa ao programa implementado neste trabalho e o WinRDBI[1], utilizado atualmente na disciplina de Sistemas de Bancos de Dados do Ba-charelado de Ciencia da Computacao do IME-USP. Esse programa possui diver-sos problemas, como erros de leitura de arquivos de dados, lentidao na execucaodas consultas, mensagens de erros crıpticas no editor de consultas (onde asmensagens devem claras, pois o usuario esta utilizando o programa para apren-der como realizar consultas), alem de ser codigo fechado. Portanto, o objetivodeste trabalho e fazer algo melhor que o WinRDBI, para poder ser utilizado nadisciplina de Bancos de Dados mencionada anteriormente.

1.3 Organizacao da Monografia

Como o tradutor de linguagens e a parte mais complexa da aplicacao, essamonografia entrara em detalhes na teoria de analise sintatica. Por causa disso,esse texto fara um resumo sobre topicos de Linguagens Formais e Automatos.Esse texto esta organizado da seguinte forma:

• Linguagens Formais e Automatos: resumo sobre conceitos basicossobre linguagens formais e automatos. Fala sobre alfabetos, linguagense operacoes sobre linguagens, linguagens regulares e expressoes regulares,linguagens livres de contexto e automato com pilha, arvore sintatica.

• Analise sintatica: apresenta as tecnicas mais comuns sobre analise sintatica:analisador descendente recursivo, analisadores LL e LR.

• O Interpretador de Consultas: explica resumidamente as tecnologiasutilizadas, as principais funcionalidades do programa e como ele imple-menta essas funcionalidades.

• Resultados: apresenta os resultados, atraves do funcionamento do pro-grama.

4

• Melhorias: apresenta o que nao pode ser implementado e ideias paraexpandir o programa. Como ele e codigo livre, espera-se que no futuroessas melhorias sejam implementadas.

5

2 Linguagens Formais e Automatos

Para entender o funcionamento do tradutor de consultas utilizado pelo pro-grama, e necessario conhecer um pouco sobre a teoria de analise sintatica. Porsua vez, para entender essa teoria, e necessario conhecer as definicoes e resulta-dos basicos da teoria de linguagens formais e automatos. Essa secao apresentaessas definicoes basicas, comecando com alfabetos e linguagens, passando paraautomatos e terminando com linguagens livres de contexto, automatos com pi-lha e arvores sintaticas, as estruturas produzidas pelos analisadores sintaticos.Esta secao e, basicamente, um resumo dos capıtulos 1, 2 e 3 de [2].

2.1 Alfabetos

Um alfabeto nada mais e do que um conjunto finito nao vazio. Como essa de-finicao e muito geral, uma definicao alternativa mais utilizada define um alfabetocomo sendo um conjunto nao vazio de sımbolos, onde esses sımbolos podem serqualquer coisa, mas geralmente sao letras ou numeros.

Uma palavra w em um alfabeto Σ e uma sequencia de sımbolos daquelealfabeto. Uma palavra e representada justapondo os sımbolos que a formam.Por exemplo, para o alfabeto Σ = {a, b, c, ..., z}, uma palavra sobre esse alfa-beto pode ser, por exemplo, abracadabra, que e a justaposicao dos sımbolosa, b, c, d, r. Uma palavra pode ter um numero qualquer de sımbolos (seu tama-nho pode ser arbitrario). Em especial, ela pode ter tamanho nulo, e chamamosessa palavra de palavra vazia, denotada por λ. O conjunto de todas as palavrassobre um alfabeto Σ, incluindo a palavra vazia, e denotada por Σ∗.

Podemos definir diversas operacoes envolvendo palavras. Uma delas e aconcatenacao: a concatenacao das palavras x e y pertencentes a Σ∗, denotadapor x ◦ y, e a palavra x seguida da palavra y. Formalmente, w = x ◦ y se esomente se |w| = |x|+|y|, w(j) = x(j) para j = 1, ..., |x|, e w(|x|+j) = y(j) paraj = 1, ..., |y|. A concatenacao e associativa: vale a igualdade (wx)y = w(xy)para qualquer palavra x, y, w ∈ Σ∗.

2.2 Linguagens

Uma linguagem L e definida como sendo um subconjunto de Σ∗, onde Σ e umalfabeto. Exemplos de linguagens sao Σ, ∅,Σ∗ etc.

Linguagens sao conjuntos, portanto podemos lidar com linguagens da mesmaforma que lidamos com conjuntos. Em especial, e possıvel usar as operacoes deconjuntos (∪,∩, etc.). Alem disso, existem operacoes definidas especificamentepara linguagens. Uma delas e a concatenacao de linguagens: se M e N saoduas linguagens sobre Σ (ou seja, contem palavras formadas por sımbolos deΣ), entao a concatenacao L = M ◦N , ou L = MN , e definida como

L = {w ∈ Σ∗ | w = x ◦ y para algum x ∈M e u ∈ N}

Uma outra operacao importante sobre linguagens e a estrela de Kleene: aestrela de Kleene de uma linguagem L, denotada por L∗, e o conjunto obtido a

6

partir da concatenacao de zero ou mais palavras de L, ou seja,

L∗ = {w ∈ Σ∗ | w = w1 ◦ ... ◦ wk para algum k ≥ 0 e algum w1, ..., wk ∈ L}

O conjunto Σ∗, visto anteriormente, nada mais e do que a linguagem resultanteda estrela de Kleene de Σ.

Uma notacao muito comum e L+ para representar LL∗, o menor conjuntoque contem L e todas as concatenacoes de palavras de L.

2.3 Linguagens Regulares

Como linguagens sao conjuntos, um jeito de representar uma linguagem e listartodos os seus elementos. Mas se a linguagem e resultado da estrela de Kleene deoutra linguagem, entao ela possui infinitos elementos, e esse metodo de repre-sentacao nao funciona. Para contornar essa situacao, podemos usar expressoesregulares.

Definicao. uma expressao regular sobre um alfabeto Σ e definida da seguinteforma:

1. ∅ e cada membro de Σ e uma expressao regular

2. se α e β sao expressoes regulares, entao (αβ) e uma expressao regular

3. se α e β sao expressoes regulares, entao (α ∪ β) e uma expressao regular

4. se α e uma expressao regular, entao α∗ e uma expressao regular

5. nada alem de 1 ate 4 e uma expressao regular

Se ∪ e ∗ forem interpretados como uniao de conjuntos e estrela de Kleene,respectivamente, alem de interpretar a justaposicao de expressoes como sendoa concatenacao, entao toda expressao regular representa uma linguagem.

A linguagem representada por uma expressao regular e definida atraves deuma funcao: se α e uma expressao regular qualquer, entao L(α) e a linguagemrepresentada por α. Essa funcao e definida da seguinte forma:

1. L(∅) = ∅ e L(a) = a para cada a ∈ Σ

2. Se α e β sao expressoes regulares, entao L((αβ)) = L(α)L(β)

3. Se α e β sao expressoes regulares, entao L((α ∪ β)) = L(α) ∪ L(β)

4. Se α e uma expressao regular, entao L(α∗) = L(α)∗

O conjunto de todas as linguagens sobre um alfabeto Σ possıveis de seremrepresentadas por expressoes regulares e o conjunto das linguagens regulares.Um resultado importante e que nem todas as linguagens sao regulares, ou seja,nem todas as linguagens podem ser representadas por expressoes regulares. Oexemplo canonico desse fato e a linguagem anbn:

L = {anbn | n ≥ 0}

7

2.4 Automatos Finitos

Automatos, ou maquinas de estados, sao dispositivos de reconhecimento de lin-guagens. Seu funcionamento e analogo a maquinas: aceitam uma palavra comoentrada e, como resultado, indicam se essa palavra faz parte da linguagem emquestao. Automatos representam modelos de computacao: eles possuem umaunidade central, alguns tipos possuem memoria, etc.

Esses dispositivos contem uma fita de entrada dividida em celulas, e a palavrade entrada ocupa essa fita, um sımbolo por celula. Internamente, os automatospossuem um conjunto de estados e regras de transicoes entre estados; o dispo-sitivo sempre se encontra em um estado, e de acordo com o sımbolo lido nomomento, pode mudar de estado, seguindo essas regras. Antes de ler o primeirosımbolo da entrada, o automato se encontra no chamado estado inicial. O seufuncionamento consiste da leitura de sımbolos e mudanca de estado levando emconta o sımbolo lido. No momento em que os sımbolos se esgotam, verifica-se seo automato se encontra em um dos estados finais: se sim, a palavra foi aceita;se nao, a palavra foi rejeitada, e nao pertence a linguagem reconhecida peloautomato.

Formalmente, temos o seguinte:

Definicao. um automato determinıstico finito e uma quıntupla M = (K,Σ, δ, s, F )onde

• K e um conjunto finito de estados,

• Σ e um alfabeto,

• s ∈ K e o estado inicial,

• F ⊆ K e o conjunto de estados finais, e

• δ : K × F → K e a funcao de transicao

A funcao de transicao controla o comportamento do automato: se o automatose encontra no estado q e le um sımbolo s da entrada, entao ele ira para o estadoδ(q, s) ∈ K. Como o automato e determinıstico, existe no maximo um estadopossıvel como resultado.

Em um automato nao determinıstico, δ(q, s) pode resultar em mais de umestado. O automato escolhe um dos estados e continua o processamento daentrada. Se a linguagem nao for aceita, ele volta ate esse momento, e esco-lhe um dos estados nao percorridos anteriormente. Dessa forma, ele acabatentando todas as possibilidades. Alem disso, existem transicoes que nao con-somem sımbolos da entrada; essas transicoes sao equivalentes a transicoes queconsomem λ. Se o automato se encontra em um estado que possui uma dessastransicoes, ele pode escolher ler um sımbolo da entrada ou mudar de estadousando essa transicao vazia.

Formalmente, temos:

Definicao. um automato finito nao-determinıstico e uma quıntupla M = (K,Σ,∆, s, F ),onde

8

• K e um conjunto finito de estados,

• Σ e um alfabeto,

• s ∈ K e o estado inicial

• F ⊆ K e o conjunto de estados finais

• ∆ e a relacao de transicao, um subconjunto de K × (Σ ∪ {λ})×K

Um automato finito determinıstico e um tipo de automato finito nao de-terminıstico, onde nao existem transicoes que aceitam λ como entrada e cadaestado pode ir a apenas um outro estado. Mas apesar disso, automato nao-determinısticos nao sao mais expressivos que automatos determinısticos; ambosreconhecem as mesmas linguagens. De fato, existem algoritmos para converterum automato nao-determinıstico em um automato determinıstico.

Teorema. Para cada automato finito nao-determinıstico, existe um automatofinito determinıstico que reconhece a mesma linguagem.

Prova. Demonstracao encontrada em [2].

Automatos finitos determinısticos sao importantes, ja que eles sao equiva-lentes as expressoes regulares:

Teorema. Uma linguagem e regular se e somente se ela e reconhecida por umautomato finito determinıstico.

Prova. Demonstracao encontrada em [2].

2.5 Linguagens Livres de Contexto

Em 2.3, falamos que existem linguagens que nao sao regulares. Essa secaoexplica um pouco sobre as linguagens livres de contexto, classe que englobaalgumas linguagens que nao sao regulares.

Podemos encarar expressoes regulares como geradores de linguagens. A ex-pressao a∗b pode ser lida como: gere zero ou mais a’s, e depois gere um b. Aqui,estudaremos um novo tipo de geradores de linguagens, as gramaticas livres decontexto. Esses geradores possuem mais conhecimento sobre a estrutura daspalavras presentes na linguagem.

Definicao. Uma gramatica livre de contexto G e uma quadrupla (V,Σ, R, S),onde

• V e um alfabeto

• Σ, o conjunto de terminais, e um subconjunto de V

• R, o conjunto de regras, e um subconjunto finito de (V − Σ)× V ∗

• S, o sımbolo inicial, e um elemento de V − Σ

9

Assim como no caso das linguagens regulares, uma linguagem L e uma lin-guagem livre de contexto se L = L(G), onde G e uma gramatica livre de con-texto.

Os elementos de V − Σ sao chamados nao-terminais. Para todo A ∈ V − Σe u ∈ V ∗, escrevemos A⇒G u sempre que (A, u) ∈ R.

Qualquer sequencia da forma

w0 ⇒G w1 ⇒G . . .⇒G wn

e chamada de derivacao em G de wn a partir de w0.Como exemplo de gramatica livre de contexto, temos a gramatica que gera

a linguagem anbn:

S → aSb

S → λ

Uma possıvel derivacao da palavra aaabbb e:

S ⇒ aSb⇒ aaSbb⇒ aaaSbbb⇒ aaaλbbb = aaabbb

O exemplo acima mostra que algumas linguagens livres de contexto nao saoregulares. Alem disso, temos o seguinte teorema:

Teorema. Todas as linguagens regulares sao livres de contexto.

Prova. Demonstrado varias vezes em [2], comecando pela pagina 119.

Com isso, a classe das linguagens regulares esta estritamente contida naclasse das linguagens livres de contexto.

2.6 Arvores Sintaticas

Uma palavra w ∈ L(G) pode ter muitas derivacoes em G. Por exemplo, nalinguagens dos parenteses balanceados,

S → λ

S → SS

S → (S)

considere as duas derivacoes a seguir para a palavra ()():

S ⇒ SS ⇒ (S)S ⇒ ()S ⇒ ()(S)⇒ ()()

S ⇒ SS ⇒ S(S)⇒ S()⇒ (S)()⇒ ()()

Apesar de parecer que essas duas derivacoes sao diferentes, elas sao equi-valentes, no sentido que as regras usadas sao as mesmas, e essas regras sao

10

utilizadas nos mesmos lugares. A unica diferenca esta na ordem de aplicacaodessas regras. Podemos representar ambas as derivacoes da seguinte forma:

S

S

( S

λ

)

S

( S

λ

)

Chamamos esse diagrama de arvore sintatica. No diagrama, as folhas contemos terminais, e os nos que nao sao folhas contem as regras gramaticais que fo-ram expandidas. A concatenacao dos terminais presentes nas folhas dessa arvoreforma a palavra que e resultado da derivacao. Uma regra gramatical e expan-dida em um ou mais elementos, e esses elementos se tornam seus filhos na arvoresintatica. No exemplo acima, a diferenca entre as duas derivacoes esta na ordemem que expandimos a regra de segundo nıvel: no primeiro caso, escolhemos ex-pandir a regra da esquerda, enquanto que no segundo caso, escolhemos expandir,primeiramente, a regra da direita.

Arvores sintaticas servem para condensar todas as derivacoes que diferemapenas na ordem de expansao de suas regras em uma representacao unica. Logo,no exemplo acima, as duas derivacoes sao equivalentes. Apesar disso, existemlinguagens com palavras que possuem mais de uma arvore sintatica. Considerea seguinte gramatica, retirada de [5], onde A e o sımbolo inicial:

A→ A+A

A→ A−AA→ a

Temos a seguir duas derivacoes para a palavra a+ a+ a:

1. A⇒ A+A⇒ a+A⇒ a+A+A⇒ a+ a+A⇒ a+ a+ a

2. A⇒ A+A⇒ A+ a⇒ A+A+ a⇒ A+ a+ a⇒ a+ a+ a

representadas pelas arvores

1. A

A

a

+ A

A

a

+ A

a

2. A

A

A

a

+ A

a

+ A

a

Essas duas arvores sintaticas sao bem diferentes. Portanto, para a palavraa + a + a, existe duas arvores sintaticas, ou seja, duas derivacoes nao equiva-lentes. Nesse caso, dizemos que a gramatica e ambıgua. Quando falarmos de

11

analisadores sintaticos, veremos que uma arvore sintatica representa o ’signifi-cado’ da palavra e, portanto, em termos praticos, gramaticas ambıguas possuempalavras com mais de um ’significado’, o que as tornam indesejaveis.

Como nao queremos utilizar uma linguagem ambıgua em nossas aplicacoes,seria desejavel a existencia de um algoritmo que decide se uma linguagem eambıgua. Infelizmente, esse problema e indecidıvel. Felizmente, podemos, namaioria dos casos, transformar uma gramatica ambıgua em uma outra gramaticaque nao e ambıgua. A gramatica do exemplo acima e equivalente a seguintegramatica nao ambıgua:

A→ A+ a

A→ A− aA→ a

Porem, existem linguagens em que isso nao e possıvel: todas as gramaticasque as descrevem sao ambıguas. Essas linguagens sao chamadas de inerente-mente ambıguas.

2.7 Automatos com Pilha

Como vimos anteriormente, automatos finitos estao intimamente ligados comlinguagens regulares. Por conta disso, eles nao conseguem reconhecer lingua-gens livres de contexto. Analisando a linguagem anbn, percebemos que umreconhecedor de palavras dessa linguagem deve, de alguma forma, guardar asletras que ja leu, para utilizar futuramente (dessa forma, ele conseguiria contaro numero de a’s e o numero de b’s presentes na palavra). Para linguagens livresde contexto, essa ’memoria’ se traduz em uma pilha, uma estrutura de dadosem que o primeiro elemento que entra e o ultimo que sai (ao contrario de umafila, onde o primeiro que entra e o primeiro que sai).

Definicao. Um automato com pilha (ou a pilha) e uma sextupla M = (K,Σ,Γ,∆, s, F ),onde

• K e um conjunto de estados

• Σ e o alfabeto dos sımbolos de entrada

• Γ e o alfabeto dos sımbolos na pilha

• s ∈ K e o estado inicial

• F ⊆ K e o conjunto de estados finais

• ∆ e um subconjunto finito de (K × (Σ ∪ λ)× Γ∗)× (K × Γ∗)

Nesse tipo de automato, uma transicao deve levar em conta o estado atual,o sımbolo lido e o sımbolo no topo da pilha. Na definicao, essa transicao e umdos elementos do conjunto ∆.

12

Um teorema bem importante relaciona automatos com pilha e linguagenslivres de contexto:

Teorema. A classe de linguagens aceita pelo automato com pilha e a classe daslinguagens livres de contexto.

Prova. A prova desse teorema e longa e nao sera mostrada nesse texto. Elapode ser encontrada em [2].

13

3 Analisadores Sintaticos

Um analisador sintatico (ou parser) e um algoritmo que verifica se uma pa-lavra pertence a uma determinada linguagem e, em caso afirmativo, constroia arvore sintatica dessa palavra. Existem diversas formas de construir essaarvore sintatica e, portanto, existem diversos tipos de analisadores sintaticos.Em especial, existe duas grandes classes de analisadores: top-down, que cons-troem a arvore sintatica da raiz ate as folhas, e bottom-up, que constroem aarvore sintatica das folhas ate a raiz. Alem disso, todos os analisadores uti-lizados na pratica sao determinısticos, ou seja, cada sımbolo da entrada lidoavanca o processo. Isso diminui um pouco o conjunto das linguagens que po-dem ser analisadas, mas garante que o analisador tera um desempenho bom, aocontrario do analisador nao determinıstico. Um analisador determinıstico pos-sui complexidade linear no tamanho da entrada. Alem do fator complexidade,uma gramatica determinıstica, por consequencia, tambem e uma gramatica nao-ambıgua, ja que nao existira dois caminhos pelo automato que correspondem amesma palavra.

Um grande problema enfrentado pelos analisadores e a existencia de gramaticasambıguas, ou seja, de gramaticas que possuem palavras com mais de uma arvoresintatica. Como os programas que utilizam analise sintatica inferem o signifi-cado da palavra a partir da sua arvore sintatica, uma palavra que possui maisde uma arvore sintatica e uma palavra que possui mais de um significado. Napratica, isso se traduz em uma maior complexidade da aplicacao, ja que ela devedecidir o significado da palavra utilizando outras tecnicas. Por conta disso, asgramaticas utilizadas na pratica nao sao ambıguas:

Definicao. Seja G uma gramatica livre de contexto que descreve a linguagemL. Entao, G nao e ambıgua se e somente se toda palavra l ∈ L possui apenasuma arvore sintatica com regras de G.

Como existem diversas maneiras de montar a arvore sintatica de uma deter-minada palavra, e possıvel que um analisador nao consiga montar essa arvore,enquanto que um outro tipo de analisador obtenha essa arvore sem problemas.Dessa forma, dentre as linguagens livres de contexto nao ambıguas, temos diver-sas classes de linguagens (nao disjuntas) que correspondem ao tipo de analisadorque as reconhece. Alguns exemplos:

• Linguagens LL: sao linguagens reconhecidas por analisadores recursi-vos descendentes ou analisadores LL; esses analisadores montam a arvoresintatica de cima para baixo (top-down), obtendo a arvore sintatica quecorresponde a derivacao mais a esquerda (ou seja, que sempre expandeo nao terminal mais a esquerda da derivacao). Alem disso, eles leem aentrada da esquerda para a direita. Corresponde a montar a arvore napre-ordem.

• Linguagens LR: sao linguagens reconhecidas por analisadores LR, SLR,LR(k) etc. Eles leem a entrada da esquerda para a direita, montando a

14

arvore que corresponde a derivacao mais a direita. Corresponde a montara arvore na pos-ordem.

Vamos agora estudar o funcionamento de alguns tipos de analisadores exis-tentes. Essa secao foi fortemente baseada nos capıtulos 1 e 2 de [3].

3.1 Analisador Recursivo Descendente

Esse analisador monta a arvore sintatica da raiz para as folhas. A analise erealizada da seguinte forma:

1. A raiz corresponde ao sımbolo inicial;

2. Se o processo esta em um no que corresponde a um nao-terminal, o ana-lisador deve expandir esse no com a derivacao correspondente a esse nao-terminal na gramatica, levando em conta os sımbolos da entrada. Essa ex-pansao escolhe uma das derivacoes e adiciona os terminais e nao-terminaisdessa derivacao a arvore, sendo que esses sımbolos sao filhos do nao-terminal sendo analisado.

3. Apos a expansao, o analisador expande todos os filhos adicionados aarvore.

Como podemos ver, o processo e recursivo: expandimos um no, adicionandofilhos a ele, e depois expandimos os seus filhos. Dessa forma, se precisamosexpandir varios irmaos na arvore, devemos expandir o primeiro e guardar osoutros irmaos para serem expandidos mais tarde. Na pratica, a forma maisfacil de implementar esse processo e usando uma funcao para cada regra dagramatica. Com isso, cada expansao corresponde a uma chamada de funcao,e portanto, se quisermos expandir varios irmaos, podemos expandir o primeirochamando sua funcao correspondente e, quando a funcao chamada devolver ocontrole do processo, chamar a funcao para o segundo irmao, sucessivamenteate acabar os nos a serem expandidos, momento esse que faz com que a funcaodevolva o controle a funcao que a chamou.

Da forma descrita anteriormente, esse analisador e bem facil de ser imple-mentado, sendo composto de uma serie de funcoes. Em contrapartida, existeum grande numero de linguagens nao ambıguas que nao podem ser analisadaspor um analisador descendente recursivo. Alem disso, esse analisador nao e taoeficiente: se a arvore sintatica da entrada sendo analisada possuir uma alturaelevada, o espaco gasto na pilha de chamadas tambem e elevado.

3.2 Analisador LL

Esse tipo de analisador representa uma melhoria em relacao ao analisador re-cursivo. Sempre que temos um nao-terminal A e um sımbolo c na entrada, oanalisador recursivo verifica as regras da gramatica para decidir a expansao a serrealizada. Se nenhuma das derivacoes possui c como primeiro elemento, ele deve

15

obter o conjunto de todos os sımbolos que aparecem primeiro nas derivacoes deA e verificar se algum deles possui c como primeiro elemento. Esse processose repete ate que encontramos a regra que contem c como primeiro elemento,e entao voltamos no processo, ate chegarmos a A. Como sabemos o ’caminho’que contem c como primeiro elemento, escolhemos a derivacao de A que segueesse ’caminho’. Mas note que esse processo e realizado sempre que o analisadorencontra A como nao-terminal e c como primeiro sımbolo da entrada.

O analisador LL monta uma tabela que corresponde a esse processo, con-tendo a derivacao a ser escolhida para cada combinacao de nao-terminal daarvore e terminal da entrada. Logo, se o processo de analise quer expandiro nao-terminal A levando em conta o sımbolo c da entrada, o analisador LLconsulta a tabela na posicao correspondente (digamos, T [A][c]), e realiza a ex-pansao contida nessa posicao. Dessa forma, o processo e mais eficiente do queno caso do analisador recursivo.

Alem disso, da forma como essa pre-computacao das expansoes e realizada,o analisador LL e capaz de analisar linguagens que nao eram possıveis de seremanalisadas pelo analisador recursivo.

Para montar essa tabela de expansoes, o analisador deve obter o conjuntoFIRST. Cada derivacao A → αBβ corresponde a uma parte da entrada. Por-tanto, essa expansao possui um primeiro nao terminal, correspondente a folhada arvore sintatica que e alcancada a partir de A, sempre escolhendo a subarvoremais a esquerda. Esse terminal e o elemento first da derivacao. Portanto, cadaderivacao possui um elemento first, e o conjunto de todos os elementos first for-mam o conjunto FIRST. Se o processo de analise quer expandir A e a entradapossui, como primeiro sımbolo, o elemento first da derivacao acima, entao sa-bemos que o analisador deve utilizar A → αBβ. Portanto, a tabela tera, paracada nao-terminal A e cada terminal c, a derivacao de A que possui c como seuelemento first.

Se a gramatica nao possui regras vazias, do tipo A → λ, entao o processodescrito acima e suficiente para montar a tabela. Mas regras vazias nao possuemelementos first. Logo, se apenas usarmos o conjunto FIRST para montar atabela, entao regras vazias nunca serao escolhidas para expansao. Mas como elasestao presentes na gramatica, deve existir um conjunto de palavras que possuemuma expansao de uma regra vazia em suas derivacoes, como a palavra ()() noexemplo com a linguagem dos parenteses balanceados visto anteriormente. Paraescolher uma regra desse tipo, devemos levar em conta os elementos first dosterminais e nao terminais que a seguem na gramatica. Por exemplo, na seguintegramatica

S → αBβ

B → γ

B → λ

para decidirmos entre as duas possibilidades de derivacao a partir de B, devemosverificar se o primeiro sımbolo na entrada e FIRST (β) ou γ. Se for γ, entao

16

escolhemos a primeira derivacao; caso contrario, escolhemos a segunda. Dessaforma, devemos montar, para cada nao-terminal que possui uma regra vazia,o conjunto de terminais que podem seguir esse nao-terminal. Esse conjunto sechama FOLLOW. Com isso, se o processo esta no nao-terminal A que possuiuma regra vazia e o primeiro sımbolo da entrada e c, e c esta no conjuntoFOLLOW de A, entao o processo escolhe, como expansao para A, a regra A→ λ.

Em tudo o que foi dito ate agora, o analisador considera apenas o primeirosımbolo da entrada. Esse tipo de analisador e denominado LL(1). Se o ana-lisador considera o primeiro e o segundo sımbolo da entrada para realizar asexpansoes, temos um analisador LL(2), e assim por diante. Ainda e possıvelconstruir um analisador que considere um numero variavel de sımbolos da en-trada. Esse numero depende apenas da regra gramatical sendo testada. Essetipo de analisador e chamado de analisador LL(k), onde k e o valor maximode sımbolos considerados. Quanto maior esse valor, maior o numero de lingua-gens possıveis de serem analisadas, mas maior e a dificuldade de implementaresse analisador. Na pratica, analisadores LL sao gerados por um programa querecebe, como entrada, a gramatica livre de contexto. Esse programa monta atabela de expansoes e o automato com pilha que utiliza a tabela para montar aarvore sintatica.

3.2.1 Conflitos LL(1)

Nem todas as linguagens nao ambıguas podem ser analisadas por um analisa-dor LL. Nessa secao, vamos estudar as principais razoes que impedem essaslinguagens de serem analisadas por um analisador LL(1).

Conflito FIRST/FIRST: Dada uma regra gramatical N , existem duas de-rivacoes N → A e N → B, onde FIRST (N → A) = FIRST (N → B). Nessecaso, o analisador nao consegue decidir qual derivacao utilizar na expansao, jaque se c = FIRST (N → A) = FIRST (N → B), entao temos duas possibilida-des de preencher a tabela na posicao T [N ][c].

Conflito FIRST/FOLLOW: Dada uma regra gramatical N , existe umaderivacao N → A e a derivacao vazia N → λ, sendo que FIRST (N → A) ∈FOLLOW (N). Nesse caso, o analisador nao consegue decidir entre N → A eN → λ se o primeiro elemento da entrada for o elemento que cause o conflito.

Recursao a esquerda: Dada uma regra N , existe uma derivacao N → NM .Nesse caso, FIRST (N → NM) = FIRST (N), e essa derivacao possui conflitoFIRST/FIRST com todas as derivacoes de N .

Geralmente, esses conflitos podem ser eliminados modificando a gramaticacom uma das tecnicas a seguir:

Fatoracao: No conflito FIRST/FIRST, podemos fatorar as derivacoes quecausam o conflito, criando uma nova regra para elas. Por exemplo,

17

S → ABC

S → AD

S → E

e fatorada em

S → AF

S → E

F → BC

F → D

Substituicao: Consiste em substituir uma regra dentro da outra, para eli-minar conflitos FIRST/FOLLOW. Basicamente, e o inverso da fatoracao. Porexemplo, a gramatica

S → pAq

A→ a

A→ Bc

A→ λ

B → q

possui um conflito FIRST/FOLLOW para a regra A e o terminal q, quandoconsideramos A dentro de pAq, ja que nao sabemos se usamos A → λ ou A →Bc, ja que FIRST (B → q) = q, o que resulta em FIRST (A→ Bc) = q. Parasituacoes como essa, a substituicao resolve o conflito:

S → paq

S → pBcq

S → pq

B → q

Note que a gramatica acima possui, como resultado, um conflito FIRST/FIRST,que deve ser resolvido utilizando fatoracao. Linguagens que nao podem ser ana-lisadas com analisadores LL geralmente possuem essa propriedade: sempre queresolvemos um conflito de um tipo, o resultado contem um conflito de outrotipo, que quando resolvido faz aparecer o conflito original. Alem disso, noteque os conflitos acima so existem se o analisador considera apenas o primeirosımbolo da entrada. Se ele considerasse os dois primeiros sımbolos, por exemplo,a gramatica original nao possui conflitos.

18

Remocao de Recursao a Esquerda: Essa tecnica e um pouco mais compli-cada, e o seu resultado e uma gramatica bem diferente da original. Isso porqueexistem diversos tipos de recursao:

• Direta: a gramatica possui regras da forma N → Nαβ

• Indireta: uma gramatica com uma sequencia de regras do tipo

N →M

M → O

O → P

P → N

• Oculta: uma gramatica com regras do tipo

N →MN

M → α

M → λ

3.3 Analisador LR

O analisador LR monta a arvore sintatica das folhas ate a raiz, fazendo o inversodo analisador LL: o analisador possui a sequencia de sımbolos da entrada edeseja saber a regra que foi derivada para gerar a sequencia.

Como o interpretador utiliza analisadores LL para a traducao das consultas,esse texto nao entrara em muitos detalhes sobre os analisadores LR.

19

4 O Interpretador de Consultas

O Interpretador de Consultas e um programa que age como intermediario entreo usuario e o MySQL. O programa permite que o usuario edite dados presentesno banco de dados, adicione ou remova dados, crie ou apague bancos de da-dos, realize consultas em 4 linguagens diferentes e visualize o resultado dessasconsultas. A seguir, explicaremos como o programa realiza essas tarefas.

4.1 As Linguagens de Consulta

As linguagens de consultas suportadas pelo programa sao:

• SQL

• Algebra Relacional

• Calculo Relacional de Domınio

• Calculo Relacional de Tuplas

A descricao das linguagens de consulta e baseada nos capıtulos 6 e 8 de [4].

4.1.1 SQL

SQL e uma linguagem de consultas relacionais desenvolvida pela IBM para sera linguagem de consulta do SGBD SYSTEM R. Originalmente, a linguagemera chamada SEQUEL (Structured English QUEry Language), mais tarde setornando SQL (Structured Query Language) [4].

A linguagem possui muitos recursos, tanto para manipulacao de dados (DML- Data Manipulation Language) como para a definicao de dados (DDL - DataDefinition Language). Por conta disso, SQL e a linguagem mais utilizada emsistemas de bancos de dados. Uma consulta padrao em SQL possui a forma

SELECT <atributos>

FROM <tabelas>

[WHERE <condic~oes>]

[GROUP BY <atributos>]

[HAVING <condic~oes>]

[ORDER BY <atributos>]

O interpretador suporta apenas algumas funcionalidades da DML. E impor-tante notar que SQL nao e completamente relacional, pois a linguagem permiteque relacoes contenham varias copias das mesmas tuplas.

Uma funcionalidade que torna SQL mais expressiva que as outras linguagensde consulta sao as funcoes agregadas. Essas funcoes, como min, max, avg, sum,count, agregam tuplas do resultado e realizam operacoes sobre essas tuplas.Por exemplo, a funcao agregada sum() recebe uma coluna do resultado como

20

parametro e soma os valores dessa coluna em todas as tuplas da relacao. Essetipo de operacao nao e possıvel de ser realizada em algebra relacional, porexemplo. No interpretador, apenas SQL possui essas funcoes.

4.1.2 Algebra Relacional

A algebra relacional e o conjunto de operacoes basicas para a manipulacao dedados no modelo relacional. Atraves dessas operacoes, o usuario e capaz deexpressar requisicoes de dados. O resultado dessas requisicoes sao relacoes,formadas a partir de relacoes presentes no banco de dados. Desse modo, aalgebra relacional e fechada no conjunto das relacoes.

As operacoes da algebra relacional podem ser divididas em dois grupos:operacoes sobre conjuntos (uniao, interseccao, diferenca, produto cartesiano) eoperacoes relacionais (select, project, join).

select A operacao select filtra as tuplas de uma relacao, utilizando um con-junto de condicoes. A sintaxe basica dessa operacao e:

σ<C>(< R >)

onde < C > e uma condicao booleana (simples ou complexa) e < R > e umarelacao. Por exemplo, se quisermos todos os empregados que ganham mais de10000 reais, podemos expressar essa consulta da seguinte forma (supondo queos dados dos empregados estao presentes na relacao Empregado):

σsalario>10000(Empregado)

O resultado de uma operacao select possui os mesmos atributos da relacaosofrendo a operacao. Alem disso, como a Algebra Relacional e fechada dentrodo conjunto das relacoes, a relacao R pode ser tanto uma relacao comum comouma expressao em algebra relacional.

project A operacao project seleciona certos atributos de uma relacao, des-cartando os outros atributos. O resultado de uma projecao geralmente possui omesmo numero de elementos da relacao original, salvo casos em que elementossao descartados devido a repeticoes. A sintaxe basica da operacao e:

π<A>(< R >)

onde < A > e uma lista de atributos e < R > e uma relacao. Por exemplo, sequisermos projetar o nome e o salarios de cada empregado da relacao Empregado,podemos escrever essa consulta da seguinte forma:

πnome, salario(Empregado)

21

rename A operacao rename nao modifica as tuplas da relacao, apenas reno-meia os atributos. A sintaxe basica dessa operacao e:

ρ(B1,B2,...,Bn)(< R >)

onde B1, B2, . . . , Bn sao os novos nomes dos atributos A1, A2, . . . , An da relacaoR. Como exemplo, podemos renomear os atributos do resultado da operacaoproject acima:

ρ NomeEmp, Salario(πnome, salario(Empregado))

que tem como resultado uma relacao com os atributos (NomeEmp, Salario).

Operacoes de conjuntos Podemos realizar operacoes de conjuntos entrerelacoes, ja que uma relacao e um conjunto. A seguinte consulta

resultado1← σsalario>1000(Empregado)

resultado2← σsalario<10000(Empregado)

resultadoFinal← resultado1 ∪ resultado2

seleciona todas as tuplas de Empregado que possuem salario entre 1000 e 10000.Tambem podemos utilizar as operacoes ∩ para a interseccao de duas relacoese − para a diferenca entre duas relacoes. A unica restricao e que as relacoesenvolvidas sejam compatıveis, ou seja, possuam o mesmo tipo de tuplas:

Definicao. Duas relacoes R(A1, A2, . . . , An) e S(B1, B2, . . . , Bm) sao com-patıveis se elas possuem o mesmo grau (n = m) e dom(Ai) = dom(Bi) para1 ≤ i ≤ n.

Produto Cartesiano A operacao de Produto Cartesiano, denotada×, tambeme uma operacao entre conjuntos, mas ela nao exige que as relacoes sejam com-patıveis. Se R e S sao duas relacoes com atributos R(A1, A2, A3, . . . , Am) eS(B1, B2, . . . , Bn), o produto cartesiano T = R × S entre R e S possui atribu-tos T (A1, A2, . . . , Am, B1, B2, . . . , Bn).

join Uma combinacao comumente realizada e a selecao de tuplas do produtocartesiano de duas relacoes. E atraves dessa combinacao que conseguimos relaci-onar duas ou mais relacoes. De uma certa forma, essa combinacao esta no centrodo modelo relacional. Por causa disso, ela ganha o nome de join, denotada por./. A sintaxe basica dessa operacao e:

R ./<C> S

onde R e S sao relacoes e < C > e a condicao de juncao. Se R(A1, A2, . . . , Am) eS(B1, B2, . . . , Bn) sao relacoes, entao T = R ./C S e uma relacao com atributos

22

T (A1, A2, . . . , Am, B1, B2, . . . , Bn) com as tuplas do produto cartesiano R × Sque satisfazem a condicao C.

Como exemplo, considere as relacoes Empregado(Nome, ID) e Gerente(Departamento,ID). Se quisermos os nomes dos gerentes, podemos realizar a seguinte consulta:

πNome(Empregado ./Empregado.ID=Gerente.ID Gerente)

A maioria dos casos de uso da operacao join envolve igualdade entre atri-butos. Nesse caso, a operacao de join tambem e chamada de equijoin. Alemdisso, como no exemplo anterior, e normal querer igualdade entre atributos commesmo nome em relacoes diferentes. Um join com essa caracterıstica e chamadode natural join. Alguns autores definem operacoes separadas para essas va-riantes do join.

Todos os usos de join vistos ate agora serviram para relacionar dados devarias relacoes, podendo ser chamados de inner join, para diferenciar com oque e chamado de outer join.

division Essa operacao, denotada por ÷, e util para expressar consultas quealgumas vezes ocorrem em aplicacoes, e que envolvem varias operacoes.

O Conjunto Completo de Operacoes O conjunto {σ, π,∪,−,×} e com-pleto, ou seja, todas as operacoes da algebra relacional podem ser expressascomo combinacao dessas operacoes, assim como no caso da operacao join, quepode ser expressas como um produto cartesiano seguido de uma selecao. Deteoria de conjuntos, temos que a interseccao pode ser expressa como uma ex-pressao envolvendo unioes e diferencas. Nesse caso, um programa que processeconsultas em algebra relacional nao precisa implementar todas as operacoes an-teriores, mas apenas as operacoes pertencentes ao conjunto acima, traduzindoas operacoes derivadas em expressoes envolvendo as operacoes do conjunto com-pleto.

4.1.3 Calculo Relacional de Tuplas e de Domınio

O calculo relacional e uma linguagem de consulta baseada em logica, mais espe-cificamente em logica de predicados de primeira ordem. Dessa forma, enquantoa algebra relacional e uma linguagem procedural, onde especificamos uma se-quencia de operacoes que resultam na relacao esperada, o calculo relacional euma linguagem declarativa, onde especificamos nao o que o sistema deve fazer,mas como e a resposta. Portanto, apesar de ser possıvel expressar uma consultaem calculo relacional de varias formas diferentes, e provavel que o sistema queexecutar essa consulta realize as mesmas operacoes nas mesmas ordens para asvarias formas possıveis de se expressar a consulta. Para o interpretador, isso in-troduz uma dificuldade maior no momento de transformar consultas do calculorelacional em consultas SQL a serem executadas pelo MySQL, ja que ele deve’entender’ a consulta, e nao simplesmente executar as operacoes, como no casoda algebra relacional.

23

Apesar de serem linguagens bem diferentes, algebra relacional e calculo re-lacional sao linguagens equivalentes, ou seja, toda consulta realizada em umadas linguagem pode ser expressa pela outra linguagem, com o mesmo resultadofinal. Esse resultado e usado pelo interpretador, ja que consultas em calculorelacional sao convertidas para uma serie de consultas em algebra relacional,que por sua vez sao convertidas em consultas SQL.

O calculo relacional possui duas formas de enxergar os dados, o que resulta naexistencia de duas linguagens distintas: se vemos os dados como um conjunto derelacoes, onde cada relacao e um conjunto de tuplas, temos o calculo relacionalde tuplas, que expressa suas consultas por meio dessas tuplas; se vemos osdados como relacoes, onde cada relacao e um conjunto de domınios de atributos,temos o calculo relacional de domınio. A principal diferenca entre essas duaslinguagens e o que representa uma variavel: no Calculo de Tuplas, uma variavele uma tupla. Uma tupla e uma colecao de valores de tipos (domınios) distintos.No Calculo de Domınio, uma variavel e um valor unico, e portanto cada variavelpossui um unico tipo (ou domınio).

Essas linguagens nao sao utilizadas na pratica, mas elas servem de base parao desenvolvimento de outras linguagens de consulta. O Calculo de Tuplas, juntocom a algebra relacional, serviu de base para o SQL, a linguagem de consultamais utilizada atualmente. O Calculo de Domınio, por sua vez, e a base parao QBE (Query By Example), um outro tipo de linguagem muito utilizada eminterfaces graficas para SGDBs.

Calculo Relacional de Tuplas O Calculo Relacional de Tuplas utiliza variaveisque representam tuplas de uma relacao, variando entre todas as tuplas presen-tes na relacao associada a ela. Se imaginarmos uma relacao como sendo umatabela, as variaveis representam as linhas da tabela. Dessa forma, na expressao

Empregado(t)

a variavel t pode ser qualquer tupla de Empregado. Depois de realizada essaassociacao entre variavel e relacao, podemos realizar consultas utilizando essavariavel. Como exemplo, a seguinte consulta

{t|Empregado(t) ∧ t.salario > 10000}seleciona todas as tuplas da relacao Empregado que possuem, no campo salario,um valor maior que 10000. Se quisermos apenas os nomes dos empregados comsalario maior que 10000, podemos escrever

{t.nome|Empregado(t) ∧ t.salario > 10000}Para expressarmos consultas mais complexas do que simples selecoes e projecoes,

como a consulta anterior, devemos utilizar os quantificadores logicos ∀ e ∃. Comoexemplo, considere a seguinte consulta

{t.nome|Empregado(t) ∧ (∃g)(Departamento(g) ∧ t.ID = g.ID gerente)}

24

que tem como resultado o nome de todos os gerentes. Com os quantificadoreslogicos, podemos definir variaveis temporarias, que sao utilizadas para o pro-cessamento de relacionamentos entre relacoes. No momento que utilizamos umquantificador logico, estamos definindo variaveis dentro de um escopo limitado:as variaveis que sao definidas dentro de um ∃ ou de um ∀ nao podem ser usadasfora desse bloco.

O uso de quantificadores e negacoes em uma consulta deve ser feito comcautela, ja que a consulta expressa pode ser nao segura. Uma consulta segura euma consulta que possui, como resultado, um conjunto finito de elementos. Aconsulta a seguir nao e segura:

{t|¬Empregado(t)}O resultado da consulta acima e o conjunto com todas as tuplas que nao estaona relacao Empregado. Mas esse numero e infinito, ja que qualquer coisa quenao esteja em Empregado satisfaz essa condicao. Em especial, todos os numerosnaturais, por exemplo. Logo, garantir que as consultas sejam seguras e algoimportante para um programa que processe consultas em calculo relacional.

Calculo Relacional de Domınio O Calculo Relacional de Domınio utilizavariaveis que representam valores dentro de um domınio. Se visualizarmos asrelacoes como tabelas, as variaveis representam as colunas da relacao. Sendoassim, na consulta

{n|Empregado(n, , )}o resultado e o conjunto com os nomes dos empregados presentes na relacao

Empregado(nome, ID, salario). Para obter os nomes dos empregados que ga-nham mais de 10000 reais, usamos o quantificador logico ∃ para definir umavariavel adicional em um escopo mais interno da consulta:

{n|Empregado(n, , ) ∧ (∃s)(Empregado( , , s) ∧ s > 10000)}Assim como no calculo relacional de tuplas, a seguinte consulta nao e segura:

{n|¬Empregado(n, , )}

4.2 A Interpretacao das Consultas do Usuario

Para interpretar as consultas do usuario, o programa deve, a partir do textopuro das consultas, produzir codigo SQL, executar esse codigo no MySQL emostrar o resultado ao usuario. Todo o processo de interpretacao, do textopuro ao resultado, esta ilustrado na figura 1.

Na proxima secao, sera explicado melhor esse processo, da analise lexica atea geracao de codigo SQL. Durante a execucao, o programa captura excecoesdo MySQL, provenientes de erros na consulta, e mostra esses erros ao usuario.Apos a execucao do codigo SQL, o programa somente coloca esses dados natabela e mostra ao usuario.

25

Figura 1: Processo de interpretacao das consultas do usuario

4.3 A Traducao das Linguagens de Consulta

O interpretador suporta quatro linguagens de consulta, que devem ser traduzi-das para SQL, em especial para o SQL suportado pelo MySQL. Para realizaressas traducoes, o programa deve, primeiramente, realizar a analise sintaticadessas linguagens, ja que elas sao linguagens livres de contexto.

A analise sintatica dessas linguagens comeca pela analise lexica, ou seja,pelo reconhecimento dos tokens presentes na entrada. Um token e um elementoatomico da entrada, correspondendo aos terminais da gramatica que descrevea linguagem. Como o programa recebe como entrada uma cadeia de caracteresque contem as consultas, o primeiro passo do programa e separar essa cadeiaem cadeias menores, cada uma correspondendo a uma consulta, e reconhecer ostokens de cada uma dessas consultas.

A forma mais eficiente de se realizar a analise lexica e atraves de automatosfinitos determinısticos. Como os tokens sao palavras no alfabeto composto porletras, numeros e alguns sımbolos especiais, essas palavras podem ser descritasatraves de expressoes regulares, e por conta disso, um automato finito e suficientepara o reconhecimento dessa ’linguagem’ que reune os terminais das linguagensde consulta. Apesar de ser mais rapido, o interpretador de consultas nao utilizaautomatos para fazer a analise lexica. O programa utiliza um metodo maissimples de ser implementado, realizando varias operacoes de alto nıvel no textode entrada. Ele separa as palavras/sımbolos da entrada, e reconhece cada blocoseparadamente. Como os espacos em branco entre as palavras sao obrigatoriosnas linguagens de consulta, esse metodo funciona bem.

As operacoes realizadas pelo programa para obter a lista de tokens da entradae:

1. Converter ’\t’, ’\n’, ’\r’ em espacos

2. Utilizando o caractere ’;’, quebrar a lista de caracteres resultante emvarias listas, cada uma representando uma consulta

26

3. Cercar os sımbolos especiais (’(’, ’)’, ’{’, . . . ) com espacos

4. Transformar todas as sequencias com mais de um espaco em um espacounico

5. Quebrar cada consulta em cadeias menores, utilizando espacos como ele-mento separador

6. Reconhecer cada cadeia dessa lista e associar a um token

No final desse processo, temos uma lista de consultas, onde cada consulta euma lista de tokens, que serao usados na analise sintatica.

Como podemos ver, o programa percorre varias vezes a lista de entrada.Mesmo assim, o processo ainda e linear com relacao ao numero de caracte-res presentes na entrada, a mesma complexidade da analise lexica utilizandoautomatos finitos.

Apos obtermos a lista de tokens (especıficos de cada linguagem), podemosrealizar a analise sintatica e obter as arvores sintaticas das consultas. O ana-lisador e do tipo LL, escolhido pela sua facilidade de ser implementado. ParaSQL e Algebra Relacional, o analisador e do tipo LL(1), que leva em conta ape-nas o primeiro token da entrada para realizar as expansoes. Ja para o CalculoRelacional de Tuplas e de Domınio, o analisador e do tipo LL(2), que leva emconta os primeiros dois tokens da entrada para realizar as expansoes.

Os analisadores sao constituıdos de um automato com pilha, que controla oprocesso, e de uma tabela, que contem as derivacoes pre-computadas para cadapar (Nao-Terminal, Terminal). O processo comeca com a insercao do sımboloinicial na pilha do automato e a criacao da raiz da arvore sintatica, contendo osımbolo inicial. A partir desse ponto, temos um laco que faz o seguinte:

• Expansao: Se o primeiro elemento da pilha for um nao-terminal, substituiesse nao-terminal na pilha pelo elemento da tabela presente na posicaocorrespondente a esse nao-terminal e ao primeiro token da entrada, ou

• Casamento: Se o primeiro elemento da pilha for um terminal, verifica seo primeiro token da entrada e do mesmo tipo desse terminal, eliminandoambos em caso afirmativo. Se esse terminal for um λ, apenas elimine esseterminal da pilha e prossiga

A arvore e montada da seguinte forma: na expansao, se o nao-terminalsubstituıdo for N , entao crie um no para cada elemento da derivacao, sendo opai desses nos o no que representa N ; no casamento, coloque o valor do tokenda entrada no no que representa esse terminal.

O processo termina quando a pilha nao possui mais elementos. Nesse mo-mento, a entrada tambem nao deve possuir elementos, ja que todos os seusterminais foram casados com terminais da pilha. Se os elementos da pilha e daentrada nao se esgotarem ao mesmo tempo, a entrada nao e reconhecida comoum elemento da linguagem.

27

Como a gramatica nao possui loops em suas derivacoes, e o analisador per-corre a entrada apenas uma unica vez, o processo possui complexidade linearno numero de tokens da entrada.

E possıvel que ocorra tres tipos de erros no processo, que resultam na rejeicaoda entrada:

• Termino nao sincronizado, quando os elementos da pilha e da entrada naose esgotam ao mesmo tempo;

• Nao casamento entre um elemento da entrada e o nao terminal do topoda pilha;

• Na expansao, requisitar a derivacao de uma posicao da tabela que naopossui derivacoes, ou seja, o analisador nao esperava encontrar o token daentrada naquele momento ponto do processo.

De posse da arvore sintatica, podemos realizar a traducao para uma consultaque o MySQL consiga executar. Para isso, o interpretador realiza conversoesentre os tipos de arvores sintaticas, transformando uma arvore do tipo x em umaarvore sintatica do tipo y. As conversoes realizadas pelo programa dependemda linguagem da consulta original. O ideal seria que as arvores sintaticas dasquatro linguagens fossem traduzidas diretamente para arvores sintaticas SQLque seriam convertidas em codigo SQL. Mas como esse processo so e trivialpara o caso em que a linguagem original e SQL, na pratica o programa acabatransformando uma arvore sintatica em varias arvores sintaticas SQL. Isso fazcom que as execucoes das consultas possuam um desempenho pior do que oideal.

A traducoes das linguagens de consulta para SQL sao realizadas da seguinteforma:

SQL → SQL: para a linguagem SQL, o interpretador transforma a arvoresintatica construıda pelo analisador em uma outra arvore sintatica SQL, maissimplificada e facil de ser percorrida. Um exemplo de simplificacao realizadae a transformacao das listas. Essa transformacao esta ilustrada a seguir, ondeconsideramos uma lista de id’s da forma id, id, id, . . . , id:

1. L

id RL

, id RL

, id RL

. . .

2. L

id id id . . .

28

Figura 2: Conversoes realizadas na traducao

A arvore 1 e a arvore obtida atraves da analise sintatica, enquanto que aarvore 2 e o resultado da transformacao realizada na traducao. E facil ver quea segunda arvore e mais facil de ser percorrida, alem de ser mais simples, jaque nao possui o nao-terminal RL. Alem disso, note que a arvore 2 nao possuias vırgulas, ja que esses terminais nao sao necessarios (a gramatica nao forneceuma alternativa a essas vırgulas; logo, se temos uma lista de id’s, sabemos queeles sao separados por vırgulas).

No programa, o resultado dessa simplificacao da arvore sintatica SQL e cha-mada de arvore sintatica SQL simplificada. A partir dela, e muito facil produzircodigo SQL para ser executado pelo MySQL. Por causa disso, as traducoes detodas as linguagens de consulta resultam em arvores sintaticas SQL simplifica-das, que sao transformadas em codigo SQL.

Algebra Relacional → SQL: essa traducao nao e feita diretamente, umaconsulta da Algebra Relacional para uma consulta SQL executada. O inter-pretador realiza uma traducao de forma mais simples, sem precisar ’entender’a consulta do usuario. Para isso, ele se aproveita da propriedade do fecha-mento da algebra relacional: o resultado de uma operacao dessa algebra e umarelacao. Dessa forma, como consultas em algebra relacional sao composicoes deoperacoes, podemos traduzir cada operacao para uma consulta SQL, utilizandoo resultado dessa consulta como parametro para a consulta seguinte. Dessaforma, uma consulta da Algebra Relacional e traduzida em varias consultasSQL, uma para cada operacao utilizada na consulta original.

Por exemplo, considere a seguinte consulta em algebra relacional sobre a

29

relacao Empregado dos exemplos anteriores, com a sintaxe utilizada no pro-grama:

resultado := project Nome (select [Salario > 10000] (Empregado))

Essa consulta pode ser decomposta em:

temp1 := Empregado

temp2 := select [Salario > 10000] (temp1)

resultado := project Nome (temp2)

Cada uma das consultas acima sao faceis de serem traduzidas para SQL.Logo, o tradutor nao precisa ’entender’ a consulta, mas apenas separar asoperacoes e traduzi-las separadamente.

Apesar de ser mais simples de ser implementada, essa solucao e menos efi-ciente do que o ideal (producao de apenas uma consulta SQL a ser executada).Isso se deve ao fato de uma unica consulta gerar varias consultas SQL, o que setraduz em uma quantidade maior de dados a ser manipuladas pelo MySQL.

Calculo Relacional→ SQL: por serem linguagens muito parecidas, o metodode traducao de Calculo Relacional de Domınio e do Calculo Relacional de Tu-plas para SQL e praticamente o mesmo, adaptado para a visao de mundo daslinguagens (tuplas ou domınios).

O Calculo Relacional e bem diferente da Algebra Relacional, sendo declara-tiva ao inves de procedural. Dessa forma, o metodo utilizado para a traducaoda Algebra Relacional nao pode ser utilizado para traduzir o Calculo Relacio-nal. Apesar disso, o metodo utilizado pelo interpretador tenta encontrar umasequencia de operacoes que equivalem a consulta original. Dessa forma, o resul-tado e parecido com o resultado da traducao da Algebra Relacional.

Para traduzir uma consulta do Calculo Relacional para Algebra Relacional(que sera traduzida para SQL), o interpretador percorre a consulta da esquerdapara a direita, acumulando o resultado das conjuncoes and. Dessa forma, po-demos encarar um and como sendo um elo entre dois termos, e o tipo dessestermos define a operacao gerada. Como exemplo, considere a seguinte consultaem Calculo Relacional de Tuplas, com a sintaxe utilizada no programa:

resultado := {E.Nome | Empregado(E) and E.Salario > 10000}

Lendo a consulta da esquerda para a direita, o tradutor faz o seguinte:

• tudo entre {. . . | e guardado para o final;

• o primeiro elemento encontrado e uma tabela (associacao entre tabela evariavel). Nesse ponto, e criada a associacao entre a variavel E e a relacaoEmpregado;

30

• encontramos a conjuncao and e a condicao E.Salario > 10000. Nessecaso, como temos Tabela and Condicao, o resultado e uma operacao deselecao, temp1 := select Salario > 10000 (Empregado);

• como nao existe mais termos na consulta, voltamos para o comeco, ecriamos uma projecao das colunas especificadas em {. . . |. Nesse caso, oresultado e: resultado := project Nome (temp1)

O grande problema desse metodo e que, se temos Tabela and x, o tipo dex faz com que a consulta gerada seja bem diferente da consulta gerada por umoutro tipo de x. Dessa forma, esse tradutor e bem complicado de implementar.Em especial, o caso mais complicado e quando x e um quantificador existencial,e contem, no seu interior, uma condicao de juncao. Nesse caso, o interpretadornao traduz para a algebra relacional, mas faz algo mais simples: se aproveitado fato de SQL possuir a sintaxe exists, e traduz esse caso diretamente paraSQL.

A geracao de codigo e bem simples, apenas percorrendo a arvore SQL sim-plificada e montando o texto da consulta. Ela so precisa tomar alguns cuidadoscom:

• Diferenca e Interseccao: como o MySQL nao possui operadores que re-alizam essas operacoes (MySQL possui apenas o operador union para auniao de conjuntos), o gerador deve percorrer a arvore SQL de uma formadiferente na presenca de uma dessas operacoes

• Nomes das tabelas: o interpretador nao pode ter acesso root ao MySQL.Logo, ele nao e capaz de criar bancos de dados dentro do MySQL. Paracontornar esta situacao, o interpretador utiliza apenas um banco de dados,mas ele simula a existencia de varios bancos de dados da seguinte forma:

– Temos uma tabela com os nomes dos bancos de dados do usuario

– Toda a tabela do usuario pertencente a um banco de dados possui onome do seu banco como prefixo.

Sendo assim, o banco de dados que acompanha a aplicacao, BD_Empresa,possui varias tabelas, dentre elas a tabela Empregado. No MySQL, te-mos uma tabela chamada interp_Databases, com a lista de bancos dousuario. Dentro dessa tabela, temos uma linha com o valor BD_Empresa.A tabela Empregado, no MySQL, possui o nome BD_Empresa_Empregado.Dessa forma, podemos ter duas tabelas com nomes iguais pertencentes abancos de dados diferentes. Na hora da geracao de codigo, o gerador deveconverter Empregado para BD_Empresa_Empregado. Alem disso, ele deveter cuidado com os nomes de tabelas temporarias.

4.4 MySQL, Java e Swing

O interpretador nao armazena os dados nem executa as consultas. Para essasfuncionalidades, o programa usa o SGDB open source chamado MySQL. Seu

31

desenvolvimento comecou no ano de 1994, com a primeira versao sendo lancadaem 1995, pela empresa MySQL AB, atualmente parte da Oracle [6]. MySQL eum dos SGDBs mais utilizados atualmente, presente em alguns dos sites maisacessados do mundo, como Facebook, Google e Adobe [7]. O sistema suporta,principalmente, SQL-99 e algumas de suas extensoes.

Como linguagem de programacao, o interpretador foi implementado em Java.Lancada em 1995 pela Sun Microsystems, Java e uma linguagem interpretada,sendo executada por uma maquina virtual chamada Java Virtual Machine.Como consequencia, os programas escritos na linguagem sao faceis de seremportados para outros sistemas de computadores, ja que apenas a JVM precisade versoes especıficas. Java e uma linguagem orientada a objetos, boa paragrandes projetos. Apesar de ser interpretada, o desempenho de programas Javae aceitavel, apenas pecando na inicializacao, que e mais lenta que programasnativos, ja que a propria maquina virtual deve ser inicializada.

A interface grafica (GUI - graphical user interface) do interpretador usa abiblioteca Swing. Essa biblioteca e baseada em widgets, com arquitetura MVC(Model-View-Controller). Como o seu codigo e implementado em Java, semcodigo especıfico da plataforma nativa, Swing e um exemplo de biblioteca graficalightweight. Isso faz com que a interface possua comportamento similar nas maisdiversas plataformas, com uma penalizacao no desempenho da aplicacao.

4.5 Principais Funcionalidades

O interpretador tem como objetivo ser uma ferramenta de aprendizado de con-sultas a bancos de dados relacionais. Para alcancar esta meta, o programaimplementa diversas funcionalidades:

• criacao e remocao de bancos de dados, utilizando a interface grafica

• criacao e remocao de tabelas de um banco de dados, atraves da interfacegrafica, com suporte a quatro tipos de dados para as colunas

• edicao dos dados de uma tabela utilizando a interface grafica

• importacao e exportacao de esquemas e dados das tabelas e dos bancosde dados, utilizando XML como formato de arquivo

• execucao de consultas escritas em quatro linguagens diferentes, traduzindoessas consultas para SQL, executadas pelo MySQL

Alem disso, o programa nao utiliza nenhuma funcionalidade especıfica aalguma plataforma. Portanto, em princıpio, o programa pode ser executadoem qualquer plataforma que possua a Java Virtual Machine versao 1.6 ou maisrecente. Em princıpio porque o programa foi testado apenas em um sistemaLinux e Windows XP/Windows 7.

Outro aspecto importante e o fato do codigo do programa ser aberto. Issopossibilita que, no futuro, outras pessoas acrescentem funcionalidades que naoestao presentes na versao atual ou que nao foram possıveis de implementar porfalta de tempo, como as funcionalidades expostas na secao 6.

32

4.6 A Interface Grafica

A tela principal do interpretador possui duas areas distintas. A parte esquerdada tela possui uma arvore com os bancos de dados presentes no MySQL. Atravesdessa arvore, o usuario pode selecionar ou apagar um banco de dados. Ao serselecionado, o ramo daquele banco abre-se, mostrando uma lista com as tabelaspresentes nele. Atraves da arvore, o usuario tambem pode invocar a tela decriacao de nova tabela para o banco selecionado ou apagar uma das tabelasdesse banco. Ao selecionar um banco, o programa consulta o MySQL e mostratodos os dados presentes em todas as tabelas do banco na parte direita datela. Nessa parte, cada aba representa uma tabela do banco de dados. Naparte inferior, o usuario pode utilizar um dos botoes para apagar ou adicionaruma linha da tabela atual, alem de gravar todas as modificacoes realizadas noMySQL. O usuario pode editar os dados da tabela diretamente, clicando duasvezes no campo a ser editado.

Figura 3: Janela principal do interpretador de consultas

Na barra de ferramentas, estao presentes botoes para as operacoes maisutilizadas. Atraves dessa barra, podemos invocar as telas de criacao e remocaode um banco de dados, criacao e remocao de uma tabela, alem da tela de edicaode consultas, vinculada ao banco selecionado atualmente.

As telas de criacao e remocao de bancos de dados sao bem simples: a criacaode um novo banco de dados apenas pede um nome, que deve ter um formatoespecıfico. A tela de remocao pede apenas uma confirmacao do usuario para

33

realizar a operacao.

Figura 4: Telas de criacao e remocao de Banco de Dados

A tela de criacao de nova tabela e a mais complicada do programa. Ela pedeo nome da nova tabela, que tambem deve ser de um formato especıfico. O fundoda caixa de texto indica se o nome esta correto ou nao. Logo abaixo temos umalista com as colunas presentes na tabela a ser criada. Mais abaixo, temos a areade definicao de novas colunas. Nela, podemos definir o nome da nova coluna(novamente, com restricoes, e indicacao da corretude do nome no fundo da caixade texto), o tipo dos dados da coluna (boolean, integer, double ou varchar), seos dados da coluna podem assumir valores nulos e se a coluna faz parte da chaveprimaria da relacao. Apos uma coluna que nao assume valores nulos e faz parteda chave primaria for adicionada a lista de colunas, fica acessıvel a opcao decriar a tabela. Note que nao e permitido adicionar colunas que fazem parte dachave primaria mas assumem valores nulos.

Assim como na remocao de um banco de dados, a tela de remocao de umatabela e apenas uma tela de confirmacao do usuario. A tela de edicao de con-sultas deve ser a tela mais utilizada do programa. Ela consiste de uma areade texto principal, onde o usuario escreve as consultas; um seletor de tipo etamanho da fonte usada pelo editor; um seletor de linguagem de consulta, quedeve ser a linguagem das consultas presentes no editor; e botoes para executar aconsulta do editor, cancelar e sair do editor, gravar o texto presente no editor nodisco e carregar o texto de um arquivo do disco. Como e possıvel abrir mais deuma janela de consulta, o tıtulo da janela contem o banco de dados associadoaquela janela. Sendo assim, qualquer consulta executada naquela janela serafeita usando o banco de dados do tıtulo. Apos as consultas serem executadas,o resultado aparece em uma nova janela, que contem uma tabela para cadaconsulta. Essa janela, diferentemente da tela principal do interpretador, naopermite que o usuario edite os dados presentes nela (e nem faria sentido que elapermitisse a edicao).

No menu superior temos acesso, alem das funcionalidades anteriores, a im-

34

Figura 5: Tela de criacao de novas tabelas

Figura 6: Editor de consultas

35

portacao e exportacao de dados entre o programa e um arquivo externo. Usandoo menu, podemos exportar e importar esquemas do banco de dados e de umatabela, dados de uma tabela alem de exportar e importar uma tabela com-pleta e um banco completo. Dessa forma, o programa permite que os usuarioscompartilhem dados, sem precisar utilizar o MySQL diretamente.

Figura 7: Alguns menus do interpretador

Alem disso, no menu superior podemos mudar a linguagem da interfacegrafica, escolhendo entre Portugues do Brasil ou Ingles.

36

5 Resultados - O programa em funcionamento

O programa consegue realizar todas as funcionalidades descritas em 4.5. Oprograma realiza consultas em SQL muito rapidamente, ja que cada consultado usuario e convertida em uma consulta a ser executada pelo MySQL. No casodas outras linguagens de consultas, onde uma consulta do usuario e convertidaem varias consultas SQL, a execucao de demora um pouco, sendo perceptıvel aousuario. Essa situacao e mais grave no caso do calculo relacional, onde o tempode resposta e significativo. Alem disso, tabelas com muitas linhas demoram paraser mostradas ao usuario. Principalmente em consultas onde o resultado e bemgrande (produtos cartesianos), a maior parte do tempo gasto pelo programapara executar uma consulta esta no carregamento dos dados na tabela que seramostrada ao usuario. Isso acontece para consultas SQL, onde um arquivo com30 consultas variadas realiza a analise sintatica e a execucao das consultas peloMySQL de forma quase instantanea, enquanto que o carregamento dos dadosdo resultado para a interface grafica do programa toma quase todo o tempo daconsulta.

Apesar desses problemas, o programa consegue realizar consultas bem com-plicadas. Para a linguagem SQL, o programa suporta quase todos os tipos deconsultas realizadas na vida real (as consultas nao suportadas utilizam concei-tos muito especıficos de SQL, que nao foram implementados, ja que eles naopossuem algo parecido nas outras linguagens). Realizar consultas em AlgebraRelacional e muito agradavel, e bem ’matematico’, ja que e bem parecido comas algebras estudadas nas disciplinas de matematica. Em contrapartida, con-sultas em Calculo Relacional sao praticamente logica pura. Esse contraste entreestilos de linguagens, e a verificacao experimental de que todas essas linguagensconseguem realizar os tipos de consultas mais importantes, contribui bastantepara o aprendizado do usuario.

Alem disso, como o foco do programa e a exploracao das linguagens, muitasdas vezes utilizando apenas uma consulta e modificando/executando essa con-sulta repetidamente, os problemas apontados mais acima nao sao muito graves,ja que eles se manifestam principalmente na presenca de um numero elevado deconsultas.

37

6 Melhorias Possıveis

Infelizmente, o programa ainda nao esta pronto. Apesar de realizar todas asfuncionalidades mais importantes e basicas, como edicao dos dados utilizandoa interface e o suporte as quatro linguagens de consulta, ainda falta implemen-tar algumas funcionalidades que tornam o uso do programa mais agradavel.Algumas das melhorias possıveis sao:

• Melhoria no editor de consultas: adicionar algumas funcionalidades aoeditor de consultas para tornar a edicao mais agradavel e ajudar o usuarioa cometer um numero menor de erros. Para esse fim, podemos citar realcede sintaxe (que auxilia o usuario a reconhecer palavras reservadas e ocasamento entre delimitadores, como ’(’ e ’)’, ’{’ e ’}’, etc.), auto-identacao e acesso rapido aos nomes das tabelas e de suas colunas no bancode dados associado ao editor.

• Melhoria na traducao das consultas: ao inves de gerar varias consultasSQL como resultado da traducao de uma consulta em linguagem de origemdiferente de SQL, o ideal e que todas as traducoes sejam uma para uma:uma consulta original resulta em uma consulta SQL. Dessa forma, como onumero de consultas executadas pelo MySQL e menor, a performance doprograma no momento da execucao das consultas seria comparavel a per-formance na execucao das consultas tendo SQL como linguagem original.Atualmente, se o arquivo a ser executado possui um numero pequeno deconsultas (ate 5, mais ou menos), o tempo gasto para que essas consul-tas sejam executadas e parecido em todas as linguagens. Isso e bom, jaque o usuario pode experimentar com as linguagens sem precisar esperarmuito para obter o resultado. Mas seria bom que o programa conseguisseexecutar um grande numero de consultas rapidamente.

• Melhoria nas tabelas: as tabelas mostradas aos usuarios possuem umaperformance ruim quando possuem muitos dados. Essa demora e notadaprincipalmente no momento que utilizamos a barra de rolagem das tabelas.Nesse momento, o programa demora um ou dois segundos para mover aparte visıvel da tabela para o ponto correspondente a posicao da barra.Isso acaba dificultando a edicao de dados e a visualizacao dos resultadosdas consultas. Portanto, esse problema acaba prejudicando bastante ausabilidade do programa.

• Melhoria nos ıcones do programa: os ıcones presentes no programa saoıcones livres, utilizados pelos projetos GNU. Por causa disso, os ıconesnao sao coerentes entre si. Um conjunto de ıcones desenvolvidos para ointerpretador melhoraria a apresentacao do programa.

• Melhoria nos formatos dos arquivos: o programa utiliza XML como for-mato para os arquivos resultante da exportacao de dados e esquemas.

38

Alem disso, esse formato e o unico formato que o programa consegue re-conhecer para a importacao de dados. Apesar de ser um formato ampla-mente utilizado pelas aplicacoes mais variadas, esse formato nao e facil deser editado, pela quantidade de metatexto presente. Por conta disso, se ousuario nao quiser utilizar o programa para editar os dados, ele deve utili-zar um editor XML para editar o arquivo exportado pelo programa. Umamelhoria possıvel e o suporte pelo programa para formatos mais simplesde editar utilizando um editor de texto, como vi ou emacs.

• Melhoria na internacionalizacao: atualmente, os dados armazenados nobanco devem estar no formato ASCII. Uma melhoria desejavel e o suporteao formato Unicode. Alem disso, o esquema de traducao da interfacegrafica ainda esta muito ’hardcoded’, podendo ser abstraıdo, a fim defacilitar a traducao para novas linguagens.

39

7 Bibliografia

Referencias

[1] Arizona State University, Windows Relational DataBase Interpreter,http://winrdbi.asu.edu.

[2] Lewis H. R., Papadimitriou C. H., Elements of The Theory of Computation,Second Edition, Prentice-Hall, 1998.

[3] Grune D., Bal H. E., Jacobs C. J. H., Langendoen K. G., Modern CompilerDesign, First Edition, John Wiley & Sons LTD, 2000.

[4] Elmasri R., Navathe S. B., Fundamentals of Database Systems, FourthEdition, Pearson Education, Inc, 2004.

[5] Wikipedia, Ambiguous grammar, http://en.wikipedia.org/wiki/Ambiguous grammar,27/11/2011.

[6] Wikipedia, MySQL, http://en.wikipedia.org/wiki/MySQL, 27/11/2011.

[7] MySQL.com, Why MySQL? http://www.mysql.com/why-mysql/,27/11/2011.

[8] Oracle, Java, http://www.oracle.com/technetwork/java/index.html,27/11/2011.

40

Parte II

Parte Subjetiva

8 Desafios e Frustracoes

O maior desafio encontrado nesse projeto foi a traducao das consultas. Prin-cipalmente a traducao entre calculo relacional e SQL, que nao e direta comoa traducao entre a algebra relacional e SQL. Essa traducao envolve varios as-pectos, como escopo de variaveis, associacao entre variavel e relacao ou entrevariavel e coluna de uma relacao, alem dos quantificadores, que sao bem com-plicados de traduzir corretamente. Como resultado, a traducao das quatro lin-guagens de consultas suportadas pelo programa em SQL esta implementada emaproximadamente 4000 linhas de codigo, quase metade do numero de linhas decodigo consumido pelo programa inteiro. Alem disso, o codigo das traducoesnao e muito facil de ser entendido, ja que o tradutor deve percorrer a arvoresintatica. Isso faz com que o codigo contenha acessos a ındices que parecemmagicos. Para conseguir entender o funcionamento dos tradutores, e necessarioutilizar o diagrama das arvores sintaticas.

Para complicar ainda mais a traducao, o MySQL nao suporta as operacoesde diferenca e interseccao entre conjuntos (MINUS e INTERSECT). Essas operacoessao suportadas pela maioria dos grandes SGDBs, como Oracle e PostgreSQL.O suporte a essas operacoes reduziria um pouco a complexidade da traducao,ja que consultas contendo essas operacoes poderiam ser traduzidas diretamentena traducao SQL → SQL, sem precisar de manipulacoes na arvore sintatica.

Uma frustracao que tive com o projeto foi a lentidao encontrada na execucaodas consultas em calculo relacional e na apresentacao das tabelas com os da-dos presentes no banco ou no resultado das consultas. Um dos problemas doWinRDBI e a lentidao na realizacao das consultas. Por isso, um dos objetivosdo programa e realizar as consultas mais rapidamente, utilizando o MySQL aoinves de implementar a engine de consultas. Mas como o numero de consultasgeradas pela traducao e muito grande, o interpretador acaba nao cumprindoo planejado. A lentidao na apresentacao das tabelas era esperada, ja que oprograma utiliza Java como linguagem de programacao, mas ainda assim e frus-trante verificar que essa demora prejudica tarefas simples, como a edicao dosdados.

Uma outra frustracao foi o comportamento do MySQL em algumas situacoes.Como exemplo relevante ao programa, temos o comportamento do MySQL naentrada de dados com formato inesperado. O comportamento padrao na grandemaioria dos SGDBs e o retorno de um erro ao usuario. Mas no caso do MySQL,e mostrado um warning, e o dado entrado e transformado para um formatocoerente com o esperado. Dessa forma, o interpretador nao pode confiar noMySQL para a verificacao de dados editados pelo usuario, devendo implementarverificacoes para cada dado do usuario. Isso acaba aumentando a complexidadedo codigo da aplicacao, aumentando assim os erros presentes no programa.

41

Para completar, ainda temos o maior desafio deste projeto: o uso do inter-pretador na disciplina de Banco de Dados para o aprendizado dos alunos. Esteprojeto sera bem sucedido apenas no caso em que o programa esteja ajudando osseus usuarios a aprender linguagens de consultas. So saberemos se esse objetivofoi alcancado apos alguns anos de uso do interpretador na disciplina.

9 Disciplinas Relevantes

As disciplinas mais relevantes para esse projeto foram Banco de Dados e Lingua-gens Formais e Automatos. Da disciplina de Banco de Dados, foi aproveitadoos conceitos fundamentais sobre o modelo relacional, alem de ser a disciplinaonde aprendemos a escrever consultas. Alem disso, o objetivo do programa eser utilizado por essa disciplina, logo ela foi a principal disciplina aproveitadapelo projeto. Da disciplina de Linguagens Formais e Automatos, foi aproveitadoquase toda a teoria. E a partir dos topicos estudados durante essa disciplina quefoi possıvel a implementacao dos analisadores sintaticos utilizados nas traducoesdas consultas.

Uma outra disciplina importante foi Estruturas de Dados. E nessa disci-plina que estudamos arvores, a principal estrutura de dados utilizada pelo pro-grama. A disciplina de Conceitos de Linguagens de Programacao tambem foiimportante, ja que ela lida com linguagens de programacao, que possui algunselementos presentes nas linguagens de consultas utilizadas pelo interpretador,como escopo de variaveis no caso do calculo relacional.

A disciplina de Algebra II tambem foi importante para a traducao da algebrarelacional, ja que nessa disciplina estudamos varios tipos de conjuntos comoperacoes definidas sobre esses conjuntos, e portanto, o conceito do fechamentoaparece bastante nessa disciplina, conceito esse central nessa traducao.

As disciplinas de programacao, como Laboratorio de Programacao I e II,foram importantes na implementacao, principalmente da interface grafica.

10 Conceitos Utilizados

Os principais conceitos utilizados pelo projeto foram:

• Bancos de Dados: sistemas gerenciadores de bancos de dados; o modelorelacional; consultas no modelo relacional; calculo e algebra relacional;SQL

• Linguagens Formais e Automatos: alfabetos; linguagens; automatosfinitos; linguagens regulares; linguagens livres de contexto; gramaticaslivres de contexto; automatos com pilha; analisadores sintaticos.

• Laboratorio de Programacao II: programacao orientada a objetos;programacao de interfaces graficas.

• Estruturas de Dados: pilhas; listas; arvores.

42

• Algebra II: operacoes sobre conjuntos; fechamento.

11 Planos Futuros

Pretendo terminar a implementacao da parte basica, como as traducoes. Comtodas as traducoes funcionando, acho que o programa ja pode ser usado comosubstituto ao WinRDBI na disciplina de Banco de Dados do IME-USP. Algobem desejavel e a implementacao das funcionalidades adicionais ao editor deconsultas, ja que nao existe editor de texto que suporte as linguagens de con-sulta do interpretador. Essas funcionalidades nao sao vitais para o sucesso doprograma, mas elas ajudam a melhorar a experiencia do usuario com o pro-grama, o que faz com que o usuario tenha mais vontade de utilizar o programa.Alem disso, uma melhora nas traducoes e, consequentemente, uma melhora nodesempenho da execucao das traducoes trara benefıcios ao aprendizado.

12 Agradecimentos

Eu gostaria de agradecer a minha famılia e aos meus amigos pela forca dadadurante este ano. Alem disso, eu tambem gostaria de agradecer ao meu orien-tador, principalmente pela ideia de utilizar o MySQL para armazenar os dadose executar as consultas, ideia tao simples que economizou um grande tempo dedesenvolvimento.

43