Ноль в peek(0) не обнуляется циклом, потому что peek(0) всегда возвращает текущий символ по позиции pos. Когда вызывается метод next(), он увеличивает значение pos, тем самым продвигаясь к следующему символу. Без вызова next(), значение pos останется на месте, и peek(0) всегда будет возвращать один и тот же символ, не двигаясь по строке.
Проще говоря, next() заставляет pos продвигаться вперёд, позволяя peek(0) возвращать следующий символ в строке. Без next() программа застрянет на одном символе и не сможет анализировать всю строку.
вот что делает код полностью:
package com.annimon.ownlang.parser; // Указывает пакет, к которому относится класс Lexer.
import java.util.ArrayList; // Импортирует класс ArrayList.
import java.util.List; // Импортирует интерфейс List.
/**
* @author aNNiMON
*/
public final class Lexer { // Объявляет финальный класс Lexer.
private static final String OPERATOR_CHARS = "+-*/()"; // Строка с символами операторов.
private static final TokenType[] OPERATOR_TOKENS = { // Массив, соответствующий операторам из OPERATOR_CHARS.
TokenType.PLUS, TokenType.MINUS,
TokenType.STAR , TokenType.SLASH,
TokenType.LPAREN, TokenType.RPAREN,
};
private final String input; // Исходная строка для анализа.
private final int length; // Длина исходной строки.
private final List<Token> tokens; // Список токенов.
private int pos; // Текущая позиция в строке.
public Lexer(String input) { // Конструктор класса Lexer.
this.input = input;
length = input.length();
tokens = new ArrayList<>();
}
public List<Token> tokenize() { // Основной метод для лексического анализа.
while (pos < length) { // Пока текущая позиция меньше длины строки.
final char current = peek(0); // Получаем текущий символ.
if (Character.isDigit(current)) tokenizeNumber(); // Если символ - цифра, вызываем метод tokenizeNumber().
else if (current == '#') { // Если символ - '#', переходим к следующему символу и вызываем метод tokenizeHexNumber().
next();
tokenizeHexNumber();
}
else if (OPERATOR_CHARS.indexOf(current) != -1) { // Если символ - оператор, вызываем метод tokenizeOperator().
tokenizeOperator();
} else { // Если символ не подходит ни под одно из условий, переходим к следующему символу (пропускаем пробелы и прочее).
next();
}
}
return tokens; // Возвращаем список токенов.
}
private void tokenizeNumber() { // Метод для токенизации чисел.
final StringBuilder buffer = new StringBuilder(); // Создаём буфер для накопления символов числа.
char current = peek(0); // Получаем текущий символ.
while (Character.isDigit(current)) { // Пока символ - цифра.
buffer.append(current); // Добавляем символ в буфер.
current = next(); // Переходим к следующему символу.
}
addToken(TokenType.NUMBER, buffer.toString()); // Добавляем токен числа в список токенов.
}
private void tokenizeHexNumber() { // Метод для токенизации шестнадцатеричных чисел.
final StringBuilder buffer = new StringBuilder(); // Создаём буфер для накопления символов числа.
char current = peek(0); // Получаем текущий символ.
while (Character.isDigit(current) || isHexNumber(current)) { // Пока символ - цифра или шестнадцатеричное число.