Add final parse method

This commit is contained in:
Flowsqy 2022-02-23 16:31:33 +01:00
parent 69993536e5
commit 159abf6286
2 changed files with 156 additions and 6 deletions

View File

@ -11,7 +11,7 @@ import java.util.function.Function;
public class FormatParser { public class FormatParser {
public List<Token<?>> getTokens(String string) { private List<Token<?>> getTokens(String string) {
final List<Token<?>> tokens = new LinkedList<>(); final List<Token<?>> tokens = new LinkedList<>();
final char[] chars = string.toCharArray(); final char[] chars = string.toCharArray();
@ -83,7 +83,7 @@ public class FormatParser {
return new ArrayList<>(tokens); return new ArrayList<>(tokens);
} }
public Token<?> getToken(StringBuilder currentToken) { private Token<?> getToken(StringBuilder currentToken) {
// If it's empty, don't need to add a token // If it's empty, don't need to add a token
if (currentToken.length() == 0) { if (currentToken.length() == 0) {
return null; return null;
@ -151,7 +151,7 @@ public class FormatParser {
return token; return token;
} }
public List<Token<?>> createNode(Iterable<Token<?>> tokens) { private List<Token<?>> createNode(Iterable<Token<?>> tokens) {
final Iterator<Token<?>> tokenIterator = tokens.iterator(); final Iterator<Token<?>> tokenIterator = tokens.iterator();
final Counter counter = new Counter(); final Counter counter = new Counter();
final List<Token<?>> resolvedTokens = resolveNode(tokenIterator, counter).getValue(); final List<Token<?>> resolvedTokens = resolveNode(tokenIterator, counter).getValue();
@ -165,7 +165,7 @@ public class FormatParser {
return resolvedTokens; return resolvedTokens;
} }
public Token<List<Token<?>>> resolveNode(Iterator<Token<?>> tokens, Counter counter) { private Token<List<Token<?>>> resolveNode(Iterator<Token<?>> tokens, Counter counter) {
final List<Token<?>> nodeTokens = new LinkedList<>(); final List<Token<?>> nodeTokens = new LinkedList<>();
while (tokens.hasNext()) { while (tokens.hasNext()) {
final Token<?> token = tokens.next(); final Token<?> token = tokens.next();
@ -213,7 +213,7 @@ public class FormatParser {
return null; return null;
} }
public <P> Token<?> createFunctions(Iterable<Token<?>> tokens, Function<String, P> providerFunction, Map<P, Class<?>> providerTypes) { private <P> Token<?> createFunctions(Iterable<Token<?>> tokens, Function<String, P> providerFunction, Map<P, Class<?>> providerTypes) {
Chain<Token<?>> tokensChain = Chain.getChain(tokens); Chain<Token<?>> tokensChain = Chain.getChain(tokens);
if (tokensChain == null) { if (tokensChain == null) {
return null; return null;
@ -658,7 +658,7 @@ public class FormatParser {
// It uses a valid provided value // It uses a valid provided value
if (provided != null) { if (provided != null) {
final Class<?> providedClass = providerTypes.get(provided); final Class<?> providedClass = providerTypes.get(provided);
// The provided value is a number // The provided value is a string
if (providedClass == String.class) { if (providedClass == String.class) {
// Return the provided key // Return the provided key
return new MapProvider.StringMapProvider<>(provided); return new MapProvider.StringMapProvider<>(provided);
@ -675,4 +675,75 @@ public class FormatParser {
return null; return null;
} }
public <P> ParserResult<P> parse(String input, Function<String, P> providerFunction, Map<P, Class<?>> providerTypes) {
final List<Token<?>> tokens = getTokens(input);
final List<Token<?>> tokenNode = createNode(tokens);
final Token<?> token = createFunctions(tokenNode, providerFunction, providerTypes);
if (token == null) {
return new ParserResult<>(null, null, null, null);
}
// Constant check
if (token.getType() == Token.VALUE) {
final String value = (String) token.getValue();
final P provided = providerFunction.apply(value);
// It uses a valid provided value
if (provided != null) {
final Class<?> providedClass = providerTypes.get(provided);
// The provided value is a number
if (providedClass == String.class) {
// Return the provided key
return new ParserResult<>(
null,
null,
new MapProvider.StringMapProvider<>(provided),
null
);
}
if (providedClass == Boolean.class) {
return new ParserResult<>(
new ProviderCondition<>(new MapProvider.BooleanMapProvider<>(provided)),
null,
null,
null
);
}
if (providedClass == Double.class) {
return new ParserResult<>(
null,
null,
new MapProvider.DoubleMapProvider<>(provided),
null
);
}
// Normally impossible
throw new RuntimeException("'" + value + "' can not be used as constant, its type is not handled");
} else {
throw new RuntimeException("'" + value + "' does not exist");
}
} else if (token.getType() == Token.DOUBLE || token.getType() == Token.STRING) {
return new ParserResult<>(
null,
null,
null,
token.getValue()
);
} else if (token.getType() == Token.CALCULATION) {
return new ParserResult<>(null,
cast(token.getValue()),
null,
null
);
} else if (token.getType() == Token.CONDITION) {
return new ParserResult<>(
cast(token.getValue()),
null,
null,
null
);
}
throw new RuntimeException("Can not figure out what is the type of the parsed input");
}
} }

View File

@ -0,0 +1,79 @@
package de.epiceric.shopchest.config.hologram.parser;
import de.epiceric.shopchest.config.hologram.calculation.Calculation;
import de.epiceric.shopchest.config.hologram.condition.Condition;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
public class ParserResult<P> {
private final Condition<Map<P, Object>> condition;
private final Calculation<Map<P, Object>> calculation;
private final Function<Map<P, Object>, ?> value;
private final Object constant;
public ParserResult(Condition<Map<P, Object>> condition, Calculation<Map<P, Object>> calculation, Function<Map<P, Object>, ?> value, Object constant) {
this.condition = condition;
this.calculation = calculation;
this.value = value;
this.constant = constant;
}
public Condition<Map<P, Object>> getCondition() {
return condition;
}
public Calculation<Map<P, Object>> getCalculation() {
return calculation;
}
public Function<Map<P, Object>, ?> getValue() {
return value;
}
public Object getConstant() {
return constant;
}
public boolean isCondition() {
return condition != null;
}
public boolean isCalculation() {
return calculation != null;
}
public boolean isValue() {
return value != null;
}
public boolean isConstant() {
return constant != null;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ParserResult<?> that = (ParserResult<?>) o;
return Objects.equals(condition, that.condition) && Objects.equals(calculation, that.calculation) && Objects.equals(value, that.value) && Objects.equals(constant, that.constant);
}
@Override
public int hashCode() {
return Objects.hash(condition, calculation, value, constant);
}
@Override
public String toString() {
return "ParserResult{" +
"condition=" + condition +
", calculation=" + calculation +
", value=" + value +
", constant=" + constant +
'}';
}
}