Neste tutorial, mostraremos como analisar um fluxo de caracteres em tokens usando a classe JavaStreamTokenizer.
2. StreamTokenizer
A classeStreamTokenizer lê o fluxo caractere por caractere. Cada um deles pode ter zero ou mais dethe following attributes: white space, alphabetic, numeric, string quote or comment character.
Agora, precisamos entender a configuração padrão. Temos os seguintes tipos de caracteres:
Word characters: varia como ‘a’ a ‘z’ e ‘A’ a ‘Z
Numeric characters: 0,1, ..., 9
Whitespace characters: valores ASCII de 0 a 32
Comment character: /
String quote characters: ‘e“
Note that the ends of lines are treated as whitespaces, not as separate tokens,e os comentários no estilo C / C ++ não são reconhecidos por padrão.
Esta classe possui um conjunto de campos importantes:
TT_EOF - uma constante indicando o fim do fluxo
TT_EOL - uma constante que indica o fim da linha
TT_NUMBER - uma constante que indica um token de número
TT_WORD - uma constante que indica um token de palavra
3. Configuração padrão
Aqui, vamos criar um exemplo para entender o mecanismoStreamTokenizer. Começaremos criando uma instância desta classe e, em seguida, chamaremos o métodonextToken() até que ele retorne o valorTT_EOF:
private static final int QUOTE_CHARACTER = '\'';
private static final int DOUBLE_QUOTE_CHARACTER = '"';
public static List
O arquivo de teste simplesmente contém:
3 quick brown foxes jump over the "lazy" dog!
#test1
//test2
Agora, se imprimirmos o conteúdo do array, veremos:
Number: 3.0
Word: quick
Word: brown
Word: foxes
Word: jump
Word: over
Word: the
Word: lazy
Word: dog
Ordinary char: !
Ordinary char: #
Word: test1
Para entender melhor o exemplo, precisamos explicar os camposStreamTokenizer.ttype,StreamTokenizer.nvaleStreamTokenizer.sval.
The ttype field contains the type of the token just read. Pode serTT_EOF,TT_EOL,TT_NUMBER,TT_WORD. No entanto,for a quoted string token, its value is the ASCII value do caractere de aspas. Além disso, se o token for um caractere comum como‘!', sem atributos, ottype será preenchido com o valor ASCII desse caractere.
A seguir,we’re using sval field to get the token, only if it’s a TT_WORD, ou seja, um token de palavra. Mas, se estivermos lidando com um token de string entre aspas - digamos“lazy” –, então este campo contém o corpo da string.
Último,we’ve used the nval field to get the token, only if it’s a number token, using TT_NUMBER.
4. Configuração Personalizada
Aqui, vamos alterar a configuração padrão e criar outro exemplo.
Primeiro, o métodowe’re going to set some extra word characters using the wordChars(int low, int hi). Então,we’ll make the comment character (‘/') an ordinary onee promova‘#' como o novo caractere de comentário.
Finalmente,we’ll consider the end of the line as a token character com a ajuda do métodoeolIsSignificant(boolean flag).
Precisamos apenas chamar esses métodos no objetostreamTokenizer:
public static List streamTokenizerWithCustomConfiguration(Reader reader) throws IOException {
StreamTokenizer streamTokenizer = new StreamTokenizer(reader);
List tokens = new ArrayList();
streamTokenizer.wordChars('!', '-');
streamTokenizer.ordinaryChar('/');
streamTokenizer.commentChar('#');
streamTokenizer.eolIsSignificant(true);
// same as before
return tokens;
}
Observe que as aspas duplas se tornaram parte do token, o caractere de nova linha não é mais um caractere de espaço em branco, mas um caractere comum e, portanto, um token de caractere único.
Além disso, os caracteres após o caractere ‘# 'agora são ignorados e o‘ /' é um caractere comum.
Também poderíamoschange the quote character with the quoteChar(int ch) method ou mesmo os caracteres de espaço em branco chamando o métodowhitespaceChars(int low, int hi). Assim, outras personalizações podem ser feitas chamando os métodos deStreamTokenizer em diferentes combinações.
5. Conclusão
Neste tutorial,we’ve seen how to parse a stream of characters into tokens using the StreamTokenizer class. Aprendemos sobre o mecanismo padrão e criamos um exemplo com a configuração padrão.
Finalmente, alteramos os parâmetros padrão e notamos como a classeStreamTokenizer é flexível.
Como de costume, o código pode ser encontradoover on GitHub.