int end, i2;
while (j < pattern.length()) {
switch (pattern.charAt(j)) {
case '[': {
final ParseLogHandler log = SkriptLogger.startParseLogHandler();
try {
res = parse_i(pattern, i, j + 1);
if (res != null) {
log.printLog();
return res;
}
log.clear();
j = nextBracket(pattern, ']', '[', j + 1, true) + 1;
res = parse_i(pattern, i, j);
if (res == null)
log.printError();
else
log.printLog();
return res;
} finally {
log.stop();
}
}
case '(': {
final ParseLogHandler log = SkriptLogger.startParseLogHandler();
try {
final int start = j;
for (; j < pattern.length(); j++) {
log.clear();
if (j == start || pattern.charAt(j) == '|') {
int mark = 0;
if (j != pattern.length() - 1 && ('0' <= pattern.charAt(j + 1) && pattern.charAt(j + 1) <= '9' || pattern.charAt(j + 1) == '-')) {
final int j2 = pattern.indexOf('¦', j + 2);
if (j2 != -1) {
try {
mark = Integer.parseInt(pattern.substring(j + 1, j2));
j = j2;
} catch (final NumberFormatException e) {}
}
}
res = parse_i(pattern, i, j + 1);
if (res != null) {
log.printLog();
res.mark ^= mark; // doesn't do anything if no mark was set as x ^ 0 == x
return res;
}
} else if (pattern.charAt(j) == '(') {
j = nextBracket(pattern, ')', '(', j + 1, true);
} else if (pattern.charAt(j) == ')') {
break;
} else if (j == pattern.length() - 1) {
throw new MalformedPatternException(pattern, "Missing closing bracket ')'");
}
}
log.printError();
return null;
} finally {
log.stop();
}
}
case '%': {
if (i == expr.length())
return null;
end = pattern.indexOf('%', j + 1);
if (end == -1)
throw new MalformedPatternException(pattern, "Odd number of '%'");
final String name = "" + pattern.substring(j + 1, end);
final ExprInfo vi = getExprInfo(name);
if (end == pattern.length() - 1) {
i2 = expr.length();
} else {
i2 = next(expr, i, context);
if (i2 == -1)
return null;
}
final ParseLogHandler log = SkriptLogger.startParseLogHandler();
try {
for (; i2 != -1; i2 = next(expr, i2, context)) {
log.clear();
res = parse_i(pattern, i2, end + 1);
if (res != null) {
final ParseLogHandler log2 = SkriptLogger.startParseLogHandler();
try {
for (int k = 0; k < vi.classes.length; k++) {
if ((flags & vi.flagMask) == 0)
continue;
log2.clear();
@SuppressWarnings("unchecked")
final Expression<?> e = new SkriptParser("" + expr.substring(i, i2), flags & vi.flagMask, context).parseExpression(vi.classes[k].getC());
if (e != null) {
if (!vi.isPlural[k] && !e.isSingle()) {
if (context == ParseContext.COMMAND) {
Skript.error(Commands.m_too_many_arguments.toString(vi.classes[k].getName().getIndefiniteArticle(), vi.classes[k].getName().toString()), ErrorQuality.SEMANTIC_ERROR);
return null;
} else {
Skript.error("'" + expr.substring(0, i) + "<...>" + expr.substring(i2) + "' can only accept a single " + vi.classes[k].getName() + ", not more", ErrorQuality.SEMANTIC_ERROR);
return null;
}
}
if (vi.time != 0) {
if (e instanceof Literal<?>)
return null;
if (ScriptLoader.hasDelayBefore == Kleenean.TRUE) {
Skript.error("Cannot use time states after the event has already passed", ErrorQuality.SEMANTIC_ERROR);
return null;
}
if (!e.setTime(vi.time)) {
Skript.error(e + " does not have a " + (vi.time == -1 ? "past" : "future") + " state", ErrorQuality.SEMANTIC_ERROR);
return null;
}
}
log2.printLog();
log.printLog();
res.exprs[countUnescaped(pattern, '%', 0, j) / 2] = e;
return res;
}
}
// results in useless errors most of the time
// Skript.error("'" + expr.substring(i, i2) + "' is " + notOfType(vi.classes), ErrorQuality.NOT_AN_EXPRESSION);
return null;
} finally {
log2.printError();
}
}
}
} finally {
if (!log.isStopped())
log.printError();
}
return null;
}
case '<': {
end = pattern.indexOf('>', j + 1);// not next()
if (end == -1)
throw new MalformedPatternException(pattern, "Missing closing regex bracket '>'");
Pattern p;
try {
p = Pattern.compile(pattern.substring(j + 1, end));
} catch (final PatternSyntaxException e) {
throw new MalformedPatternException(pattern, "Invalid regex <" + pattern.substring(j + 1, end) + ">", e);
}
final ParseLogHandler log = SkriptLogger.startParseLogHandler();
try {
final Matcher m = p.matcher(expr);
for (i2 = next(expr, i, context); i2 != -1; i2 = next(expr, i2, context)) {
log.clear();
m.region(i, i2);
if (m.matches()) {
res = parse_i(pattern, i2, end + 1);
if (res != null) {
res.regexes.add(0, m.toMatchResult());
log.printLog();
return res;
}
}
}
log.printError(null);
return null;
} finally {
log.stop();
}
}
case ']':
case ')':
j++;