Utilização do JavaCC na construção de um compilador
Colaboração: Rubens Queiroz de Almeida
Data de Publicação: 31 de Julho de 2004
O programa JavaCC é um gerador de analisador sintático que
produz código Java. Ele permite que uma determinada linguagem
seja definida de maneira simples, por meio de uma notação
semelhante à EBNF. Como saída produz o código-fonte de algumas
classes Java que implementam os analisadores léxico e sintático
para aquela linguagem. Provê também maneiras de incluir,
junto à definição da linguagem, código Java para, por exemplo,
construir-se a árvore de derivação do programa analisado.
O JavaCC foi inicialmente desenvolvido pela Sun que depois
de algum tempo passou seu desenvolvimento para a Metamata
Inc. que, depois, foi incorporada pela Webgain Inc. Sua
versão encontra-se num repositório da própria Sun. Para
os interessados em conhecer melhor o JavaCC, sua página na
Internet é https://javacc.dev.java.net/. Na página pode-se
encontrar ainda um link para uma série de gramáticas prontas
para utilização pelo JavaCC. São gramáticas, por exemplo,
de Java, C, C++, SQL, HTML, e muitas outras.
O JavaCC define uma linguagem própria para descrição,
em um único arquivo, do analisador léxico e do analisado
sintático. Iniciando com o analisador léxico, esta linguagem
permite que cada token seja definido na forma de uma expressão
regular que pode ser tão simples como
TOKEN : {
< CLASS: "class" >
}
ou mais complexos como
TOKEN : {
< string_constant: // constante string como "abcd bcda"
"\""( ~["\"","\n","\r"])* "\"" >
}
Em ambos os casos, os tokens definidos entre < > serão
utilizados como constantes inteiras, acessíveis dentro do
analisador léxico. Além de tokens, podem ser definidos no
analisador léxico quais caracteres ou expressões devem ser
ignorados e também os tokens especiais que são tokens que não
são passados para o analisador sintático mas são armazenados
e podem ser recuperados a partir de um token normal.
As declarações para o analisador sintático correspondem às
produções da gramática que se deseja implementar. O JavaCC
utiliza a técnica descendente recursiva de análise. Nessa
abordagem cada não terminal da gramática é implementado através
de um método que, quando chamado, procura reconhecer na entrada
a estrutura do não terminal.
Seguindo a filosofia da análise descendente recursiva, as
declarações dos não terminais são parecidas com a declaração de
um método. A diferença é que o corpo do não terminal possui as
produções descritas através de seqüências de tokens e estruturas
de repetição, escolhas ou opcionais. Um exemplo simples retirado
dos exemplos do próprio JavaCC é mostrado a seguir. Nele,
além da produção propriamente dita, associou-se código Java
que é executado quando ocorre o casamento da entrada com uma
parte da produção.
void Input() : { int count; } {
count=MatchedBraces() <EOF> { System.out.println("The levels
of nesting is " + count); }
}
int MatchedBraces() : { int nested_count=0; } {
<LBRACE> [ nested_count=MatchedBraces() ] <RBRACE> { return
++nested_count; }
}
O código associado às produções podem ser bem mais complexos.
Pode-se armazenar o valor dos tokens reconhecidos e pode-se
ter até mesmo blocos "try/catch", como em Java. Em geral,
o código associado à produção é utilizado para construir-se
a árvore sintática do programa analisado.
Existem também programas que, trabalhando junto com o Javacc,
auxiliam na geração da árvore sintática e das classes para
fazer as visitas aos nós dessa árvore. O próprio JavaCC possui
o JJTree. Ele é um pré-processador para o arquivo da gramática
(sem código associado às produções), que insere o código
necessário para a criação da árvore sintática. O resultado é
um arquivo que deve, então, ser processado pelo JavaCC. Através
de certas anotações no arquivo original, processado pelo JJTree
o programador pode de certo modo customizar a criação da árvore.
Resumindo, o JavaCC é uma ferramenta bastante poderosa,
flexível e com um pouco de prática, fácil de utilizar. Além
disso, seu extenso uso pela comunidade tem disponibilizado
diversas facilidades extras como ferramentas e gramáticas que
o tornam ainda mais atrativo.
A editora Novatec acabou de publicar o livro "Como Construir um
Compilador Utilizando Ferramentas Java" de autoria do professor
Márcio Delamaro, que mostra, com detalhes, todos os passos da
utilização do JavaCC no desenvolvimento de um compilador. O
livro tem, ainda, uma abordagem interessante para abordar a
geração de código, mostrando como gerar código para a própria
JVM (Máquina Virtual Java).
Saiba mais sobre o livro em http://novateceditora.com.br/livros/compilador/