Agradecimientos:


  • Profesor Helmuth Trefz.

Esta sección hace una breve descripción de como usar el JLex.


El Jlex es una generador de analizadores léxicos diseñado para Java, creado en la
Universidad de princeton. Existe una versión diseñada para C la cual tendrá mas
adelante su propio espacio.

la página oficial es la siguiente:
http://www.cs.princeton.edu/~appel/modern/java/JLex/

Lo primero que hay que hacer es descargarse las clases y compilarlas, sin embar-
go cuando yo estaba aprendiendo tenia muchos problemas y pienso que lo mejor
y más práctico es tener al alcance las clases ya compiladas.

En este enlace se encuentra el paquete de clases del JLex, dichas clases deben
agregarse en la misma carpeta donde se encuentre el proyecto en Java a diseñar.


La filosofía del JLex, como analizador léxico orientado a Objetos, consiste en ir mos-
trando Tokens por Tokens según se les encuentre en el buffer. Para eso es necesa-
rio que cada Token (lexema) tenga características propias, por ejemplo un Nombre
que contenga el lexema, y a menudo, suele usarse un atributo que indique de que
tipo es el lexema.

Por ejemplo tenemos la Clase Token, que es creada para comprender este ejemplo.
class Token {
  String lexema;
  String tipo;
}
 
Si tenemos un Scanner que reconoce las expresiones

Numero -> Digito+
Palabra -> Letra+

Cada vez que se encuentre un Número debe crearse una Instancia de la Clase Token
...
  Token lexemaEncontrado = new Token();
     lexemaEncontrado.lexema = Analizador.obtenerLexemaEncontrado();
     lexemaEncontrado.Tipo = "Número";
  return lexemaEncontrado;
...

Para Iniciar el ejemplo se crea un archivo que contenga

class Yytoken  {
    private int token;
    public static final int Errors       = -1;
    public static final int EOF    = 204;
    public static final int Null    = 205;
 
    public static final int Id      = 1;
    public static final int Cadena      = 2;
    public static final int Numero      = 3;
 
    public String cadena;
      /* Me devuelve la cadena evaluada que corresponda a un estado de acetacion */
 
      public int PuttansBoys;
     /* Me devuelva la linea m' sirv' pa' los errores */
 
      public char CharError;
      /*Me devuelve el caracter del error*/
 
    Yytoken(int f) {
         token=f;
         cadena = "";
         PuttansBoys = 0;
         CharError = '0';
      }
 
  Yytoken(int f,String p) {
    token=f;
    cadena = p;
    PuttansBoys = 0;
    CharError = '0';
  }
 
  Yytoken(int f,String p, int linex) {
    token=f;
    cadena = p;
    PuttansBoys = linex;
    CharError = '0';
  }
 
  public int getToken() {
    return token;
  }
 
  public String getTextToken(){
    return this.cadena;
  }
 
  public String getMiError() {
    return
      (this.getToken()==this.Errors)
       ?
      ("Error de Compilacion en la linea " + this.getLineToken() +
       " ,  carecter ' "+this.getTextToken()+" '"+"\n")
      :
      ("");
  }
 
  public String getTextReferencia() {
     switch(this.token) {
        case  Id:
            return "Variable";
        case  Cadena:
            return "cadena";
        case  Numero:
            return "Numero";
        case     Yytoken.Errors:
            return "error";
        case     Yytoken.EOF :
            return "Fin del Archivo EOF";
        default:
            return " ";
    }
  }
 
  public int getLineToken() {
      return PuttansBoys + 1;
  }
 
  public char getCharWrongsToken() {
      return CharError;
  }
 
}
 
%%
%line
 
%%
 
[\"][a-zA-Z0-9\<\>\!\#\$\%\&\/\(\)\=\?\'\¿\]\[\{\}\+\-\*\;\.\,\-\_\\\ ]+[\"]
{ return new Yytoken(Yytoken.Cadena  , yytext() ); }
 
[a-zA-Z\_]+[a-zA-Z0-9\_]*
{ return new Yytoken(Yytoken.Id  , yytext() ); }
 
[0-9]+
{ return new Yytoken(Yytoken.Numero  , yytext() ); }
 
[\+\-\*\/]
{ return new Yytoken( 100 , yytext()); }
 
 
[\0]        { return new Yytoken(Yytoken.EOF); }
[\n]         { }
[\t\r]             { }
" "         { }
null         { return new Yytoken(Yytoken.EOF); }
.        { return new Yytoken(Yytoken.Errors , yytext() ,yyline);}



El Scanner o utilidad del Parser, es la interfaz que devuelve los lexemas del analizador léxico.

public class ParserUtil
{
    private Yylex myYylex = null;
 
    Yytoken myToken = null;
 
    public void setBuffer(String a) throws Exception {
        java.io.BufferedReader Rider = new java.io.BufferedReader( new java.io.StringReader(a) );
        myYylex = new Yylex(Rider);
    }
 
    public boolean Next() throws Exception{
        myToken = myYylex.yylex();
        if (myToken!=null){
            return true;
        }else{
            return false;
        }
    }
 
    public Yytoken getToken(){
        return myToken;
    }
 
}

asimismo tenemos una Clase principal para Scanner

class Main {
    public static void main(String args[]) throws Exception
    {
        ParserUtil t = new ParserUtil();
        t.setBuffer("la casa es muy bella y a mi me gusta");
        while(t.Next()){
            System.out.println(t.getToken().getTextToken());
        }
    }
}

Una vez tengamos el archivo de Gramatica y las dos clases, usamos las siguientes
directivas de compilación, mediante la Consola de DOS en Windows:

'Esta linea de comando Borra todos los archivos .class
del *.class
 
'Elimina el archivo Yylex.java
del Yylex.java
 
'Compila el archivo donde estan las expressiones regulares
java JLex.Main Grammar.java
 
'Renombra el archivo de salida del Jlex 'Grammar.java.java' a 'Yylex.java'
rename Grammar.java.java Yylex.java
 
'Elimina archivos temporales
del *.tmp
 
'hace una pausa que me muestra que paso en todo lo anterior
pause

Todos los archivos están disponibles en el enlace mostrado a continuación.


Fabio Palmieri - Talento Humano.
TALFlento Humano.