Separar Cadenas por caracteres

Que tal tenia un buen sin pasar por aqui pero debido a que siempre encuentro las soluciones regrese.... jejeje :)

Bueno Resulta que estoy realizando un analizador léxico para un lenguaje que definí (en sintesis es la sintaxis del lenguaje java al español con palabras reservadas y esas cosas obvio no todas solo algunas) pero tengo problemas a la hora de separar las cadenas por caracteres, pues mi idea es leer el archivo de texto, después ya que tenga su contenido ahora si separar las cadenas de entrada por caracteres especiales para realizar los tokens necesarios. El detalle es que realizo bien la lectura de cada linea del archivo pero cuando trato de separar la cadena no logro hacer que funcione(si la separo con espacio si funciona pero lee la linea completa por eje: System.out.print()). Esto es lo que llevo:

Sintesis de como funciona: en archivos .txt separo lo que son palabras reservadas,caracteres especiales, de esa manera comparo el contenido del .txt de reservadas para palabras reservadas y el .txt de caracteres especiales los caract. esp.

//metodo para separar las cadenas apartir de que encuentra un caracter especial:
    public void get_Cadenas(String cadena[],String caracter[])
    {
        String cadenas_Aux[] = new String[cadena.length];
        String cadenaAux="";
       
        for(int i=0;i<cadena.length;i++)
        {
            cadenas_Aux = cadena[i].split(caracter[i]);
            cadenaAux+=cadenas_Aux[i];
        }
       
    }

Pero truena igual si trato de hacer esto pasa lo mismo:

for(int i=0;i<cadena.length;i++)
        {
            for(int x=0;x<caracter.length;x++)
            {
              cadenas_Aux = cadena[i].split(caracter[i]);
              cadenaAux+=cadenas_Aux[i];
            }
        }

Con esto si funciona pero toma toda la linea porque separo por espacios:

private String unir(String[] str) {
        String unir = "";
        for (int z = 0; z < str.length; z++) {
            unir += str[z] + " ";
        }

        String re = "";

        StringTokenizer cadena = new StringTokenizer(unir);
        while (cadena.hasMoreTokens()) {
            re += " " + cadena.nextToken().trim();
        }

        return re;
    }

La idea es que yo lea esta cadena: Pantalla.Imprime("hola");

y separé la cadena así: Pantalla, . , Imprime , (, "hola", ) , ;

Lo que yo hago es que el contenido del programa fuente lo recibo como el 1er parametro y el 2° parametro es el de los caracteres especiales para comparar de uno en uno y así separar las cadenas cuando encuentre un caracter especial.

Espero no haberlos confundido tanto con la solución que quiero tener.

Que esten de lo mejor y espero sus respuestas!
Saludos y gracias!...

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de Nopalin

No se entiende que quieres

No se entiende que quieres lograr, pero puedes utilizar el metodo toCharArray que trae el objeto String.

Sobres

Imagen de ezamudio

pues...

depende qué tan correcto quieres que sea el análisis. El ejemplo concreto de separar Pantalla.Imprime("hola"); lo resuelves fácil con una expresión regular o bien recorriendo caracter por caracter la cadena, para separar un nuevo elemento cada que encuentras un caracter especial. Pero te falta algo muy importante: contexto.

Porque el programa que únicamente separa por los caracteres especiales, te va a dar igual una lista para cadenas inválidas. Si estás pensando en hacer la validación de los tokens posteriormente entonces no tienes tanta bronca. Pero así como te puede devolver una lista de Pantalla, ., imprime, (, "hola", ) igual te puede devolver los elementos para cad)enas.(invali;das.)

Imagen de rodrigo salado anaya

Tok tok, ¿Quién e(n)s?

Hola pues aquí de pasada te dejo un pequeño ejemplo de lo que entendí que quieres hacer. No es la mejor ni la más óptima de las formas pero es la más sencilla que se me ocurre, y tronaría si primero se comparara ‘=’ que ‘==’ vale : ).

Seguro algún compañeros de la comunidad te dirán que tema de compiladores o XXX cosa es la que debes de estudiar para que tu programa sea algo decente.
Bueno pues te dejo mi ejemplo:

package org.javamexico;

import org.junit.Test;

/**
 *
 * @author rodrigo.salado
 */

public class LexTest {

    /**
     * Test of scann method, of class Lex.
     */

    @Test
    public void testScann() {
        Lex lex = new Lex();
        String codigo = ""
                + "a=13;"
                + "b = 14;"
                + "r =a+b- 23+ 45;"
                + "imprime r;"
                + "System.out.println('hola');";
        lex.escanea(codigo);
    }
}

package org.javamexico;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author rodrigo.salado
 */

public class Lex {

    private List<String[]> listaTokens = new ArrayList<String[]>();
    private String[] FUNCIONES = {
        "System",
        "out",
        "println",
        "imprime",
        "mayusculas",
        "==",
        "=",
        "+",
        "-",
        ".",
        "(",
        ")",
        "'"
    };

    public void escanea(String codigo) {
        for (String sentencia : codigo.split(";")) {
            separaFunciones(sentencia);
        }
        for (String[] tokens : listaTokens) {
            for (String token : tokens) {
                System.out.print("[" + token + "]");
            }
            System.out.println("");
        }
    }

    private void separaFunciones(String sentencia) {
        for (String funcion : FUNCIONES) {
            if (sentencia.contains(funcion)) {
                sentencia = sentencia.replace(funcion, " " + funcion + " ");
            }
        }
        String[] tokens = sentencia.replaceAll("\\s+", " ").trim().split(" ");
        listaTokens.add(tokens);
    }
}

