Ръководство за StreamTokenizer

1. Въведение

В този урок ще покажем как да анализираме поток от символи в маркери, използвайки класа Java StreamTokenizer .

2. StreamTokenizer

Класът StreamTokenizer чете поток символ по знак. Всеки от тях може да има нула или повече от следните атрибути: празно пространство, азбучен, цифров, кавичка или символ на коментар.

Сега трябва да разберем конфигурацията по подразбиране. Имаме следните типове знаци:

  • Слово знаци : варира като „a“ до „z“ и „A“ до „Z“
  • Цифрови знаци : 0,1,…, 9
  • Пробели : ASCII стойности от 0 до 32
  • Коментарен знак : /
  • Низови кавички : „и“

Имайте предвид, че краищата на редовете се третират като бели пространства, а не като отделни маркери, а коментарите в стил C / C ++ не се разпознават по подразбиране.

Този клас притежава набор от важни полета:

  • TT_EOF - Константа, указваща края на потока
  • TT_EOL - Константа, указваща края на реда
  • TT_NUMBER - Константа, показваща числов маркер
  • TT_WORD - Константа, указваща лексема на дума

3. Конфигурация по подразбиране

Тук ще създадем пример, за да разберем механизма StreamTokenizer . Ще започнем със създаване на екземпляр на този клас и след това ще извикаме метода nextToken () , докато той върне стойността TT_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; }

Тестовият файл просто съдържа:

3 quick brown foxes jump over the "lazy" dog! #test1 //test2

Сега, ако разпечатаме съдържанието на масива, ще видим:

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

За да разберем по-добре примера, трябва да обясним полетата StreamTokenizer.ttype , StreamTokenizer.nval и StreamTokenizer.sval .

Полето ttype съдържа типа на току-що прочетения маркер. Може да е TT_EOF , TT_EOL , TT_NUMBER , TT_WORD . Обаче за кодиран символен низ неговата стойност е стойността ASCII на символа на кавичката. Освен това, ако символът е обикновен знак като „!“ , без атрибути, тогава ttype ще се попълни със стойността ASCII на този символ.

След това използваме sval поле, за да получим маркера, само ако това е TT_WORD , т.е. Но ако имаме работа с котиран символен низ - кажете „мързелив“ - тогава това поле съдържа тялото на низа.

И накрая, използвахме полето nval, за да получим маркера, само ако това е цифров маркер, използвайки TT_NUMBER .

4. Персонализирана конфигурация

Тук ще променим конфигурацията по подразбиране и ще създадем друг пример.

Първо ще зададем някои допълнителни символи на думи, използвайки метода wordChars (int low, int hi) . След това ще направим символа за коментар ('/') обикновен и ще популяризираме '#' като нов знак за коментар.

И накрая, ще разгледаме края на реда като символен символ с помощта на метода eolIsSignificant (булев флаг) .

Трябва само да извикаме тези методи на обекта streamTokenizer :

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

И тук имаме нов изход:

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

Обърнете внимание, че двойните кавички станаха част от маркера, символът за нов ред вече не е знак за интервал, а е обикновен символ и следователно едносимволен знак.

Също така, символите след символа „#“ вече се пропускат, а „/“ е обикновен знак.

Можем също така да променим символа на кавичките с метода quoteChar (int ch) или дори белите символи, като извикаме метода whitespaceChars (int low, int hi) . По този начин могат да се направят допълнителни персонализации при извикване на методите на StreamTokenizer в различни комбинации .

5. Заключение

В този урок видяхме как да анализираме поток от символи в символи с помощта на класа StreamTokenizer . Научихме за механизма по подразбиране и създадохме пример с конфигурацията по подразбиране.

Накрая сме променили параметрите по подразбиране и забелязахме колко гъвкав е класът StreamTokenizer .

Както обикновено, кодът може да бъде намерен в GitHub.