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: [email protected]
[email protected]

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
3
JFlex

Gerador automático de analisadores léxicos na linguagem
Java
Especificação
JFlex
Classe do
Lexer
4
Especificando um 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
6
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;
%%
...
7
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
8
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...
9
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
%%
...
10
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
11
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)
12
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.
13
Parte 2.2 – Macros

Definem nomes para expressões regulares particulares
...
%%
%class Lexer
ALPHA=[A-Za-z_]
DIGIT=[0-9]
%%
...
14
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}
15
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”);}
16
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!
17
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()
18
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 */ }
19
Gerando o Lexer
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”
21
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
22
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
> java -jar JFlex.jar <nome-do-arquivo>

Um arquivo “.java” será criado no diretório
atual
23
Gerando o Lexer

Se usar o mesmo comando sem passar o arquivo, uma
janela se abrirá
> java –jar JFlex.jar

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
24
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
25
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!
26
Referências (Java)

Site do JFlex
- http://jflex.de

Manual do JFlex
- http://jflex.de/manual.html
27
Download

Aula 4 (08/04/2015)