Salida

[a][=][13]
[b][=][14]
[r][=][a][+][b][-][23][+][45]
[imprime][r]
[System][.][out][.][println][(]['][hola]['][)]

Te agradecería una retroalimentación para ver cómo quedo al final.
Saludos a todos : )

Imagen de rodrigo salado anaya

Re: Tok tok, ¿Quién es?, Es Groovy

Estoy estudiando Groovy en mis pocos ratos libres y decidí ver cómo hacer mi ejemplo más chido (groovy).
Sé que esto iría en otro hilo, pero… ¿Qué opinan del código en Groovy?, algunos consejos.
También me lo eche en Haskell, pero no me salió nada bonito para mostrar, eso de plano no viene al caso aquí. (: S)

listaTokens = []
funciones = ["System","out","println","imprime","mayusculas","==","=","+","-",".","(",")","'"]
codigo = """a = 3;
            b = 14;
            r =a+b- 23+ 45;
            imprime r;
            System.out.println('hola');"
""
           
def escanea(String codigo){
    codigo.split(";").each({sentencia -> separaFunciones sentencia})
    listaTokens.each({tokens -> tokens.each({token -> print "[" + token + "]"}) println ""})
}

def separaFunciones(String sentencia){
    funciones.each({funcion -> sentencia = sentencia.replace(funcion, " " + funcion + " ")});
    listaTokens.add sentencia.replaceAll("\\s+", " ").trim().split(" ")
}
escanea codigo

Saludos a todos. : )

Imagen de ezamudio

paréntesis

Rodrigo, aprovecha la azúcar sintáctica de Groovy que te permite omitir los paréntesis cuando sólo pasas un argumento a un método (de hecho esa veo que sí la usas), y la que te permite poner un closure afuera de los paréntesis cuando es el último argumento de un método. Es decir:

objeto.metodo(Object x)
objeto.metodo(Object a, Object b, Closure c)
//los puedes llamar así
objeto.metodo parametro
objeto.metodo(parm1, parm2) { closure }

Y recuerda que si tienes closures donde no declaras parámetros, por default son de un parámetro sin tipo llamado it. Aprovecha también los Gstrings, y los strings especiales para regex... Ah y recuerda algunos métodos adicionales que simulan sobrecarga de operadores, como +, << etc (aunque ya es cuestión de gustos). Entonces:

void escanea(String codigo) {
    codigo.split(";").each { separaFunciones it }
    listaTokens.each { it.each { token -> print "[$token]" } println() }
}
void separaFunciones(String sentencia){
    funciones.each { sentencia = sentencia.replace(it, " $it ") }
    listaTokens << sentencia.replaceAll(/\s+/, " ").trim().split(" ")
}
Imagen de rodrigo salado anaya

Epifanía Groovy.

Jajaja bueno no para tanto. Muchas gracias por los consejos, y que fumadas están unas cosas, como <<, también jugando un poco le quite el tipo a los métodos (los infiere, que padre), eso me gustó mucho, lo del ‘it’ en los closures es algo muy útil, también me gustó mucho, no sé si Haskell lo tenga… hoy lo investigo. En fin que bonito lenguaje.

void escanea(codigo){
    codigo.split(";").each { sentencia ->
        funciones.each {sentencia = sentencia.replace(it, " $it ")};
        listaTokens << sentencia.replaceAll(/\s+/, " ").trim().split(" ")
    }
    listaTokens.each {it.each {token -> print "[$token]"} println()}
}

@JEMZ Disculpa por agárrame de tu hilo y espero que te sirva de algo todo lo anterior.

Imagen de ezamudio

no los infiere

Groovy no infiere los tipos. Simplemente le valen madres, recuerda que es un lenguaje de tipado dinámico. Le puedes pedir intValue o substring a un arreglo o un Object o lo que quieras, en runtime resuelve si contesta o no.

Imagen de rodrigo salado anaya

Duck typing

Cierto olvide eso, solo para ejemplificar esto:

class Perro{
    def aulla(){def sonido = 'Guauuuu!!!'}
}

class Lobo{
    def aulla(){def sonido = 'Auuuuuu!!!'}
}

class Gato{
    def maulla(){def sonido = 'Miauuuu!!!'}
}

animales = [new Perro(), new Lobo(), new Gato()]

animales.each {
    println it.metaClass.respondsTo(it, "aulla").isEmpty() == false?
            it.aulla():
            it.maulla()
};
/*
animales.each { //El gato truena
    println it.aulla()
};
*/

Salida:
Guauuuu!!!
Auuuuuu!!!
Miauuuu!!!

Ejemplo de cómo crear y redefinir métodos dinámicos:

class Gato{
    def foo(){}
}

gato = new Gato()
assert gato.metaClass.respondsTo("maulla").isEmpty()
gato.metaClass."maulla" = {-> "Miauuuu!!!"}
assert !gato.metaClass.respondsTo(gato, "maulla").isEmpty()
println gato.maulla()

gato.foo()
gato.metaClass."foo" = {-> "fooMensaje!!!"} // Esto es una fregonería :)
println gato.foo()

Salida:
Miauuuu!!!
fooMensaje!!!

Fuentes:
http://en.wikipedia.org/wiki/Duck_typing
http://groovyconsole.appspot.com/script/135001
http://groovy.codehaus.org/ExpandoMetaClass+-+Dynamic+Method+Names