domingo, septiembre 04, 2005

 

Otra aplicación típica para JFlex

Soy uno solo


¿Quién no ha querido en ocasiones convertirse en varios a la vez? Esta semana no he podido avanzar con el complilador, tuve que entregarle mi tiempo a documentar un diseño que ya tengo un poco avanzado.

Pero siempre hay tiempo para "jugar" un poco y como tengo un programa pendiente, el cual ya varios amigos me han dicho que está interesante, un "commander" que reconoce comandos creados por el usuario para correr programas o abrir archivos específicos mediante pequeñas abreviaturas.

Una de las mejoras es naturalmente implentarle tecnología de compiladores a ese programa, para mejorar el reconocimiento de comandos.

La idea con ese programa es escribir lo menos posible, de modo que su uso acelere la productividad. Por lo tanto, una mejora sustancial, es que el programa detecte que comando llamar, con ver solamente el parámetro. Es decir, provéele solamente www.loquesea.tu, y el solo abrirá Iexplore, dile C:\Mis Polainas y automáticamente se abriria una ventana del Explorador de archivos, apuntando a esa carpeta.

Esto es muy sencillo de lograr, utilizando un analizador léxico.

Aqui les presento un ensayo, totalmente autónomo, realizado en JFLEX. Con Autónomo me refiero a que no utilicé absolutamente nada más que jflex.

El ensayo toma uno o varios archivos, o la entrada estandar, y reconoce ciertos tipos de cadenas comunes. Este ensayo podría ser útil también, para entender como es que Word convierte automáticament en Links, cuando uno escribe una direccione de correo, o de internet.

--------- empieza JFlex -------------

import java.io.*;

/**
* Class YyLex, creada mediante jFlex a partir de minimal. lex.
* @author Gerson Lara
* @URL http://www2.cs.tum.edu/projects/cup/minimal.tar.gz
*/
%%
%class Liner
%type int
%full
//%cup
%{

static void print(String s){ System.out.print(s); }
void sout(String s){ System.out.print(s + ": " + yytext() + "\n"); }

public static void main(String args[]) throws Exception {

print("Bienvenido a line detector\n");
System.out.println("Argumentos: " + args.length);
for(int i = 0; i < args.length; i++){
System.out.println("Leyendo desde archivo: " + args[i]);
FileReader fr = new FileReader(args[i]);
Liner cuente = new Liner(fr);
cuente.funcione();
}

if(args.length == 0){
System.out.println("Leyendo desde System.in");
Liner cuente = new Liner(System.in);
cuente.funcione();
}
}

public void funcione() throws Exception {
yylex();
print("\n");
}
%}
LETRA=[A-Za-z_~]
DIGITO=[0-9]
PUNTUAC=[!#?]
TRESD={DIGITO}({DIGITO}{DIGITO}?)?
NOMBRE={LETRA}+(" "{LETRA}+)*
%%
[\t\f\n|\r] { /* ignore white space*/ }
{LETRA}+"://"{LETRA}+("."{LETRA}+)*("/"({LETRA}+|"."|{PUNTUAC})+)* { sout("URL");}
{LETRA}+"."{LETRA}+("."{LETRA}+)* { sout("Direccion de internet");}
{LETRA}+@{LETRA}+"."{LETRA}+ { sout("Direccion de correo-e");}
{LETRA}: {sout("Unidad de disco");}
{LETRA}":"("\\"{NOMBRE}("."{NOMBRE})*)* { sout("Directorio");}
{LETRA}+ { sout("Palabra");}
{TRESD}"."{TRESD}"."{TRESD}"."{TRESD} {sout("Direccion IP");}
<> { return 0;}
. { sout("Expresion no reconocida"); }
----------- termina JFlex --------------

Aqui un par de ejemplos de corrida. El primero fue lanzado directamente desde el IDE, y el segundo fue utilizando linea de comandos y alimentándolo con dos archivos de texto.

---------- empiezan ejemplos ------------
Bienvenido a line detector

Argumentos: 0
Leyendo desde System.in
www.unitec.edu
Direccion de internet: www.unitec.edu
efutch@gmail.com
Direccion de correo-e: efutch@gmail.com
dir
Palabra: dir
c:
Unidad de disco: c:
c:\cmpl
Directorio: c:\cmpl
192.167.0.1
Direccion IP: 192.167.0.1
^Z

Press any key to continue...

-------------------------------------------------------------
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Program Files\Comendador>cd C:\cmpl\src\WrdCnt\Liner

C:\cmpl\src\WrdCnt\Liner>java Liner correos.txt rev.txt
Bienvenido a line detector
Argumentos: 2
Leyendo desde archivo: correos.txt
Direccion de correo-e: glaraf@unitec.edu
Direccion de correo-e: iguana@tierra.mia

Leyendo desde archivo: rev.txt
Direccion de internet: www.huevos.revueltos.com
Directorio: C:\yuca


C:\cmpl\src\WrdCnt\Liner>
---------- terminan ejemplos ------------

Espero que con esto se les ocurran más ideas de lo que pueden hacer con JFlex y similares. A mi se me ocurre hacer un "Find & Replace" más poderoso que los normales. Creo que ese será el siguiente "Juguete".

Comments:
Existen CIENTOS de aplicaciones para el análisis léxico...por ejemplo el word count si se dió cuenta era directo hacerlo en JFLex...el reconocimiento de secuencias de genes en bioinformatics, reconocimiento de patrones en imágenes (lea algo sobre captchas), el procesador de llamadas telefónicas del primer parcial, filtros antispam, etc. etc. etc.

Eso sí, tómele más tiempo al proyecto...
 
Ahhh se me ocurrió otra que tuve que utilizar una vez:

Copiar archivos de Win2 a Linux por ejemplo, no les preserva el "case", por lo que INDEX.HTM queda como INDEX.HTM en Unix, y Unix si es case sensitive.

Entonces...renombrar 1000 archivos de un website se convierte en un dolor, y allí lo viene a rescatar un simple filtro escrito en Lex, o usar el que ya existe en Unix que se llama tr.

Esto es un caso de la vida real, como dicen en las películas.
 
excelente..

queria trabajar con jflex y cup por separado (en una primera instancia)

y este codigo me va a ser de mucha ayuda

muchas gracias!!
 
hola, oye me marca un error en la parte final tienes esta linea de código:

<> { return 0;}

me marca error justo en el inicio de la linea donde están estos caracteres:

<>

no se si pudieras decirme por que pasa esto?
 
Publicar un comentario

<< Home

This page is powered by Blogger. Isn't yours?