PLP – JavaCC
Java Compiler Compiler
Joabe Jesus - [email protected]
Prof. Augusto Sampaio
Agenda
• Compiladores
– Analisadores léxicos e sintáticos (Parsers)
• Parser generators
• JavaCC
Compiladores
• Analisadores léxicos
– Verificam se os símbolos terminais e palavras estão
de acordo com as restrições da linguagem
• Há identificadores inválidos?
• Há símbolos (caracteres) inválidos
• Analisadores sintáticos (Parsers)
– Programas que recebem como entrada um arquivo
fonte e diz se ele está correto sintaticamente,
segundo uma gramática pré-definida.
Parsers
• Há dois grupos de parsers
– Top-down
– Bottom-up
Parsers
• Por que usar um parser generator?
– Implementar um parser ‘manualmente’ (passo-apasso) pode ser uma tarefa muito trabalhosa...
Parsers generators
• Um Parsers generator é um programa que
recebe como entrada um arquivo de
especificação da gramática a ser aceita pelo
parser e retorna um parser que reconhece esta
gramática
– O formato do arquivo de especificação da gramática
depende muito do tipo de parser gerado (top-down ou
bottom-up)
Parsers generators
• Existem vários geradores de parser
–
–
–
–
–
JavaCC
JLex & Cup
AntLR
SableCC
…
É um dos mais populares na
comunidade Java, sendo
suportado hoje pela comunidade
java.net
Tem um dos melhores suportes a
gramáticas em EBNF (Extended
Backus Naur Form) e gera
estrutura OO da AST (Abstract Syntax
Tree) além de classes utilitárias
usando o padrão Visitor.
JavaCC
JavaCC
• Gerador de parser 100% Java
– O mais utilizado pela comunidade Java
• Desenvolvido inicialmente pela Sun
– Hoje é mantido pela java.net
• É um parser top-down
– Mais fácil de depurar
• Utiliza uma sintaxe muito próxima de Java
JavaCC
• Desvantagens
– Mistura código Java com a gramática
– Não checa a corretude do código Java inserido
– Pode gerar classes que não compilam
JavaCC
• Inclui um pré-processador para geração de árvores
sintáticas (jjTree)
• Possui um repositório de gramáticas bastante extenso
disponível – inclui linguagens como Java, C, C++, Perl,
etc
• Possui uma interface gráfica fácil de usar
• Definições léxicas e sintáticas em um único arquivo
• Não aceita ambigüidades.
– Ex: A gramática não pode possuir recursão à esquerda.(ex: expr:=
expr ‘+’ expr)
Gramáticas em JavaCC
•
Uma gramática JavaCC possui a seguinte estrutura:
– Opções do Parser (Não obrigatório)
– Definição da classe do Parser
– Definição dos Tokens (Componente Léxico)
• Terminais
– Definição das Produções (Componente Sintático)
• Ações semânticas associadas
• Não-Terminais
Opções do parser
• STATIC – diz se os métodos do parser serão estáticos (default: true)
• LOOKAHEAD – informa o nível de profundidade do lookahead
(default: 1)
• DEBUG_PARSER – instrui o parser a registrar todas as
informações durante o parsing do arquivo (default: false)
• DEBUG_LOOKAHEAD – instrui o parser a registrar também as
tentativas de lookahead (default: false)
Mais opções
• UNICODE_INPUT – informa se a entrada usa a
codificaçõo UNICODE
• OUTPUT_DIRECTORY – seta o diretório onde os
arquivos java serão gerados (o default é o atual)
• FORCE_LA_CHECK- força a checagem do lookahead
em todos os “choice points”, independente da
especificação explícita do lookahead (default: false)
Definição do Parser
• Este trecho define a classe do Parser. Nesta classe,
podem ser definidos métodos e variáveis auxiliares. O
formato é o seguinte:
PARSER_BEGIN(parser_name)
...
class parser_name ...{
...
}
...
PARSER_END(parser_name)
Definição dos tokens
• Serve para especificar os tipos de tokens e as
expressões regulares associadas
• Nesta seção são descritas as palavras
reservadas
TOKEN:
{
< NUMBER: (<DIGIT>)+ ( "." (<DIGIT>)+ )? >
| < DIGIT: ["0"-"9"] >
| < EOL: "\n" >
}
Definição das produções
• Obedecem o seguinte formato:
tipoRetorno nomeProducao(listaParametros):
{
Declaração de variáveis,
código Java
invocação de métodos, etc
}
{
subProducao1()
{ ação semântica correspondente }
[lista de subProducoes]
}
Código Java. Em geral,
corresponde a montagem da
árvore
Exemplo: EBNF
•
Dada a gramática na forma EBNF
expr :=
|
|
|
|
|
number
expr '+'
expr '-'
expr '*'
expr '/'
- expr
expr
expr
expr
expr
number := digit+ ('.' digit+)?
digit := '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7‘
| '8' | '9'
Exemplo: Gramática
options
{
LOOKAHEAD=2;
STATIC=false;
}
Lembre-se de que o JavaCC
não permite recursão à
esquerda, por isso, é
necessário modificar a
gramática antes de traduzí-la.
PARSER_BEGIN(Arithmetic)
public class Arithmetic
{
}
PARSER_END(Arithmetic)
Exemplo: JavaCC
SKIP:
{
" "
| "\r"
| "\t"
}
TOKEN:
{
< NUMBER: (<DIGIT>)+ ( "." (<DIGIT>)+ )? >
| < DIGIT: ["0"-"9"] >
}
Exemplo: JavaCC
double expr(): {}
{
term() ( "+" expr() | "-" expr() )*
}
double term(): {}
{
unary() ( "*" term() | "/" term() )*
}
Exemplo: JavaCC
double unary(): { }
{
"-" a=element() |
}
double element(): {}
{
<NUMBER>
}
a = element()
Exercício
• Altere o exemplos dados para que estes
possam reconhecer as seguintes expressões:
– parênteses “(“ , “)” -> expr ::= (expr)
– exponenciação -> expr ::= expr ^ expr
• Onde a ordem de precedência é: parênteses >
exponenciação
Referências
•
•
•
•
•
•
https://javacc.dev.java.net/
https://javacc.dev.java.net/doc/docindex.html
http://www.cs.aau.dk/~bt/SPOF07/Lecture4.htm
http://www.antlr.org/works/index.html
http://en.wikipedia.org/wiki/Top-down_parsing
http://en.wikipedia.org/wiki/Bottom-up_parsing
PLP – JavaCC
Java Compiler Compiler
Joabe Jesus - [email protected]
Prof. Augusto Sampaio
Download

javacc