Guia do StreamTokenizer

Guia do StreamTokenizer

1. Introdução

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 streamTokenizerWithDefaultConfiguration(Reader reader) throws IOException {
    StreamTokenizer streamTokenizer = new StreamTokenizer(reader);
    List tokens = new ArrayList();

    int currentToken = streamTokenizer.nextToken();
    while (currentToken != StreamTokenizer.TT_EOF) {

        if (streamTokenizer.ttype == StreamTokenizer.TT_NUMBER) {
            tokens.add(streamTokenizer.nval);
        } else if (streamTokenizer.ttype == StreamTokenizer.TT_WORD
            || streamTokenizer.ttype == QUOTE_CHARACTER
            || streamTokenizer.ttype == DOUBLE_QUOTE_CHARACTER) {
            tokens.add(streamTokenizer.sval);
        } else {
            tokens.add((char) currentToken);
        }

        currentToken = streamTokenizer.nextToken();
    }

    return tokens;
}


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;
}


E aqui temos uma nova saída:

// same output as earlier
Word: "lazy"
Word: dog!
Ordinary char:

Ordinary char:

Ordinary char: /
Ordinary char: /
Word: test2

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.