in core/src/main/java/com/jetbrains/youtrackdb/internal/common/parser/BaseParser.java [558:723]
protected String parserNextWord(
final boolean iForceUpperCase, final String iSeparatorChars, boolean preserveEscapes) {
parserPreviousPos = parserCurrentPos;
parserLastWord.setLength(0);
parserEscapeSequenceCount = 0;
parserSkipWhiteSpaces();
if (parserCurrentPos == -1) {
return null;
}
var stringBeginChar = ' ';
final var text2Use = iForceUpperCase ? parserTextUpperCase : parserText;
while (parserCurrentPos < text2Use.length()) {
final var c = text2Use.charAt(parserCurrentPos);
var found = false;
for (var sepIndex = 0; sepIndex < iSeparatorChars.length(); ++sepIndex) {
if (iSeparatorChars.charAt(sepIndex) == c) {
// SEPARATOR AT THE BEGINNING: JUMP IT
found = true;
break;
}
}
if (!found) {
break;
}
parserCurrentPos++;
}
try {
var openParenthesis = 0;
var openBracket = 0;
var openGraph = 0;
var escapePos = -1;
for (; parserCurrentPos < text2Use.length(); parserCurrentPos++) {
final var c = text2Use.charAt(parserCurrentPos);
if (escapePos == -1 && c == '\\' && ((parserCurrentPos + 1) < text2Use.length())) {
// ESCAPE CHARS
if (openGraph == 0) {
final var nextChar = text2Use.charAt(parserCurrentPos + 1);
if (preserveEscapes) {
parserLastWord.append(c);
parserLastWord.append(nextChar);
parserCurrentPos++;
} else {
if (nextChar == 'u') {
parserCurrentPos =
StringParser.readUnicode(text2Use, parserCurrentPos + 2, parserLastWord);
parserEscapeSequenceCount += 5;
} else {
if (nextChar == 'n') {
parserLastWord.append('\n');
} else if (nextChar == 'r') {
parserLastWord.append('\r');
} else if (nextChar == 't') {
parserLastWord.append('\t');
} else if (nextChar == 'b') {
parserLastWord.append('\b');
} else if (nextChar == 'f') {
parserLastWord.append('\f');
} else {
parserLastWord.append(nextChar);
parserEscapeSequenceCount++;
}
parserCurrentPos++;
}
}
continue;
} else {
escapePos = parserCurrentPos;
}
}
if (escapePos == -1 && (c == '\'' || c == '"')) {
if (stringBeginChar != ' ') {
// CLOSE THE STRING?
if (stringBeginChar == c) {
// SAME CHAR AS THE BEGIN OF THE STRING: CLOSE IT AND PUSH
stringBeginChar = ' ';
if (openBracket == 0 && openGraph == 0 && openParenthesis == 0) {
parserCurrentPos++;
parserLastWord.append(c);
break;
}
}
} else
// START STRING
{
stringBeginChar = c;
}
}
if (stringBeginChar == ' ') {
if (openBracket == 0
&& openGraph == 0
&& openParenthesis == 0
&& parserCheckSeparator(c, iSeparatorChars)) {
// SEPARATOR FOUND!
break;
} else if (c == '(') {
openParenthesis++;
} else if (c == ')' && openParenthesis > 0) {
openParenthesis--;
} else if (c == '[') {
openBracket++;
} else if (c == ']' && openBracket > 0) {
openBracket--;
} else if (c == '{') {
openGraph++;
} else if (c == '}' && openGraph > 0) {
openGraph--;
}
}
if (escapePos != -1) {
parserEscapeSequenceCount++;
}
if (escapePos != parserCurrentPos) {
escapePos = -1;
}
parserLastWord.append(c);
}
// CHECK MISSING CHARACTER
if (stringBeginChar != ' ') {
throw new IllegalStateException(
"Missing closed string character: '"
+ stringBeginChar
+ "', position: "
+ parserCurrentPos);
}
if (openBracket > 0) {
throw new IllegalStateException(
"Missing closed braket character: ']', position: " + parserCurrentPos);
}
if (openGraph > 0) {
throw new IllegalStateException(
"Missing closed graph character: '}', position: " + parserCurrentPos);
}
if (openParenthesis > 0) {
throw new IllegalStateException(
"Missing closed parenthesis character: ')', position: " + parserCurrentPos);
}
} finally {
if (parserCurrentPos >= text2Use.length()) {
// END OF TEXT
parserCurrentPos = -1;
parserLastSeparator = ' ';
}
}
return parserLastWord.toString();
}