Está en la página 1de 6

23/03/2014

JFlex
• Es un generador de analizadores lexicográficos
• Esta desarrollado en Java y genera
Diseño de compiladores analizadores en código Java
• Es una reescritura de la herramienta JLex, la
JFlex cual es una reescritura de la herramienta
lex/flex para Unix
• Esta pensado para ser usado en conjunto con
el generador de parsers LALR CUP

JFlex Funcionamiento
• Es open source • Entrada
• Puede ser descargado de la pagina del curso o del – Archivo con la especificación del scanner
sitio de JFlex
– http://jflex.de/download.html • Salida
• Puede ser utilizado en forma standalone o – El analizador léxico (scanner) Texto del
integrado con Eclipse, a través de una tarea ANT
o de la herramienta de gestión de proyecto – Escrito en código Java programa

MAVEN

Scanner.class
• Información detallada del funcionamiento se JFlex javac
puede encontrar en el manual en línea:
– http://jflex.de/manual.html Especificacion.lex Scanner.java

Lista de
tokens

Archivo de especificación Código de usuario


• Código de usuario • Definición de packages
– Copiado directamente al scanner
• Importaciones necesarias
• %%
• Cualquier código de ayuda necesario para que el
• Directivas JFlex
scanner funcione correctamente
– Definen macros, nombres de estados
• %% • Generalmente contiene código utilizado desde las
• Reglas del analizador acciones realizadas al encontrar un token
– Expresiones regulares package uy.edu.fing.compiladores.obligatorio
– Cambios de estado import java.util.Stack;
– Acciones cuando se localiza un token
public void debug(String texto) {
System.out.println(texto);
}

1
23/03/2014

Directivas JFlex Directivas JFlex


• Directivas: Controlan el comportamiento de JFlex • Definiciones de estado
– %line: Prende el conteo de líneas – %state nombre-de-estado
– %char: Prende el conteo de caracteres
– %class class-name: Cambia el nombre de la clase • Definiciones de macro
generada – nombre-de-macro = expresion regular
– %cup: Activa la compatibilidad con CUP
– %type token-class-name: Clase usar para el Token
– %public: Hace que la clase generada es publica
– %function read-token-method
– %scanerror exception-type-name

Expresiones regulares Macros


r$ match reg. exp. r at end of a line • ALPHA=[A-Za-z_]
. (dot) any character except the newline
"..." verbatim string • DIGIT=[0-9]
{name} macro expansion
* zero or more repetitions
• ALPHA_NUMERIC={ALPHA}|{DIGIT}
+ one or more repetitions • IDENT={ALPHA}({ALPHA_NUMERIC})*
? zero or one repetitions
(...) grouping within regular expressions • NUMBER=({DIGIT})+
a|b match a or b
class of characters - any one character enclosed in
• WHITE_SPACE=([\ \n\r\t\f])+
[...]
brackets
a–b range of characters
[^…] negated class – any one not enclosed in brackets

Reglas Acciones
• Estructura de las reglas • Escritas en código Java
– [estados] regexp { acción (código java) } • Puede utilizar métodos y variables especiales
– regexp: Describe como detectar los tokens provistos por JFlex
– Prioridad para el matcheo de la regla: El string – yytext(): Retorna el lexema del token actual
mas largo – yyline: Retorna el numero de línea
– Si para el mismo largo tenemos mas de una • Transiciones de estado
concordancia: La primera regla es la que se utiliza
– yybegin(nombre-estado): Le indica a JFlex para
• Importante: saltar al nuevo estado
– Las reglas deben matchear toda posible entrada – YYINITIAL: Nombre que le da JFlex al estado inicial

2
23/03/2014

Cambios de estado Cambios de estado


<YYINITIAL> {NUMBER} {
return new Symbol(sym.NUMBER, yytext(), yyline));
}
YYINITIAL COMMENTS
<YYINITIAL> {WHITE_SPACE} { }

<YYINITIAL> "+" {
‘//’ return new Symbol(sym.PLUS, yytext(), yyline);
^\n
}
<YYINITIAL> "-" {
return new Symbol(sym.MINUS, yytext(), yyline);
}
<YYINITIAL> "*" {
return new Symbol(sym.TIMES, yytext(), yyline);
\n }
...
<YYINITIAL> "//" { yybegin(COMMENTS); }
<COMMENTS> [^\n] { }
<COMMENTS> [\n] { yybegin(YYINITIAL); }
<YYINITIAL> . { return new Symbol(sym.error, null); }

Contador de líneas: lineCount.lex Contador de líneas: lineCount.lex


import java_cup.runtime.Symbol; java JFlex.Main lineCount.lex
%%
%cup text
%{ lineCount.lex JFlex Yylex.java
private int lineCounter = 0;
%} Lexical
javac
analyzer
%eofval{
System.out.println("line number=" + lineCounter);
return new Symbol(sym.EOF); javac *.java
Main.java tokens
%eofval}

NEWLINE=\n
%%
sym.java
<YYINITIAL>{NEWLINE} {
lineCounter++;
}
<YYINITIAL>[^{NEWLINE}] { } JFlex y JavaCUP deben estar en el CLASSPATH, junto con cualquier otra
biblioteca necesaria para que el programa funcione

Contador de líneas: lineCount.lex Un ejemplo


import java.io.*;

public class Main {


• Un “compilador” sencillo de expresiones
public static void main(String[] args) {
Symbol currToken;
• Soporta +, -, * y /
try {
FileReader txtFile = new FileReader(args[0]);
• Maneja enteros, flotantes e identificadores
Yylex scanner = new Yylex(txtFile);
do { • Construiremos el analizador léxico y el
currToken = scanner.next_token();
// do something with currToken
analizador sintáctico
} while (currToken.sym != sym.EOF);
• Lo vamos a embeber dentro de un proyecto
} catch (Exception e) {
throw new RuntimeException("IO Error (brutal exit)” +
Eclipse (para posterior reutilización)
e.toString());
}
}
}

3
23/03/2014

Proyecto Eclipse
• Creamos un proyecto Eclipse estándar
(Aplicación Java de consola)
– Separamos directorios src (fuentes) y bin (clases)
– Creamos un directorio lib (para almacenar
bibliotecas externas)
– Creamos una carpeta “language” para almacenar
los archivos relacionados con JFlex y Cup

Sección “Java” del compilador


Relacionada al modelado del
lenguaje y al control del Biblioteca de soporte
proceso de compilación utilizada para la ejecución del
programa (Al ejecutar el
parse en runtime
necesitamos esto)

Todo lo relacionado a la
generación de los elementos
de análisis (léxico y sintáctico)
va en esta carpeta

Físicamente, la dependencia
anterior va en esta carpeta

4
23/03/2014

Archivo con la especificación


sintáctica del lenguaje (para
CUP)

Archivo con la especificación


léxica del lenguaje (para
JFlex)

Script ANT para la ejecución


del CUP y JFlex

Modelado del lenguaje


El proceso de análisis genera
esta estructura para posterior
procesamiento

Clases generadas por el


proceso de análisis (léxico y
sintáctico)

Tester

5
23/03/2014

Fuente de JFlex

Modelo del lenguaje


Representación intermedia

Fuente de JFlex Fuente de CUP

Fuente de CUP

Que hace nuestro compilador?


• Leer el fuente (en este caso un string, pero puede
ser un archivo)
• Analizarlo lexicalmente
• Analizarlo sintácticamente
• Construir una estructura que nos permita
procesar lo leído
– En este caso, solo lo recorremos para mostrarlo en
otro formato
• Nuestro “compilador” es mas bien un “traductor”

También podría gustarte