plp – javacc java compiler compiler joabe jesus - [email protected]@cin.ufpe.br prof. augusto...
TRANSCRIPT
PLP – JavaCCJava Compiler Compiler
Joabe Jesus - [email protected]. Augusto Sampaio
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
• Por que usar um parser generator?– Implementar um parser ‘manualmente’ (passo-a-
passo) 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
• 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):{ código Java}{ subProducao1() { ação semântica correspondente } [lista de subProducoes]}
Declaração de variáveis, invocação de métodos,
etc
Código Java. Em geral, corresponde a montagem da
árvore
Exemplo: EBNF
• Dada a gramática na forma EBNFexpr := 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; }
PARSER_BEGIN(Arithmetic) public class Arithmetic { }
PARSER_END(Arithmetic)
Lembre-se de que o JavaCC não permite recursão à
esquerda, por isso, é necessário modificar a
gramática antes de traduzí-la.
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() | a = element()}
double element(): {} { <NUMBER>}
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 – JavaCCJava Compiler Compiler
Joabe Jesus - [email protected]. Augusto Sampaio