Definiç˜ao Modular da Sintaxe de AspectJ usando - DC

Propaganda
Definição Modular da Sintaxe de AspectJ
usando Parsing Expression Grammar
Luı́s Eduardo de Souza Amorim,
Vladimir Oliveira Di Iorio,
Giorgio P. F. Guimarães Torres,
Felipe da Silva Pinheiro
Leonardo Vieira dos Santos Reis
Departamento de Ciências Exatas e Aplicadas
Universidade Federal de Ouro Preto
Email: [email protected]
Departamento de Informática
Universidade Federal de Viçosa
Email: [email protected], [email protected],
[email protected], [email protected]
Resumo—Propostas de novos recursos para linguagens orientadas a aspectos são objeto de muita pesquisa. Sendo AspectJ
a linguagem orientada a aspectos mais utilizada, boa parte
dessa pesquisa envolve a extensão de AspectJ. Para facilitar o
desenvolvimento e teste de novos recursos, é desejável se ter
uma especificação da linguagem AspectJ que seja construı́da de
forma modular e que ofereça facilidades para extensão.
Este trabalho apresenta uma definição da sintaxe de AspectJ
usando o formalismo conhecido como Parsing Expression Grammar (PEG). Um analisador sintático é gerado utilizando a ferramenta Rats!, que inclui recursos para construir especificações
com alta modularidade e para facilitar a extensibilidade. São
apresentados testes comparativos que mostram que esse analisador apresenta desempenho superior a outros analisadores com
caracterı́sticas similares.
I. I NTRODUÇ ÃO
A linguagem AspectJ, desde sua criação, tem sido a linguagem orientada a aspectos mais estudada e utilizada. Muitos
trabalhos desenvolvidos no sentido de propor novos recursos
e caracterı́sticas para linguagens orientadas a aspectos são
implementados como extensões para AspectJ, frequentemente
envolvendo extensão da sintaxe concreta [1], [2].
Para facilitar a especificação e testes de novos recursos para
AspectJ, é necessário, primeiramente, dispor de uma definição
sintática da linguagem que permita uma composição modular
de extensões. Novas construções propostas devem poder ser
combinadas sem que haja conflitos com as já existentes.
Ferramentas devem estar disponı́veis para automaticamente
construir, a partir dessas definições, analisadores sintáticos
cujo desempenho não seja comprometido pelas extensões.
Este artigo apresenta uma definição sintática para a linguagem AspectJ com o objetivo de facilitar a criação de extensões,
de maneira modular. A sintaxe é definida usando o formalismo
Parsing Expression Grammars (PEG) [3]. Um analisador
sintático é construı́do com a ferramenta Rats! [4], que fornece os recursos necessários para construção de analisadores
sintáticos rápidos, extensı́veis e modulares. Testes mostram
que essa combinação pode alcançar resultados superiores nos
quesitos de facilidade para criação de extensões e eficiência
dos analisadores, quando comparada com trabalhos similiares.
O texto está estruturado da seguinte maneira. Na Seção II,
apresentamos alguns trabalhos relacionados, em que também
foram propostas definições sintáticas para AspectJ. A Seção III
apresenta o formalismo de PEG e a Seção IV lista recursos da ferramenta Rats!. Na Seção V, detalhes sobre a
definição de AspectJ usando PEG e Rats! são discutidos. A
definição construı́da é comparada com trabalhos relacionados,
na Seção VI. Para a comparação, são avaliadas as facilidades
para extensibilidade e recursos de modularidade, e ainda o
desempenho dos analisadores sintáticos gerados. Finalmente,
a Seção VII apresenta conclusões e possı́veis trabalhos futuros.
II. T RABALHOS R ELACIONADOS
Esta seção discute diferentes especificações para a sintaxe
de AspectJ, usadas para implementar analisadores sintáticos
para a linguagem. Oferecimento de recursos para extensibilidade é uma preocupação de alguns trabalhos, pois foram
desenvolvidos com o objetivo de proporcionar facilidades para
pesquisa sobre possı́vel evolução de AspectJ.
A ferramenta ajc [5] consiste de um compilador completo
para AspectJ, projetado de modo a ter geração de código e
execução eficientes. É o compilador original para AspectJ,
atualmente desenvolvido e suportado pelo projeto AspectJ
Eclipse. Não são oferecidas facilidades para extensibilidade,
uma vez que isso não fez parte dos objetivos principais do
projeto.
O projeto AspectBench Compiler (abc) [6] também oferece
um compilador completo para a linguagem AspectJ. Esse
compilador foi projetado de modo a permitir uma maior
facilidade para extensão de seus componentes, especialmente
o analisador sintático.
No abc, a sintaxe de AspectJ é especificada por uma
gramática livre de contexto LALR(1). Um analisador sintático
é construı́do automaticamente, a partir dessa gramática, usando
a ferramenta Polyglot [7], que oferece recursos para extensibilidade da sintaxe. Produções podem ser estendidas, eliminadas
e inseridas na gramática. O analisador léxico do abc é dividido
em estados, que permitem que suas palavras-chave sejam
sensı́veis ao contexto, isto é, dependendentes do contexto onde
são utilizadas. Diferente da sintaxe, há poucos recursos para
extensão dos componentes léxicos da linguagem.
Outra definição para a gramática de AspectJ é baseada no
formalismo SDF [8], que oferece suporte à extensibilidade e
recursos para especificações de forma modular. Analisadores
sintáticos gerados com SDF são scannerless [9], isto é, reconhecem construções léxicas ao mesmo tempo em que realizam
a análise sintática. A definição de AspectJ com SDF pode
seguir um dos três modelos:
• AJF, que é a definição mais liberal, onde somente ambiguidades reais são resolvidas, por exemplo, reservando
palavras-chave em pontos especı́ficos.
• AJC, que adiciona restrições à linguagem para ser mais
compatı́vel com o compilador oficial de AspectJ. As
restrições adicionais são em maioria relacionadas a conflitos shift-reduce no analisador sintático LALR de ajc.
• ABC, que usa palavras-chave sensı́veis ao contexto. Define a linguagem suportada pelo compilador abc.
Este trabalho apresenta uma especificação da sintaxe de
AspectJ utilizando o formalismo conhecido como Parsing
Expression Grammar (PEG), que é discutido na Seção III.
Até onde vai nosso conhecimento, esta é a primeira descrição
completa de AspectJ usando PEG.
III. PARSING E XPRESSION G RAMMARS
O sistema generativo de Chomsky, particularmente gramáticas livres de contexto (CFG, do inglês, Context Free
Grammars) e expressões regulares, foram, por muito tempo,
os formalismos mais utilizados para expressar a sintaxe de
linguagens de programação. Parsing Expression Grammars
(PEG) [3] é um novo formalismo oferecido para tal propósito.
PEGs são parecidas estruturalmente com gramáticas livres de
contexto, contendo recursos de expressões regulares e notação
Extended Backus-Naur Form.
A ideia de PEG está intimamente relacionada à construção
de analisadores top-down, que podem ser considerados como
uma forma mais natural e compreensı́vel de análise sintática.
Sintaticamente, PEGs são similares a CFGs, mas têm uma
interpretação diferente, diretamente ligada à implementação de
uma análise descendente recursiva (recursive descent parser).
Uma diferença chave entre PEG e CFG é a utilização do
operador de escolha “prioritária” (representado pelo sı́mbolo
‘/’) que, diferentemente do operador ‘ou’ (representado por
‘|’), leva em consideração a ordem na qual os padrões são
definidos.
Diferentemente de CFGs, PEGs não são ambı́guas, ou seja,
se uma palavra é “aceita”, ela possui somente uma árvore
de derivação (parse tree) válida. Isso faz com que PEGs
sejam úteis para expressar linguagens de programação, e não
linguagens naturais. PEG, assim como SDF, é scannerless, ou
seja, não é necessária análise léxica separada.
Formalmente, uma PEG pode ser definida como uma tupla
(Σ, N , P , es ) onde:
Σ
é um conj. finito de terminais.
N
é um conj. finito de não-terminais.
P
é um conj. finito de regras (parsing rules) da forma
“A ← e” onde A ∈ N e e é uma parsing expression.
es
é uma parsing expression chamada expressão inicial.
Uma parsing expression é uma expressão hierárquica similar
a uma expressão regular, que é construı́da conforme o modelo
descrito a seguir.
Uma parsing expression atômica consiste de:
• um sı́mbolo terminal;
• um sı́mbolo não-terminal; ou
• a palavra vazia λ.
Dadas parsing expressions e, e1 , e e2 , uma nova parsing expression pode ser construida usando os operadores mostrados
na Tabela I. Aspas simples ou duplas representam uma palavra
literal, e abre e fecha colchetes representam uma classe de
caracteres. O simbolo ‘.’ representa qualquer caractere.
Operador
‘’
“”
[]
.
(e)
e?
e*
e+
&e
!e
e1 e2
e1 / e2
Tipo
primário
primário
primário
primário
primário
sufixo unário
sufixo unário
sufixo unário
prefixo unário
prefixo unário
binário
binário
Descrição
String Literal
String Literal
Classe de Caracteres
Qualquer Caracter
Agrupamento
Opcional
Zero ou mais
Um ou mais
Predicado And
Predicado Not
Sequência
Escolha Priorizada
Tabela I
O PERADORES PARA CONSTRUÇ ÃO DE PARSING E XPRESSIONS
A sequência de expressões ‘e1 e2 ’ procura uma correspondência (match) de e1 imediatamente seguido por uma correspondência de e2 . Se alguma dessas correspondências falha,
a análise volta ao ponto anterior, utilizando backtracking. A
expressão de escolha priorizada ‘e1 / e2 ’ primeiro realiza uma
tentativa de correspondência com e1 , e depois com e2 do
mesmo ponto, se e1 falha. Os operadores ?, * e + são os
mesmos presentes na sintaxe de expressões regulares.
Já os operadores & e ! denotam predicados sintáticos,
e não consomem valores da entrada quando são avaliados,
somente os valores booleanos de correspondência da entrada
são utilizados.
Uma das implementações de PEG mais eficientes é a proporcionada pela ferramenta Rats!, discutida na seção seguinte.
IV. Rats!
Conforme discutido na Seção II, ferramentas para definir extensões de linguagens necessitam de suporte a extensibilidade
em diversos nı́veis. Rats! [10] é uma ferramenta para geração
de analisadores sintáticos para Java que suporta facilmente
sintaxes extensı́veis.
Gramáticas para construções de analisadores sintáticos para
Rats! são escritas em PEG, o que permite uma melhor performance do analisador quando são construı́das extensões para
gramáticas, visto que PEG não permite ambiguidade. Além
disso, gramáticas escritas para Rats! são concisas e facilmente
modificáveis. Rats! permite:
1) Usar Parsing Expression Grammars em vez de gramáticas livres de contexto, e integrar análise léxica com
análise sintática, isto é, é scannerless;
2) Organizar especificações em módulos;
3) Permitir suporte à geração automática de Árvores de
Sintaxe Abstratas (AST, do inglês Abstract Syntax Tree);
4) Prover uma interface bem definida para geração de
analisadores sintáticos extensı́veis.
Outra vantagem de um analisador sintático gerado por essa
ferramenta é que Rats! memoriza resultados intermediários,
o que garante um tempo linear na presença de lookahead
ilimitado e backtracking [11]. Por esse motivo, o analisador
sintático gerado pode ser chamado de packrat parser.
Apesar das gramáticas para Rats! serem construı́das utilizando PEG, sua sintaxe possui algumas diferenças e são mais
expressivas do que a descrição de PEG da Seção III.
Uma gramática em Rats! consiste em um módulo no nı́vel
superior, que é o módulo especificado na linha de comando
ao invocar o Rats! e zero ou mais módulos dependentes. Cada
módulo pode iniciar com várias declarações:
• Uma declaração de módulo, que especifica seu nome
completo dentro da gramática. Opcionalmente essa declaração pode ter um ou mais parâmetros, que são tratados
como nomes de outros módulos e substituidos através do
seu corpo.
• Zero ou mais declarações de dependência que especificam
como o módulo atual depende de outros módulos.
Rats! permite três tipos de declarações de dependências.
Dependências do tipo import fazem não-terminais de outros módulos referenciáveis de dentro do módulo corrente.
Dependências do tipo modify fazem as produções de outro
módulo disponı́veis para modificação no módulo atual. Cada
módulo pode ter apenas uma dependência do tipo modify.
Além disso, podem haver dependências do tipo instantiate que
instanciam outros módulos (normalmente módulos que possuem argumentos) e tornam seus nomes disponı́veis para uso
em outras dependências. Esses são recursos fundamentais para
aumentar a modularidade e extensibilidade das especificações.
Após as declarações, seguem as produções. Uma produção
escrita segundo a especificação de Rats! é da forma:
Atributos Tipo Não-Terminal = e ;
onde os Atributos são uma lista, separada por espaço, de zero
ou mais atributos da produção, Tipo é o Tipo em Java do valor
semântico, Não-terminal é o nome do não-terminal, e e é a
expressão a ser analisada. Além disso, uma expressão pode
ser rotulada com um nome, que possibilita sua modificação
por outro módulo.
Expressões podem ser construı́das utilizando os elementos
da Tabela I juntamente com os elementos da Tabela II, que são
operadores especı́ficos de Rats!. O operador é semelhante
ao operador de qualquer caracter de PEG. Já o operador { }
define uma ação semântica, semelhante às ações definidas para
gramática livres de contexto. Os outros operadores são usados
na construção de expressões. id : e constrói uma amarração
entre e, fazendo-o ser do tipo id. É possı́vel também amarrar
uma expressão a um String, utilizando o operador “”: e, e além
disso, podemos marcar uma produção utilizando o operador
< nome >, onde nome é o nome da marcação.
Operador
{}
id : e
“ ”: e
void : e
<nome> e1 ... e2
Tipo
primário
primário
prefixo unário
prefixo unário
prefixo unário
binário
Descrição
Qualquer Caracter
Ação Semântica
Amarração
Combinação de String
Valor void
Sequência
Tabela II
O PERADORES PARA CONTRUÇ ÃO DE E XPRESSIONS EM Rats!
Em uma produção, é opcional a definição de uma ação
semântica visto que Rats! constrói automaticamente a árvore
de sintaxe abstrata. Uma produção sem ação semântica deve
ser declarada do tipo genérico.
Conforme dito anteriormente, um módulo pode modificar
produções de outro módulo através da declaração modify.
Produções que adicionam novas opções a produções de outro módulo podem ser escritas utilizando o operador +=, e
definindo a posição onde ela acrescenta a nova alternativa.
Pode-se também remover opções de uma produção através
do operador -=. Finalmente, é possı́vel substituir todas as
alternativas através do operador de sobreescrever, :=.
Boa parte dos recursos de extensibilidade e facilidades para
especificações de forma modular de Rats! foram utilizadas na
definição de AspectJ que é discutida na Seção V.
V. D EFINIÇ ÃO DE A SPECT J
Como AspectJ é uma extensão da linguagem Java, sua
definição tem como base a gramática de Java. A definição
proposta neste artigo segue os moldes da gramática construı́da
pelo compilador abc [6] para Java 4.
A. Análise Léxica
A análise léxica de AspectJ é complicada pelo fato de que
existem três linguagens diferentes sendo analisadas: o código
Java normal, as declarações de aspectos e as definições de
pointcut.
O compilador abc divide o contexto da linguagem nessas três linguagens e faz com que as palavras-chave sejam
sensı́veis a sua localidade. Porém, ao utilizarmos PEG, que
é uma linguagem scannerless, optamos por implementar a
análise léxica seguindo a definição AJC vista na Seção II,
por ser uma definição mais liberal e compatı́vel com essa
caracterı́stica.
Sendo assim, neste trabalho, a análise léxica é feita juntamente com a análise sintática, com palavras-chave empregadas
em pontos especı́ficos da gramática.
B. Análise Sintática
Vimos, na Seção IV, que Rats! é uma ferramenta para
geração de analisadores sintáticos que permite extensibilidade
e modularidade. Essas caracterı́sticas foram essenciais para a
escolha dessa ferramenta para a construção da gramática de
AspectJ utilizando PEG.
A gramática de Java, base de AspectJ, que foi implementada
originalmente por Robert Grimm [10], possui a modularidade
necessária para implementação da extensão. A gramática de
AspectJ segue praticamente o mesmo esquema de modularidade da gramática de Java, estendendo-a em alguns módulos.
Os módulos para as gramáticas de Java e AspectJ foram
esquematizados conforme a Figura 1.
Figura 1.
Módulos contidos na Gramática de AspectJ
A figura mostra uma separação completa entre AspectJ
e Java. Cada identificador representa um módulo. Todas
as dependências são tratadas com modificações de módulo
(modify) ou passagem de módulos como parâmetro para os
novos módulos de AspectJ. Os módulos principais instanciam
vários módulos (instantiate) para que seus nomes possam ser
utilizados como parâmetro.
O módulo principal é identificado com o nome AspectJ. Ele
instancia vários módulos e modifica o módulo AspectJCore.
Ao fazer isso, todas as produções existentes em AspectJCore
são executadas a partir deste módulo. Os módulos instanciados
são os parâmetros necessários a AspectJCore.
Spacing é um módulo para análise léxica que contém
produções para definir o espaçamento entre cada token do
programa. Além disso, define também como se dão os comentários na linguagem. Como, nesse caso, comentários e
espaçamento de AspectJ são idênticos aos de Java, esse
módulo não é modificado.
Symbol também é um módulo que contém uma gramática
para análise léxica que contém os sı́mbolos e operadores
necessário para JavaSymbol. AspectJSymbol o recebe como
parâmetro e o modifica, acrescentando o sı́mbolo “..”.
AspectJIdentifier é um módulo contendo os identificadores especı́ficos de AspectJ. Ele recebe como parâmetro AspectJSymbol e Spacing para modificar o módulo JavaIdentifier
e contém as produções necessárias para definir alguns identificadores em AspectJ, que podem possuir o sı́mbolo ‘*’.
JavaConstant e JavaType são módulos necessários para
AspectJCore, e só se modificam em virtude dos parâmetros
AspectJSymbol, AspectJIdentifier e Spacing passados a eles.
AspectJPatterns é um módulo acrescentado à hierarquia de
AspectJ, que define as construções de patterns dentro de um
aspecto. Patterns são padrões de nomes de métodos, classes,
tipos e expressões que são usados na definição de pointcuts
dentro de um programa em AspectJ. Eles permitem, por exemplo que identificadores contenham caracteres especiais para
definição de hierarquia de classes, ou contenham métodos,
classes ou tipos que comecem, terminem ou possuam alguma
sequência de caracteres.
O módulo AspectJCore modifica o módulo JavaCore, incluindo assim a definição de todas as construções presentes
em Java. Este módulo garante a extensibilidade entre Java e
AspectJ e possui como parâmetro os módulos instanciados
anteriormente. Através do operador +=, esse módulo acrescenta a opção de se construir um aspecto, adicionando AspectDeclaration ao não-terminal TypeDeclaration. Além disso,
esse módulo também modifica o não-terminal Declaration,
dando a possibilidade de se definir pointcuts e outros aspectos
dentro de uma construção (classe, interface ou aspecto). A
última modificação feita nas produções de Java consiste em
adicionar a possibilidade de se chamar o método proceed().
Isso é feito adicionando essa possibilidade ao não-terminal
PrimaryExpression. As produções vistas na Figura 2 ilustram
as modificações descritas neste parágrafo.
No mais, o módulo AspectJCore define como se dá a estrutura sintática em AspectJ, de maneira semelhante à estrutura
definida pela gramática LALR(1) do compilador abc.
Em se tratando da tradução da gramática em si, foram feitas
poucas modificações à gramática do abc, eliminando somente
casos de recursividade à esquerda, pois PEG não permite esse
tipo de recursividade.
C. Testes
Um analisador sintático foi gerado usando a ferramenta
Rats!. O analisador consiste em uma classe Java que recebe
um programa de entrada e o analisa. Caso o programa esteja
sintaticamente correto, uma representação por meio de uma
AST é construı́da.
Para testarmos o analisador com diversas instâncias,
foi utilizado o framework JUnit [12]. Os programas de
teste são os exemplos de aspectos definidos no endereço
http://www.eclipse.org/aspectj/sample-code.html. Todos os
testes foram corretamente processados pelo analisador.
Um único problema encontrado no conjunto de testes foi a
definição de um pointcut, num dos aspectos. A definição
execution(Object !Cloneable+.clone());
Node TypeDeclaration +=
<Interface> ...
/
<Aspect> AspectDeclaration
;
Node Declaration +=
<Class> ...
/
<Aspect> AspectDeclaration
/
<Pointcut> PointCutDeclaration
;
Node PrimaryExpression +=
<Proceed> ProceedExpression
/
<Call> ...
;
Figura 2.
Produções que estendem a Gramática de Java
não é aceita pelo analisador construı́do, nem pela gramática
do compilador abc. Porém, ao substituirmos essa definição por
execution(Object (!Cloneable+).clone());
a definição passa a ser aceita.
Isso ocorre, principalmente pelo fato da linguagem AspectJ
não possuir um padrão. As diferenças entre os modelos
apresentados na Seção II, mais especificamente, entre o AJC
e o ABC, fazem com que ocorra esse “erro” de sintaxe.
Foram também construı́dos exemplos que continham propositalmente erros sintáticos, introduzidos arbitrariamente no
conjunto descrito acima. Todos os testes com esses exemplos
apresentaram o resultado esperado.
conflitos entre as gramáticas e ainda oferece recursos para
especificações modulares.
Testes de desempenho foram realizados para avaliar a velocidade e o consumo de memória, comparando o analisador
sintático apresentado em [8] e o analisador produzido neste
trabalho. Os testes foram realizados no ambiente do Eclipse
Helios, instalado na arquitetura descrita a seguir:
• Processador AMD Athlon(tm), modelo P320, Dual-core,
2100Mhz
• Memória total instalada 4 Gigabytes
• Sistema Operacional Microsoft Windows 7 de 32 bits
Como o Rats! gera um analisador na linguagem Java, o
analisador sintático gerado a partir da descrição em SDF
deveria também estar escrito em Java, para que o teste ficasse
mais justo. Assim foi usado o gerador JSGLR, que faz parte
da ferramenta Spoofax [13] e atende aos requisitos desejados.
Enquanto analisadores sintáticos produzidos pelo Rats! não
necessitam nenhuma atividade prévia à análise, o JSGLR
precisa carregar uma tabela que descreve a gramática desejada,
antes de iniciar a análise dos programas. O tempo transcorrido
e o gasto de memória para a carga dessa tabela não foram
computados nos testes comparativos.
A Tabela III apresenta resultados da comparação. Os programas em AspectJ cuja sintaxe é analisada são os mesmos
programas usados nos testes da Seção V-C. Os casos de teste
que vão do 11 ao 14 consistem em replicação de partes do
código do programa de número 8, com o objetivo de testar
arquivos mais extensos. Nenhum desses casos apresentam erro
de sintaxe, pois o objetivo é testar a performance durante toda
a análise.
Número
do
teste
11
Tamanho do
Arquivo de Teste
(kbytes)
121,444
12
220,662
VI. C OMPARAÇ ÃO COM TRABALHOS SIMILARES
13
341,884
Este trabalho tem como objetivo apresentar uma especificação de AspectJ que facilite a construção de extensões, para
permitir experimentos com a linguagem. Dessa forma, não
pode ser comparado adequadamente com o compilador ajc [5],
que não tem objetivo de extensibilidade e não oferece recursos
para isso.
A gramática usada no compilador abc [6] serviu de modelo
para a definição apresentada na SeçãoV. Mas este trabalho não
apresenta um compilador completo como o abc. Comparando
as duas abordagens, pode-se concluir que a extensibilidade
é mais facilitada com a especificação deste trabalho, pois
extensões são definidas sem a geração de conflitos que o
analisador LR do Polyglot pode gerar. Além disso, os recursos
para extensibilidade do analisador léxico do abc são muito
restritos.
A especificação de uma gramática apresentada em [8],
escrita em SDF, é a que pode ser melhor comparada com
a deste trabalho. A SDF facilita extensibilidade, sem gerar
14
395,86
Parser
JSGLR
Rats!
JSGLR
Rats!
JSGLR
Rats!
JSGLR
Rats!
Tempo de
Análise
(ms)
3409
75
6701
201
15721
164
19090
180
Memória
Gasta na Análise
(kbytes)
117133
11603
160947
18147
189294
27839
141568
71631
Tabela III
TABELA DE COMPARAÇ ÃO DE DESEMPENHO
A Tabela III apresenta o tempo transcorrido na execução
dos analisadores sintáticos quando os programas de teste são
processados, bem como a memória utilizada. Os valores são
uma média de 5 execuções. O analisador apresentado neste
trabalho foi superior ao gerado pelo JSGLR, em todos os
casos de testes, tanto em tempo de processamento quanto em
memória consumida.
É possı́vel notar uma falta de linearidade entre os valores de
tempo de procesamento e de consumo de memória, quando se
comparam os testes 8 e 10. O teste 8 é uma classe em Java que
contém grande quantidade de comandos complexos. Já o teste
10 é um aspecto que contém apenas uma grande quantidade
de pointcuts. Os analisadores consomem mais recursos em um
programa complexo em Java, do que em um aspecto contendo
apenas pointcuts. Essa discrepância é ainda mais evidente no
analisador gerado com Rats!.
Através dos resultados dos testes, pode-se concluir que
o analisador sintático apresentado neste traballho é muito
mais eficiente que o apresentado em [8], quando gerado com
JSGLR.
Na questão de desempenho, outra possibilidade é fazer uma
comparação com o analisador sintático do compilador ajc,
visto que ele é um benchmark, ou seja, possui o melhor
desempenho dentre os trabalhos similares.
VII. C ONCLUS ÃO E T RABALHOS F UTUROS
R EFER ÊNCIAS
Este trabalho apresentou uma especificação e implementação de um analisador sintático para AspectJ. Para esse
analisador, foram destacadas caracterı́sticas esperadas, como
modularidade, facilidade para extensibilidade e eficiência na
execução. A sintaxe do analisador foi baseada na especificação
utilizada no projeto abc. Foi utilizado o formalismo PEG
para descrever a especificação e a ferramenta Rats! para gerar
automaticamente um analisador sintático.
O trabalho foi comparado com abordagens semelhantes.
A definição de AspectJ encontrada que mais se aproximava
do modelo proposto foi uma especificação em SDF, que
procura reunir qualidades de alta modularidade e oferecimento
de facilidades para construção de extensões. Comparando
o analisador apresentado neste trabalho com um analisador
gerado a partir da especificação em SDF, foi possı́vel observar
uma grande diferença de desempenho. O analisador proposto
apresentou resultados muito superiores em tempo de processamento e gasto de memória. Dessa forma, concluı́mos que o
objetivo do trabalho foi satisfatoriamente cumprido.
A gramática descrita neste trabalho pode ser obtida no
endereço http://code.google.com/p/aspectj-rats/, dentro de um
projeto Eclipse. O projeto inclui ainda todos os testes de
validação e os testes comparativos, permitindo reproduzir os
resultados discutidos na Seção VI.
A modularidade da especificação proposta não foi devidamente avaliada neste trabalho. Uma definição modular pode
tornar mais fácil reaproveitar suas partes, e facilitar também a
construção de extensões. Para realizar uma avaliação do trabalho nesses quesitos, faz parte dos planos futuros a elaboração
de diversas extensões de AspectJ baseadas na especificação
proposta, avaliando o processo de construção, de modo similar
ao realizado em [8]. É importante lembrar, que apesar de
não avaliar a extensibilidade, o próprio trabalho se trata da
implementação de uma extensão de uma linguagem, da linguagem AspectJ estendida da linguagem Java, e conforme vimos
na Seção V, não houve conflitos para sua implementação de
maneira modular.
Outra tarefa que faz parte dos planos futuros é produzir
uma nova definição que englobe as caracterı́sticas de AspectJ
5, incluindo funcionalidades como anotações e generics.
[1] J. Aldrich, “Open Modules: Modular Reasoning About Advice,” in
ECOOP 2005 - Object Oriented Programming: 19th European Conference, Glasgow, UK, July 25-29, 2005. Proceedings, ser. Lecture Notes
in Computer Science, A. P. Black, Ed., vol. 3586. Springer, 2005, pp.
144–168.
[2] Éric Tanter, K. Gybels, M. Denker, and A. Bergel, “Context-aware
aspects,” in Software Composition, 5th International Symposium, SC
2006, Vienna, Austria, March 25-26, 2006, Revised Papers, ser. Lecture
Notes in Computer Science, W. Löwe and M. Südholt, Eds., vol. 4089.
Springer, 2006, pp. 227–242.
[3] B. Ford, “Parsing expression grammars: a recognitionbased syntactic foundation.” in POPL, N. D. Jones and
X. Leroy, Eds. ACM, 2004, pp. 111–122. [Online]. Available:
http://pdos.csail.mit.edu/ baford/packrat/popl04/
[4] R. Grimm, “Better extensibility through modular syntax,” in PLDI ’06:
Proceedings of the 2006 ACM SIGPLAN conference on Programming
language design and implementation. New York, NY, USA: ACM,
2006, pp. 38–51.
[5] “The AspectJ Compiler,” avaliable from URL:
http://www.eclipse.org/aspectj/doc/next/devguide/ajc-ref.html.
[6] P. Avgustinov, A. S. Christensen, L. Hendren, S. Kuzins, J. Lhoták,
O. Lhoták, O. de Moor, D. Sereni, G. Sittampalam, and J. Tibble,
“abc: an extensible aspectj compiler,” in AOSD ’05: Proceedings of the
4th international conference on Aspect-oriented software development.
New York, NY, USA: ACM, 2005, pp. 87–98.
[7] N. Nystrom, M. R. Clarkson, and A. C. Myers, “Polyglot: An extensible
compiler framework for java,” in In 12th International Conference on
Compiler Construction. Springer-Verlag, 2003, pp. 138–152.
[8] M. Bravenboer, E. Tanter, and E. Visser, “Declarative, formal, and extensible syntax definition for AspectJ. A case for scannerless generalizedlr parsing,” in Proceedings of the 21th ACM SIGPLAN Conference
on Object-Oriented Programing, Systems, Languages, and Applications
(OOPSLA’06), W. R. Cook, Ed. Portland, Oregon, USA: ACM Press,
October 2006, pp. 209–228.
[9] D. J. Salomon and G. V. Cormack, “Scannerless nslr(1) parsing of
programming languages,” in Proceedings of the ACM SIGPLAN 1989
Conference on Programming language design and implementation, ser.
PLDI ’89. New York, NY, USA: ACM, 1989, pp. 170–178. [Online].
Available: http://doi.acm.org/10.1145/73141.74833
[10] R. Grimm, “Better extensibility through modular syntax,” in
Proceedings of the 2006 ACM SIGPLAN conference on Programming
language design and implementation, ser. PLDI ’06.
New
York, NY, USA: ACM, 2006, pp. 38–51. [Online]. Available:
http://doi.acm.org/10.1145/1133981.1133987
[11] M. G. J. van den Brand, J. Scheerder, J. J. Vinju, and
E. Visser, “Disambiguation filters for scannerless generalized
lr parsers,” in Proceedings of the 11th International
Conference on Compiler Construction, ser. CC ’02. London,
UK: Springer-Verlag, 2002, pp. 143–158. [Online]. Available:
http://portal.acm.org/citation.cfm?id=647478.727925
[12] “JUnit test tool, http://www.junit.org.”
[13] L. C. L. Kats and E. Visser, “The Spoofax language workbench. Rules
for declarative specification of languages and IDEs,” in Proceedings
of the 25th Annual ACM SIGPLAN Conference on Object-Oriented
Programming, Systems, Languages, and Applications, OOPSLA 2010,
October 17-21, 2010, Reno, NV, USA, M. Rinard, Ed., 2010, pp. 444–
463.
AGRADECIMENTOS
Por bolsas de iniciação cientı́fica que foram usadas por dois
dos autores deste trabalho, agradecemos à Fapemig e ao CNPq.
Download