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.