mirror of
https://github.com/Flowsqy/ShopChest.git
synced 2024-11-26 01:05:12 +01:00
Improve and fix unit detection, add nodes
This commit is contained in:
parent
e2f4afde4b
commit
b8fc15a6a8
@ -0,0 +1,29 @@
|
|||||||
|
package de.epiceric.shopchest.config.hologram.parser;
|
||||||
|
|
||||||
|
public class Counter {
|
||||||
|
|
||||||
|
private int value;
|
||||||
|
|
||||||
|
public Counter() {
|
||||||
|
this(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Counter(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int get() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Counter increment() {
|
||||||
|
value++;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Counter decrement() {
|
||||||
|
value--;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package de.epiceric.shopchest.config.hologram.parser;
|
package de.epiceric.shopchest.config.hologram.parser;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -39,118 +41,149 @@ public class FormatParser {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean isSpace = currentChar == ' ';
|
// Unit detection
|
||||||
final boolean isOpenParenthesis = currentChar == '(';
|
if (currentChar == '(') {
|
||||||
final boolean isCloseParenthesis = currentChar == ')';
|
final Token<?> token = getToken(currentToken);
|
||||||
final boolean isLastChar = index + 1 >= chars.length;
|
if (token != null) {
|
||||||
|
tokens.add(token);
|
||||||
// Handle specific token
|
|
||||||
if (
|
|
||||||
isSpace ||
|
|
||||||
isOpenParenthesis ||
|
|
||||||
isCloseParenthesis ||
|
|
||||||
isLastChar
|
|
||||||
) {
|
|
||||||
if (isLastChar) {
|
|
||||||
// Add the last char only if it's the last (otherwise it will be skipped)
|
|
||||||
currentToken.append(currentChar);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If it's empty, don't need to add a token
|
|
||||||
if (currentToken.length() == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String stringToken = currentToken.toString();
|
|
||||||
|
|
||||||
// Double detection
|
|
||||||
try {
|
|
||||||
final double doubleValue = Double.parseDouble(stringToken);
|
|
||||||
tokens.add(new Token<>(Token.DOUBLE, doubleValue));
|
|
||||||
|
|
||||||
// Duplicate due to the double detection with exception
|
|
||||||
|
|
||||||
// Reset the specific token
|
|
||||||
currentToken = new StringBuilder();
|
currentToken = new StringBuilder();
|
||||||
|
|
||||||
// Unit detection
|
|
||||||
if (isOpenParenthesis) {
|
|
||||||
tokens.add(new Token<>(Token.BEGIN_UNIT, null));
|
|
||||||
} else if (isCloseParenthesis) {
|
|
||||||
tokens.add(new Token<>(Token.END_UNIT, null));
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
}
|
||||||
|
tokens.add(new Token<>(Token.BEGIN_UNIT, null));
|
||||||
// Operator detection
|
} else if (currentChar == ')') {
|
||||||
final Token<?> token;
|
final Token<?> token = getToken(currentToken);
|
||||||
switch (stringToken) {
|
if (token != null) {
|
||||||
// Calculation
|
tokens.add(token);
|
||||||
case "+":
|
currentToken = new StringBuilder();
|
||||||
token = new Token<>(Token.CALCULATION_OPERATOR, Token.CalculationOperator.ADDITION);
|
|
||||||
break;
|
|
||||||
case "-":
|
|
||||||
token = new Token<>(Token.CALCULATION_OPERATOR, Token.CalculationOperator.SUBTRACTION);
|
|
||||||
break;
|
|
||||||
case "*":
|
|
||||||
token = new Token<>(Token.CALCULATION_OPERATOR, Token.CalculationOperator.MULTIPLICATION);
|
|
||||||
break;
|
|
||||||
case "/":
|
|
||||||
token = new Token<>(Token.CALCULATION_OPERATOR, Token.CalculationOperator.DIVISION);
|
|
||||||
break;
|
|
||||||
case "%":
|
|
||||||
token = new Token<>(Token.CALCULATION_OPERATOR, Token.CalculationOperator.MODULO);
|
|
||||||
break;
|
|
||||||
// Logic
|
|
||||||
case "&&":
|
|
||||||
token = new Token<>(Token.LOGIC_OPERATOR, Token.LogicOperator.AND);
|
|
||||||
break;
|
|
||||||
case "||":
|
|
||||||
token = new Token<>(Token.LOGIC_OPERATOR, Token.LogicOperator.OR);
|
|
||||||
break;
|
|
||||||
// Condition
|
|
||||||
case "==":
|
|
||||||
token = new Token<>(Token.CONDITION_OPERATOR, Token.ConditionOperator.EQUAL);
|
|
||||||
break;
|
|
||||||
case "!=":
|
|
||||||
token = new Token<>(Token.CONDITION_OPERATOR, Token.ConditionOperator.NOT_EQUAL);
|
|
||||||
break;
|
|
||||||
case ">":
|
|
||||||
token = new Token<>(Token.CONDITION_OPERATOR, Token.ConditionOperator.GREATER);
|
|
||||||
break;
|
|
||||||
case "<":
|
|
||||||
token = new Token<>(Token.CONDITION_OPERATOR, Token.ConditionOperator.LESS);
|
|
||||||
break;
|
|
||||||
case ">=":
|
|
||||||
token = new Token<>(Token.CONDITION_OPERATOR, Token.ConditionOperator.GREATER_OR_EQUAL);
|
|
||||||
break;
|
|
||||||
case "<=":
|
|
||||||
token = new Token<>(Token.CONDITION_OPERATOR, Token.ConditionOperator.LESS_OR_EQUAL);
|
|
||||||
break;
|
|
||||||
// Boolean
|
|
||||||
default:
|
|
||||||
token = new Token<>(Token.BOOLEAN, stringToken);
|
|
||||||
}
|
}
|
||||||
|
tokens.add(new Token<>(Token.END_UNIT, null));
|
||||||
tokens.add(token);
|
} else if (currentChar == ' ') {
|
||||||
|
final Token<?> token = getToken(currentToken);
|
||||||
// Reset the specific token
|
if (token != null) {
|
||||||
currentToken = new StringBuilder();
|
tokens.add(token);
|
||||||
|
currentToken = new StringBuilder();
|
||||||
// Unit detection
|
|
||||||
if (isOpenParenthesis) {
|
|
||||||
tokens.add(new Token<>(Token.BEGIN_UNIT, null));
|
|
||||||
} else if (isCloseParenthesis) {
|
|
||||||
tokens.add(new Token<>(Token.END_UNIT, null));
|
|
||||||
}
|
}
|
||||||
continue;
|
} else if (index + 1 >= chars.length) {
|
||||||
|
// Add the last char only if it's the last (otherwise it will be skipped)
|
||||||
|
currentToken.append(currentChar);
|
||||||
|
final Token<?> token = getToken(currentToken);
|
||||||
|
if (token != null) {
|
||||||
|
tokens.add(token);
|
||||||
|
currentToken = new StringBuilder();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Add the char to currentToken to handle specific token
|
||||||
|
currentToken.append(currentChar);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the char to currentToken to handle specific token
|
|
||||||
currentToken.append(currentChar);
|
|
||||||
}
|
}
|
||||||
return tokens;
|
return new ArrayList<>(tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Token<?> getToken(StringBuilder currentToken) {
|
||||||
|
// If it's empty, don't need to add a token
|
||||||
|
if (currentToken.length() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String stringToken = currentToken.toString();
|
||||||
|
|
||||||
|
// Double detection
|
||||||
|
try {
|
||||||
|
final double doubleValue = Double.parseDouble(stringToken);
|
||||||
|
return new Token<>(Token.DOUBLE, doubleValue);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Operator detection
|
||||||
|
final Token<?> token;
|
||||||
|
switch (stringToken) {
|
||||||
|
// Calculation
|
||||||
|
case "+":
|
||||||
|
token = new Token<>(Token.CALCULATION_OPERATOR, Token.CalculationOperator.ADDITION);
|
||||||
|
break;
|
||||||
|
case "-":
|
||||||
|
token = new Token<>(Token.CALCULATION_OPERATOR, Token.CalculationOperator.SUBTRACTION);
|
||||||
|
break;
|
||||||
|
case "*":
|
||||||
|
token = new Token<>(Token.CALCULATION_OPERATOR, Token.CalculationOperator.MULTIPLICATION);
|
||||||
|
break;
|
||||||
|
case "/":
|
||||||
|
token = new Token<>(Token.CALCULATION_OPERATOR, Token.CalculationOperator.DIVISION);
|
||||||
|
break;
|
||||||
|
case "%":
|
||||||
|
token = new Token<>(Token.CALCULATION_OPERATOR, Token.CalculationOperator.MODULO);
|
||||||
|
break;
|
||||||
|
// Logic
|
||||||
|
case "&&":
|
||||||
|
token = new Token<>(Token.LOGIC_OPERATOR, Token.LogicOperator.AND);
|
||||||
|
break;
|
||||||
|
case "||":
|
||||||
|
token = new Token<>(Token.LOGIC_OPERATOR, Token.LogicOperator.OR);
|
||||||
|
break;
|
||||||
|
// Condition
|
||||||
|
case "==":
|
||||||
|
token = new Token<>(Token.CONDITION_OPERATOR, Token.ConditionOperator.EQUAL);
|
||||||
|
break;
|
||||||
|
case "!=":
|
||||||
|
token = new Token<>(Token.CONDITION_OPERATOR, Token.ConditionOperator.NOT_EQUAL);
|
||||||
|
break;
|
||||||
|
case ">":
|
||||||
|
token = new Token<>(Token.CONDITION_OPERATOR, Token.ConditionOperator.GREATER);
|
||||||
|
break;
|
||||||
|
case "<":
|
||||||
|
token = new Token<>(Token.CONDITION_OPERATOR, Token.ConditionOperator.LESS);
|
||||||
|
break;
|
||||||
|
case ">=":
|
||||||
|
token = new Token<>(Token.CONDITION_OPERATOR, Token.ConditionOperator.GREATER_OR_EQUAL);
|
||||||
|
break;
|
||||||
|
case "<=":
|
||||||
|
token = new Token<>(Token.CONDITION_OPERATOR, Token.ConditionOperator.LESS_OR_EQUAL);
|
||||||
|
break;
|
||||||
|
// Boolean
|
||||||
|
default:
|
||||||
|
token = new Token<>(Token.VALUE, stringToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Token<?>> createNode(Iterable<Token<?>> tokens) {
|
||||||
|
final Iterator<Token<?>> tokenIterator = tokens.iterator();
|
||||||
|
final Counter counter = new Counter();
|
||||||
|
final List<Token<?>> resolvedTokens = resolveNode(tokenIterator, counter).getValue();
|
||||||
|
if (counter.get() > 0) {
|
||||||
|
throw new RuntimeException("Start unit '(' without closing it");
|
||||||
|
} else if (counter.get() < 0) {
|
||||||
|
throw new RuntimeException("End unit ')' without starting it");
|
||||||
|
}
|
||||||
|
return resolvedTokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Token<List<Token<?>>> resolveNode(Iterator<Token<?>> tokens, Counter counter) {
|
||||||
|
final List<Token<?>> nodeTokens = new LinkedList<>();
|
||||||
|
while (tokens.hasNext()) {
|
||||||
|
final Token<?> token = tokens.next();
|
||||||
|
if (token.getType() == Token.END_UNIT) {
|
||||||
|
counter.decrement();
|
||||||
|
break;
|
||||||
|
} else if (token.getType() == Token.BEGIN_UNIT) {
|
||||||
|
nodeTokens.add(resolveNode(tokens, counter.increment()));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
nodeTokens.add(token);
|
||||||
|
}
|
||||||
|
if (nodeTokens.isEmpty()) {
|
||||||
|
// TODO Create a custom exception
|
||||||
|
throw new RuntimeException("Empty unit '( )'");
|
||||||
|
}
|
||||||
|
if (nodeTokens.size() == 1) {
|
||||||
|
final Token<?> token = nodeTokens.get(0);
|
||||||
|
if (token.getType() == Token.NODE) {
|
||||||
|
return (Token<List<Token<?>>>) token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Token<>(Token.NODE, nodeTokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
package de.epiceric.shopchest.config.hologram.parser;
|
package de.epiceric.shopchest.config.hologram.parser;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class Token<T> {
|
public class Token<T> {
|
||||||
|
|
||||||
public final static TokenType<String> STRING = new TokenType<>("String");
|
public final static TokenType<String> STRING = new TokenType<>("String");
|
||||||
public final static TokenType<Double> DOUBLE = new TokenType<>("Double");
|
public final static TokenType<Double> DOUBLE = new TokenType<>("Double");
|
||||||
public final static TokenType<String> BOOLEAN = new TokenType<>("Boolean");
|
public final static TokenType<String> VALUE = new TokenType<>("Value");
|
||||||
public final static TokenType<Void> BEGIN_UNIT = new TokenType<>("Begin unit");
|
public final static TokenType<Void> BEGIN_UNIT = new TokenType<>("Begin unit");
|
||||||
public final static TokenType<Void> END_UNIT = new TokenType<>("End unit");
|
public final static TokenType<Void> END_UNIT = new TokenType<>("End unit");
|
||||||
public final static TokenType<Void> REVERSE = new TokenType<>("Reverse");
|
public final static TokenType<Void> REVERSE = new TokenType<>("Reverse");
|
||||||
public final static TokenType<ConditionOperator> CONDITION_OPERATOR = new TokenType<>("Condition operator");
|
public final static TokenType<ConditionOperator> CONDITION_OPERATOR = new TokenType<>("Condition operator");
|
||||||
public final static TokenType<LogicOperator> LOGIC_OPERATOR = new TokenType<>("Logic operator");
|
public final static TokenType<LogicOperator> LOGIC_OPERATOR = new TokenType<>("Logic operator");
|
||||||
public final static TokenType<CalculationOperator> CALCULATION_OPERATOR = new TokenType<>("Calculation operator");
|
public final static TokenType<CalculationOperator> CALCULATION_OPERATOR = new TokenType<>("Calculation operator");
|
||||||
|
public final static TokenType<List<Token<?>>> NODE = new TokenType<>("Node");
|
||||||
private final TokenType<T> type;
|
private final TokenType<T> type;
|
||||||
private final T value;
|
private final T value;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user