eu tenho uma "sugestão", de um algoritmo que acho que funciona, você lendo cada caractere:
-
monte uma pilha contendo cada caractere em separado;
-
crie um array com os tokens aceitos;
-
crie uma string para guardar o "acumulado" entre os caracteres lidos
-
crie um array de tokens reconhecidos e um de não reconhecidos;
-
leia e retire o primeiro caractere da pilha, insira-o no acumulado;
-
com o indexof, verifique se existe algum dos caracteres aceitos no acumulado,
-
caso sim:
retire-o do acumulado e coloque-o nos tokens aceitos
retire o que vier antes dele e coloque nos não aceitos
o que vier depois dele você deve manter no acumulado para consumir depois
leia e retire o próximo caractere igual você fez no passo 5 com o primeiro e depois volte ao passo 6.
depois de ter consumido o ultimo caractere, caso ainda exista alguma coisa no acumulado, jogue no array de tokens não encontrados.
desta forma eu estou desconsiderando "separadores" de tokens, como um espaço ou um ";" em um analisador lexico de java por exemplo e identificando o token mesmo que ele esteja no meio de uma palavra como por exemplo em abc->def.
se você quiser usar os "separadores", teria que mudar esse algoritmo para só validar o token como a palavra inteira (entre um separador e outro, você precisaria de um array de separadores também), separar tokens entre um separador e outro para depois validar ou invalidar, mas ai é outra história…