Análisis Léxico usando JFlex

Al realizar una tarea sobre el Análisis Léxico, me pude dar cuenta lo difícil que es encontrar un ejemplo que muestre como utilizar la herramienta JFlex. En casi la totalidad de los ejemplos, se realiza en conjunto el análisis sintáctico

En esta publicación se dejará constancia de un ejemplo sencillo de cómo realizar un análisis léxico con JFlex.

Como requisito para este ejemplo, se debe tener Java y JFlex instalado y configurado correctamente.

Crear la clase TokenPersonalizado con el siguiente código:


// Clase que será utilizada para devolver los tokens
public class TokenPersonalizado {

  String _token;
  String _lexema;

  public String getLexema(){
    return this._lexema;
  }

  public String getToken(){
    return this._token;
  }

  TokenPersonalizado (String lexema, String token){
    this._lexema = lexema;
    this._token = token;
  }

  public String toString(){
    return "Lexema: " + this._lexema + " Token: " + this._token + ";";
  }
}

Luego, se debe de crear un archivo con extensión flex, el cual será el que tendrá las reglas para el Análisis Léxico.

He comentado el código en las diferentes secciones como para tomar una idea de que es lo que se realiza en cada una, sin embargo el mejor apoyo es la documentación oficial.


/* Sección de declaraciones de JFlex */
%%
%public
%class AnalizadorLexico
%{

 /* Código personalizado */

 // Se agregó una propiedad para verificar si existen tokens pendientes
 private boolean _existenTokens = false;

 public boolean existenTokens(){
 return this._existenTokens;
 }

%}

 /* Al utilizar esta instrucción, se le indica a JFlex que devuelva objetos del tipo TokenPersonalizado */
%type TokenPersonalizado

%init{
 /* Código que se ejecutará en el constructor de la clase */
%init}

%eof{

 /* Código a ejecutar al finalizar el análisis, en este caso cambiaremos el valor de una variable bandera */
 this._existenTokens = false;

%eof}

/* Inicio de Expresiones regulares */

 Digito = [0-9]
 Numero = {Digito} {Digito}*
 Letra = [A-Za-z]
 Palabra = {Letra} {Letra}*
 Simbolo = "*"|"+"|"-"|"/"|"#"
 Espacio = " "
 SaltoDeLinea = \n|\r|\r\n

/* Finaliza expresiones regulares */

%%
/* Finaliza la sección de declaraciones de JFlex */

/* Inicia sección de reglas */

// Cada regla está formada por una {expresión} espacio {código}

{Numero} {
 TokenPersonalizado t = new TokenPersonalizado(yytext(), "NUMERO");
 this._existenTokens = true;
 return t;
}

{Palabra} {
 TokenPersonalizado t = new TokenPersonalizado(yytext(), "PALABRA");
 this._existenTokens = true;
 return t;
}

{Simbolo} {
 TokenPersonalizado t = new TokenPersonalizado(yytext(), "SIMBOLO");
 this._existenTokens = true;
 return t;
}

{Espacio} {
 // Ignorar cuando se ingrese un espacio
}

{SaltoDeLinea} {
 TokenPersonalizado t = new TokenPersonalizado("Enter", "NUEVA_LINEA");
 this._existenTokens = true;
 return t;
}

Por último se creará una clase que tendrá la lógica necesaria para leer el contenido de un archivo y pasar la información a JFlex para su análisis. El archivo tendrá de nombre PruebaJFlex.

import java.io.BufferedReader;
import java.io.FileReader;

public class PruebaJFlex {

  public static void main(String[] args) {

  try{

  // Asignación del nombre de archivo por defecto que usará la aplicación
  String archivo = "prueba.txt";

  // Se trata de leer el archivo y analizarlo en la clase que se ha creado con JFlex
  BufferedReader buffer = new BufferedReader(new FileReader(archivo));
  AnalizadorLexico analizadorJFlex = new AnalizadorLexico(buffer);

  while(true){

  // Obtener el token analizado y mostrar su información
  TokenPersonalizado token = analizadorJFlex.yylex();

  if (!analizadorJFlex.existenTokens())
   break;

  System.out.println(token.toString());
 }
 }
 catch (Exception e){
   System.out.println(e.toString());
 }
 }
}

Para probar el desarrollo, es necesario un archivo prueba.txt que tendrá la siguiente información.


1777*
#*1
*#06#
a123
12345
este es un
ejemplo
de
analisis
lexico
con
JFlex

¿Y que pasó con el IDE?

