private void parsePatternToTokens(String pattern) {
    tokens.clear();
    String originalPattern = pattern;
    pattern = pattern.toLowerCase();

    // indexes of the substring we will check (includes begin, does not include end)
    int begin=0, end=0;
    String candidate;
    Token lastAddedToken = null;
    boolean fillMode = false;

    while (begin < pattern.length()) {
      // if begin hasn't progressed, then pattern is not parsable
      if (begin != end) {
        tokens.clear();
        throw new IllegalArgumentException("Bad date/time conversion pattern: " + pattern);
      }

      // find next token
      for (int i = LONGEST_TOKEN_LENGTH; i > 0; i--) {
        end = begin + i;
        if (end > pattern.length()) { // don't go past the end of the pattern string
          continue;
        }
        candidate = pattern.substring(begin, end);
        if (isSeparator(candidate)) {
          lastAddedToken = parseSeparatorToken(candidate, lastAddedToken, fillMode, begin);
          begin = end;
          break;
        }
        if (isIso8601Delimiter(candidate)) {
          lastAddedToken = parseIso8601DelimiterToken(candidate, fillMode, begin);
          begin = end;
          break;
        }
        if (isNumericTemporalToken(candidate)) {
          lastAddedToken = parseTemporalToken(originalPattern, candidate, fillMode, begin);
          fillMode = false;
          begin = end;
          break;
        }
        if (isCharacterTemporalToken(candidate)) {
          lastAddedToken = parseCharacterTemporalToken(originalPattern, candidate, fillMode, begin);
          fillMode = false;
          begin = end;
          break;
        }
        if (isTimeZoneToken(candidate)) {
          lastAddedToken = parseTimeZoneToken(candidate, fillMode, begin);
          begin = end;
          break;
        }
        if (isTextToken(candidate)) {
          lastAddedToken = parseTextToken(originalPattern, fillMode, begin);
          end = begin + lastAddedToken.length + 2; // skip 2 quotation marks
          lastAddedToken.removeBackslashes();
          begin = end;
          break;
        }
        if (isFormatModifierToken(candidate)) {
          checkFillModeOff(fillMode, begin);
          fillMode = isFm(candidate);
          if (!fillMode) {
            formatExact = true;
          }
          begin = end;
          break;
        }
      }
    }
  }
Parse pattern to list of tokens.
common/src/java/org/apache/hadoop/hive/common/format/datetime/HiveSqlDateTimeFormatter.java