Token next() {
        if (isEnd()) // end reached
            return Token.EOF;

        Token next = null;

        char[] chars = this.chars;
        int i = cursor;

        loop:
        while (i < length) {
            char c = chars[i];

            s0:
            switch (c) {
                // DIGITS
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9': {
                    if (isUndefined())
                        tokenStart = i;

                    if (lastChar() != '\0' && !Character.isDigit(lastChar())) {
                        next = createAndReset(Symbol.STRING);
                        break loop;
                    }

                    buff.append(c);
                    characteristics.add(DIGITS);

                    if (isNextDigit(i)) {
                        // next character is digit. continuing...
                        break;
                    } else {
                        // advancing pointer to non digit character
                        i++;
                        next = createAndReset(Symbol.DIGITS);

                        // break iteration and hoping to read token with digits.
                        break loop;
                    }
                }
                // PUNCTUATION
                case ':': {
                    if (isUndefined()) {
                        // empty buffer indicates that nothing has been parsed
                        next = Token.of(Symbol.COLON, i++, 1);
                    } else {
                        // buffer is not empty and we reached colon so we must return
                        next = createWithGuessedSymbol();
                    }
                    resetBuffer();
                    break loop;
                }
                case '.': {
                    if (isUndefined()) {
                        next = Token.of(Symbol.DOT, i++, 1);
                        resetBuffer();
                        break loop;
                    } else {
                        char lc = lastChar();

                        if (Character.isLetter(lc)) {
                            next = createAndReset(Symbol.STRING);
                        } else {
                            // most probably this is DIGITS
                            buff.append(c);
                            next = createWithGuessedSymbol();
                        }

                        resetBuffer();
                        break loop;
                    }
                }
                case '_':
                case '/': {
                    if (isUndefined()) {
                        next = Token.of(Symbol.STRING, i++, 1);
                    } else {
                        next = createWithGuessedSymbol();
                    }
                    resetBuffer();
                    break loop;
                }
                case '@': {
                    next = Token.of(Symbol.AT, i++, 1);
                    break loop;
                }
                case '+': {
                    if (isUndefined()) {
                        next = Token.of(Symbol.PLUS, i++, 1);
                    } else {
                        next = createWithGuessedSymbol();
                    }
                    resetBuffer();
                    break loop;
                }
                case '-': {
                    if (isUndefined()) {
                        next = Token.of(Symbol.MINUS, i++, 1);
                    } else {
                        next = createWithGuessedSymbol();
                        resetBuffer();
                    }

                    break loop;
                }
                case ',': {
                    if (isUndefined()) {
                        next = Token.of(Symbol.COMMA, i++, 1);
                    } else {
                        next = createWithGuessedSymbol();
                        resetBuffer();
                    }

                    break loop;
                }
                case '\n': {
                    if (isUndefined()) {
                        next = Token.of(Symbol.NEWLINE, i++, 1);
                    } else {
                        next = createWithGuessedSymbol();
                        resetBuffer();
                    }
                    break loop;
                }
                case '\r': {
                    if (isUndefined()) {
                        if (lookahead(i, 1) == '\n') {
                            next = Token.of(Symbol.NEWLINE, i++, 2);
                            i++;
                        } else {
                            next = Token.of(Symbol.NEWLINE, i++, 1);
                        }
                    } else {
                        next = createWithGuessedSymbol();
                        resetBuffer();
                    }
                    break loop;
                }
                case ' ':
                case '\t': {
                    if (isUndefined()) {
                        next = Token.of(Symbol.SPACE, i++, 1);
                    } else {
                        next = createWithGuessedSymbol();
                        resetBuffer();
                    }
                    break loop;
                }
                default: {
                    if (isUndefined())
                        tokenStart = i;

                    buff.append(c);

                    if (Character.isLetter(c)) {
                        characteristics.add(LETTERS);
                    }else if (Character.isDefined(c)) {
                        characteristics.add(PUNCTUATION);
                    }

                    break;
                }
            }

            i++;
        }

        cursor = i;

        // when reached and still can not find token.
        if (isEnd() && next == null) {
            Symbol symbol = guessSymbol();
            next = Token.of(symbol, tokenStart, buff.length());
            resetBuffer();
        }

        return next;
    }
Gets the original string being parsed.

@return The original string.
exts/jphp-zend-ext/src/main/java/org/develnext/jphp/zend/ext/standard/date/DateTimeTokenizer.java