Una de las cosas que me he percatado, es que normalmente se buscan soluciones orientadas a la herramienta o IDE que se este utilizando. Sin embargo al hacerlo, muchas veces llegamos a ignorar el proceso que se debe de realizar en caso no se tenga ese IDE disponible.

Para ejemplificarlo de mejor manera, colocaremos todos los archivos que se han creado durante este ejemplo en una misma carpeta.

En una ventana de comandos se ejecutará lo siguiente, tomando en consideración estar en la misma carpeta que los fuentes o colocar la ruta completa al momento de referirse al archivo.


jflex AnalizadorLexico.flex

Generación Analizador Léxico

Al ejecutarse el comando, JFlex crea el código java necesario para realizar el análisis léxico según las reglas que se establecieron en el archivo AnalizadorLexico.flex.

Para compilar el código fuente, se utiliza la instrucción javac.


javac PruebaJFlex.java

El compilador no mostrará ningún mensaje si la compilación se realiza con éxito.

Compilación Java

Para ejecutar el programa se utiliza la instrucción java.


java PruebaJFlex

Al ejecutarse, mostrará los diferentes Tokens que ha reconocido del archivo prueba.txt.

Resultado al momento de ejecución

Con estos sencillos pasos, se ha logrado mostrar el funcionamiento de un analizador léxico creado con la herramienta JFlex.


Icono utilizado en la Imagen destacada, “Sports Hand Biceps Icon” gracias a Icons8.

13 respuestas a “Análisis Léxico usando JFlex”

  1. […] Crear un nuevo archivo con extensión flex (puedes utilizar el código del ejemplo Análisis Léxico usando JFlex). […]

    Me gusta

  2. Este mismo codigo sirve para hacer o efectuar operaciones con su orden especifico, por ejemplo 2+3*5, donde primero se haga la multiplicacion y luego la suma.

    Gracias

    Me gusta

  3. Genial el artículo y el otro de cómo integrarlo con SublimeText.
    Ejemplo sencillo y explicado paso a paso, me ha sido de gran ayuda para empezar.
    Muchas gracias,
    Antonio B.

    Me gusta

  4. Buena Jonhy 👍, No sabia que tenias blog… pero a la próxima te pido los archivos solo pa descargarlos jajajaja, Saludos 😁

    Le gusta a 1 persona

    1. Ya le tomé foto al chat de que vas a iniciar un blog de angular!

      Le gusta a 1 persona

  5. Hola que tal, tienes la idea de que muestre solo las vocales del texto que es ingresado en el archivo de prueba. Saludos

    Me gusta

  6. Todos los archivos de este ejemplo se guardan como ,flex me salen error al compilar la pruebaJFLEX

    Me gusta

    1. Que tal Andres, puedes compartir los errores que te están generando, así tu comentario es más constructivo y específico. Hasta el momento no habían reportado inconvenientes 😉

      Me gusta

  7. Buena noche, he intentado todo y no logro solucionar estos probelmas:
    C:\jflex\Ejercicio>javac PruebaJFlex.java
    PruebaJFlex.java:8: error: cannot find symbol
    AnalizadorLexico analizadorJFlex = new AnalizadorLexico(buffer);
    ^
    symbol: class AnalizadorLexico
    location: class PruebaJFlex
    PruebaJFlex.java:8: error: cannot find symbol
    AnalizadorLexico analizadorJFlex = new AnalizadorLexico(buffer);
    ^
    symbol: class AnalizadorLexico
    location: class PruebaJFlex
    PruebaJFlex.java:11: error: cannot find symbol
    TokenPersonalizado token = analizadorJFlex.yylex();
    ^
    symbol: class TokenPersonalizado
    location: class PruebaJFlex
    3 errors

    Me gusta

    1. Hola, el ejemplo se realizó asumiendo que todos los archivos se encuentran en la misma carpeta o que pertenecen al mismo paquete. Podrías revisar si se creó el archivo AnalizadorLexico.java al ejecutar la instrucción jflex AnalizadorLexico.flex, adicionalmente que este se encuentre en la misma carpeta que PruebaJFlex.java

      Me gusta

      1. si se creo el .java, el problema viene cuando quiero correr el javac PruebaJFlex.java ya que es donde arroja el error. dude si tenia mal las variables de entorno pero lo hic tal cual lo mencionas. gracias por tu respuesta

        Me gusta

      2. Si, parece que no logra hacer esa referencia al fuente, en el ejemplo todos los archivos están en la misma carpeta y no pertenecen a algún namespace o paquete declarado explicitamente, debido a esta razón es que logra encontrarlo y compilar

        Me gusta

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

A %d blogueros les gusta esto: