270 likes | 408 Views
Análise Léxica. Prof. Alexandre Monteiro Baseado em material cedido pelo Prof. Euclides Arcoverde Recife. Contatos. Prof. Guilherme Alexandre Monteiro Reinaldo Apelido: Alexandre Cordel E-mail/ gtalk : alexandrecordel@gmail.com greinaldo@fbv.edu.br
E N D
Análise Léxica Prof. AlexandreMonteiro Baseadoem material cedidopelo Prof. EuclidesArcoverde Recife
Contatos • Prof. Guilherme Alexandre Monteiro Reinaldo • Apelido: Alexandre Cordel • E-mail/gtalk: alexandrecordel@gmail.com greinaldo@fbv.edu.br • Site: http://www.alexandrecordel.com.br/fbv • Celular: (81) 9801-1878
JFlex • É um gerador de analisadores léxicos escrito em Java, baseado no flex para C • Também é uma melhoria do Jlex • Pode ser encontrado em http://jflex.de/ • Constrói o analisador léxico a partir de um arquivo de especificação dado como entrada • Processo visto nos slides da aula anterior • Recebe arquivo de entrada normalmente com extensão .lex ou .flex • A partir desse arquivo vai ser gerado um analisador léxico capaz de reconhecer os caracteres de determinada linguagem • Gera uma classe que faz a análise léxica
JFlex • Gerador automático de analisadores léxicos na linguagem Java JFlex Especificação Classe do Lexer
Especificando um Lexer • A especificação é dividida em 3 partes que são separadas por “%%” Código do usuário %% Opções do JFlex + Declarações de Macros %% Regras léxicas
Parte 1 – Código do Usuário • É inserido diretamente no topo do arquivo gerado (não é inserido dentro da classe) package br.fbv.examples.jflex; import java.util.Hashtable; %% ...
Parte 1 – Código do Usuário • Por exemplo, pode ser usado para: • Definir o pacote ao qual o lexer vai pertencer • Definir imports • Definir a classe Token ou qualquer outra classe, desde que não seja pública • Não recomendo • Comentários de documentação
Parte 2 – Diretivas e Macros • Situada entre o primeiro sinal “%%” e o segundo sinal “%%” • Pode conter opções do JFlex ou macros de expressões regulares • Podem vir alternadas e em qualquer ordem • Veremos separadamente...
Parte 2.1 – Opções • Geralmente definem detalhes de como será a classe gerada (para funcionar como lexer) • Nome da classe, atributos adicionais, etc. ... %% %class Lexer %% ...
Parte 2.1 – Algumas Opções • %class <name> – define o nome da classe que vai ser gerada • Se não definir a classe se chamará Yylex • %{ e }% – delimitam código Java a ser inserido dentro da classe do lexer • Ex: Atributos e métodos adicionais (ex.: main) • %cup – torna o arquivo gerado compatível com o gerador de parsers CUP
Parte 2.1 – Algumas Opções • %function <name> – define o nome da função que retorna o próximo token • Se não for definida, será yylex() • %type <class-name> – define qual classe (já existente) irá representar os tokens • Ou seja, qual será o tipo de retorno da função acima • %line– ativa o contador de linhas (no atributo yyline) • %column – ativa o contador de colunas (yychar)
Parte 2.1 – Outras Opções • Existem também opções para: • Tratamento de exceção • Criação de estados léxicos • Tornar a classe pública • etc.
Parte 2.2 – Macros • Definem nomes para expressões regulares particulares ... %% %class Lexer ALPHA=[A-Za-z_] DIGIT=[0-9] %% ...
Parte 2.2 – Macros • As macros são definições auxiliares, mas não representam tokens • Podem ser usadas na definição deles, na parte 3 • Para usar a definição de uma macro, deve-se delimitar seu nome por chaves • Exemplo de uma macro definida a partir de outra ALPHA_NUMERIC={ALPHA}|{DIGIT}
Parte 3 – Regras • Seção após o segundo “%%” que especifica regras léxicas no formato • <expressão regular> { <código Java> } ... %% ... %% [0-9] {System.out.println(“Digito encontrado”);}
Parte 3 – Regras • As regras podem ser criadas com uma expressão regular pura ou usar macros • A ação associada à expressão regular pode ser qualquer código Java • Atenção: Esse código (assim como o da opção “%{“ na segunda parte) não é verificado pelo JFlex – ele é apenas copiado fielmente para a classe!
Parte 3 – Regras • Para expressões que representam tokens, a regra deve ter um “return” passando o token • Se for uma expressão que representa comentários ou espaço em branco, a ação não deve retornar valor • Se for preciso recuperar o lexema (como um objeto String), basta chamar a função yytext()
Parte 3 – Regras • Exemplo ... %% "+" { return new Symbol(sym.MAIS); } [0-9]+ { return new Symbol(sym.NUMERO, yytext()); } "//"[^\n] { /* representa um comentário portanto, não faz nada */ }
Gerando o Lexer • Primeiramente, deve-se salvar a especificação para um arquivo • Não é necessário salvar com uma extensão específica, mas é comum usar “.flex”
Gerando o Lexer • Baixe o JFlex no site • http://jflex.de/ • Arquivo de nome “jflex-<versão>.zip” • Descompacte o arquivo • Serão gerados vários subdiretórios, como • \doc – tem o manual • \examples – tem exemplos de uso do JFlex • \lib – tem a versão compilada do JFlex • \src – tem o código fonte do JFlex
Gerando o Lexer • Basta usar a versão compilada do JFlex • Arquivo JFlex.jar na pasta \lib • Para gerar o lexer a partir de um arquivo de especificação, use o comando • Um arquivo “.java” será criado no diretório atual > java -jar JFlex.jar <nome-do-arquivo>
Gerando o Lexer • Se usar o mesmo comando sem passar o arquivo, uma janela se abrirá • Escolhe o arquivo de especificação (com extensão “.flex”) e o diretório de saída • Um arquivo “.java” será criado no diretório escolhido > java –jar JFlex.jar
Gerando o Lexer • Coloque o arquivo “.java” gerado no seu projeto (do Netbeans/Eclipse, por exemplo) e compile • Erros de compilação podem acontecer na classe por conta de trechos de código errados colocados na especificação • Ajuste a especificação, gere novamente a classe e compile-a novamente no seu projeto
Exemplo • Há exemplos de uso no próprio JFlex. • Implementação dos tokens da linguagem XPR-1 • Linguagem para expressões inteiras, como no exemplo: def myVar = (10 + 3) - 4; myVar * myVar; //imprime o resultado! 19 + 10 * myVar; //imprime o resultado!
Referências (Java) • Site do JFlex • http://jflex.de • Manual do JFlex • http://jflex.de/manual.html