Este arquivo é você quem decide o formato ou já é preestabelecido?
Se for você que decide o formato, você poderia utilizar XML ou JSON para formatar os dados, ai ficaria mais fácil para fazer o parser.
Em XML ficaria:
<gramatica>
<terminais>
<terminal valor="Brazil"/>
<terminal valor="Argentina"/>
<terminal valor="England"/>
</terminais>
<variaveis>
<variavel valor="S"/>
<variavel valor="PES"/>
<variavel valor="OBJ"/>
</variaveis>
<inicial valor="S"/>
<regras>
<regra simboloInicio="S" levaA="PES OBJ"/>
<regra simboloInicio="PES" levaA="SUJ VER"/>
<regra simboloInicio="PES" levaA="SUJ COMP"/>
</regras>
</gramatica>
Em JSON:
{
"terminais": [
"Brazil",
"Argentina",
"England"
],
"variaveis": [
"S",
"PES",
"OBJ"
],
"inicial": "S",
"regras": [
{ "simboloInicial": "S", "levaA": "PES OBJ" },
{ "simboloInicial": "PES", "levaA": "SUJ VER" },
{ "simboloInicial": "PES", "levaA": "SUJ COMP" },
]
}
Perceba que em JSON o texto fica mais "magro", pois não tem as tags de fechamento. O primeiro "abre chaves" especifica a gramática. Você pode estruturá-lo de outras formas também, colocando objetos dentro dos arrays "terminais" e "variáveis", da mesma forma que fiz com "regras", mas como os terminais e as variáveis só tem o valor, usei apenas um array. O que eu fiz é apenas uma sugestão. Mais informações sobre JSON vc pode encontrar no link http://www.json.org/.
Para fazer o parse do XML vc pode usar o SimpleXML (http://simple.sourceforge.net/) ou o XStream (http://xstream.codehaus.org/). Eu prefiro o SimpleXML
Para fazer o parse do JSON, existem diversas alternativas. Uma bem fácil de usar é o Jettison (http://jettison.codehaus.org/). O XStream também suporta JSON, mas também não gosto...
Entretanto, se o formato já for estabelecido, vc pode usar os métodos da classe String para ir recortando os valores, com base na formatação estabelecida.
Usando o split e o replace vc consegue fazer tudo.
Olha o exemplo (assumindo que existe quebra de linha (\n)):
String dados = "Terminais\n" +
"[ Brazil ]\n" +
"[ Argentina ]\n" +
"[ England ]\n" +
"Variaveis\n" +
"[ S ]\n" +
"[ PES ]\n" +
"[ OBJ ]\n" +
"Inicial\n" +
"[ S ]\n" +
"Regras\n" +
"[ S ] > [ PES ] [ OBJ ]\n" +
"[ PES ] > [ SUJ ] [ VER ]\n" +
"[ PES ] > [ SUJ ] [ COMP ]";
// tira os colchetes
String gramatica = dados.replace( "[ ", "" ).replace( " ]", "" );
// gera um array de duas posições. na primeira, está toda a parte de "Terminais"
// na segundao restante da String (variaveis + inicial + regras).
String[] spTerm = gramatica.split( "Variaveis\n" );
// gera um array de duas posições (com base no final do spTerm).
// na primeira, está toda a parte de "Variaveis" na segundao restante da
// String (inicial + regras).
String[] spVar = spTerm[1].split( "Inicial\n" );
// gera um array de duas posições (com base no final do spVar).
// na primeira, está toda a parte de "Inicial" na segundao restante da
// String (regras).
String[] spIniReg = spVar[1].split( "Regras\n" );
// cria o array de terminais quebrando nos pulos de linha, sendo que
// primeiro remove a String "Terminais\n" que ficou sobrando no processo
// anterior.
String[] terminais = spTerm[0].replace( "Terminais\n", "" ).split( "\n" );
// cria o array de variáveis (quebra nos pulos de linha)
String[] variaveis = spVar[0].split( "\n" );
// inicial vai ser sempre um só (definição na teoria), mas ainda
// precisa remover o pulo de linha
String inicial = spIniReg[0].replace( "\n", "" );
// cria o array de regras (quebra nos pulos de linha)
String[] regras = spIniReg[1].split( "\n" );
// mostra cada um
System.out.println( "terminais:" );
for ( String terminal : terminais ) {
System.out.println( terminal );
}
System.out.println();
System.out.println( "variáveis:" );
for ( String variavel : variaveis ) {
System.out.println( variavel );
}
System.out.println();
System.out.println( "inicial: " + inicial );
System.out.println();
System.out.println( "regras:" );
for ( String regra : regras ) {
// quebrando a regra atual...
String[] sRegra = regra.split( " > " );
// em 0 está o símbolo inicial de regra, no 1 está o corpo da regra
String simboloInicio = sRegra[0];
String levaA = sRegra[1];
System.out.println( "símbolo inicio: " + simboloInicio + ", leva a: " + levaA );
}
Nossa, hehe, acabei fazendo tudo ;)
Ah, uma coisa que você precisa tomar cuidado é que se houver algum terminal, ou variável que tenha como nome os valores que estão sendo usados para o recorte (Variáveis, Inicial e Regras), o código acima vai ter problemas, pois vai fazer mais recortes que o "esperado". Então sugiro que você use uma das duas soluções apresentadas acima (XML ou JSON). Eu prefiro JSON, mas XML pode ser mais fácil de ler para algumas pessoas.
[]´s