AdvancedScripts/src/main/java/de/zonlykroks/advancedscripts/lexer/ExpressionColorizer.java

135 Zeilen
5.1 KiB
Java

package de.zonlykroks.advancedscripts.lexer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ExpressionColorizer {
private ExpressionColorizer() {
throw new IllegalStateException("Utility class");
}
public static List<Token> colorize(String expression) {
List<String> parts = tokenize(expression);
List<Token> tokens = new ArrayList<>();
for (int i = 0; i < parts.size(); i++) {
String part = parts.get(i);
if ("{".equals(part) || "}".equals(part)) {
tokens.add(new Token(part, TokenTypeColors.OTHER));
continue;
}
if ("true".equalsIgnoreCase(part) || "false".equalsIgnoreCase(part)) {
tokens.add(new Token(part, TokenTypeColors.BOOLEAN));
continue;
}
try {
Double.parseDouble(part);
tokens.add(new Token(part, TokenTypeColors.NUMBER));
continue;
} catch (NumberFormatException ignored) {
}
try {
Long.parseLong(part);
tokens.add(new Token(part, TokenTypeColors.NUMBER));
continue;
} catch (NumberFormatException ignored) {
}
if (part.contains(".")) {
String[] split = part.split("\\.");
if (split.length == 1) {
tokens.add(new Token(part, TokenTypeColors.VARIABLE));
continue;
}
if (VariablePrefixes.RPEFIXES.contains(split[0])) {
tokens.add(new Token(split[0], TokenTypeColors.OTHER));
tokens.add(new Token(".", TokenTypeColors.OTHER));
split = Arrays.copyOfRange(split, 1, split.length);
}
tokens.add(new Token(split[0], TokenTypeColors.VARIABLE));
for (int j = 1; j < split.length; j++) {
String s = split[j];
tokens.add(new Token(".", TokenTypeColors.OTHER));
if (VariableSuffixes.SUFFIXES.contains(s)) {
tokens.add(new Token(s, TokenTypeColors.OTHER));
} else {
tokens.add(new Token(s, TokenTypeColors.ERROR));
}
}
continue;
}
if (Operators.OPERATORS.contains(part)) {
String previous = get(parts, i, -1);
String next = get(parts, i, 1);
if (previous == null || next == null) {
tokens.add(new Token(part, TokenTypeColors.ERROR));
continue;
}
if (Operators.OPERATORS.contains(previous) || Operators.OPERATORS.contains(next)) {
tokens.add(new Token(part, TokenTypeColors.ERROR));
continue;
}
if ("{".equals(previous) || "}".equals(next)) {
tokens.add(new Token(part, TokenTypeColors.ERROR));
continue;
}
tokens.add(new Token(part, TokenTypeColors.OTHER));
continue;
}
if (part.matches("[+\\-*/%^&|<>=!]+")) {
tokens.add(new Token(part, TokenTypeColors.ERROR));
continue;
}
tokens.add(new Token(part, TokenTypeColors.VARIABLE));
}
return tokens;
}
private static String get(List<String> parts, int index, int direction) {
for (int i = index + direction; i >= 0 && i < parts.size(); i += direction) {
String part = parts.get(i);
if (!part.isBlank()) return part;
}
return null;
}
private static List<String> tokenize(String s) {
List<String> tokens = new ArrayList<>();
StringBuilder token = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '{' || c == '}' || c == ' ') {
if (token.length() > 0) {
tokens.add(token.toString());
token = new StringBuilder();
}
tokens.add(c + "");
continue;
}
StringBuilder op = new StringBuilder();
for (int j = i; j < s.length(); j++) {
char k = s.charAt(j);
if (k == '+' || k == '-' || k == '*' || k == '/' || k == '%' || k == '^' || k == '&' || k == '|' || k == '>' || k == '<' || k == '=' || k == '!') {
op.append(k);
} else {
break;
}
}
if (op.length() > 0) {
if (token.length() > 0) {
tokens.add(token.toString());
token = new StringBuilder();
}
tokens.add(op.toString());
i += op.length() - 1;
continue;
}
token.append(c);
}
if (token.length() > 0) {
tokens.add(token.toString());
}
return tokens;
}
}