FunctionParser can now parse functions with any number of arguments
added a few functions to StringEquationParser
This commit is contained in:
parent
6a9f69e3cd
commit
d0468fcdd9
1 changed files with 59 additions and 23 deletions
|
@ -17,24 +17,6 @@ public class StringEquationParser {
|
||||||
return Optional.of(parse(toParse.substring(1, toParse.length() - 1)));
|
return Optional.of(parse(toParse.substring(1, toParse.length() - 1)));
|
||||||
});
|
});
|
||||||
|
|
||||||
//+, -
|
|
||||||
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> sumOperations = new HashMap<>();
|
|
||||||
sumOperations.put("+", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) + second.apply(stringDoubleMap));
|
|
||||||
sumOperations.put("-", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) - second.apply(stringDoubleMap));
|
|
||||||
parseRules.add(new SplitterParser(sumOperations));
|
|
||||||
|
|
||||||
//*, /, %
|
|
||||||
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> dotOperations = new HashMap<>();
|
|
||||||
dotOperations.put("*", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) * second.apply(stringDoubleMap));
|
|
||||||
dotOperations.put("/", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) / second.apply(stringDoubleMap));
|
|
||||||
dotOperations.put("%", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) % second.apply(stringDoubleMap));
|
|
||||||
parseRules.add(new SplitterParser(dotOperations));
|
|
||||||
|
|
||||||
//x^y
|
|
||||||
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> exponentOperations = new HashMap<>();
|
|
||||||
exponentOperations.put("^", (stringDoubleMap, first, second) -> Math.pow(first.apply(stringDoubleMap), second.apply(stringDoubleMap)));
|
|
||||||
parseRules.add(new SplitterParser(exponentOperations));
|
|
||||||
|
|
||||||
// try to parse as Double
|
// try to parse as Double
|
||||||
parseRules.add(toParse -> {
|
parseRules.add(toParse -> {
|
||||||
try {
|
try {
|
||||||
|
@ -45,7 +27,52 @@ public class StringEquationParser {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//variable replacer
|
// +, -
|
||||||
|
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> sumOperations = new HashMap<>();
|
||||||
|
sumOperations.put("+", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) + second.apply(stringDoubleMap));
|
||||||
|
sumOperations.put("-", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) - second.apply(stringDoubleMap));
|
||||||
|
parseRules.add(new SplitterParser(sumOperations));
|
||||||
|
|
||||||
|
// *, /, %
|
||||||
|
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> dotOperations = new HashMap<>();
|
||||||
|
dotOperations.put("*", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) * second.apply(stringDoubleMap));
|
||||||
|
dotOperations.put("/", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) / second.apply(stringDoubleMap));
|
||||||
|
dotOperations.put("%", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) % second.apply(stringDoubleMap));
|
||||||
|
parseRules.add(new SplitterParser(dotOperations));
|
||||||
|
|
||||||
|
// x^y
|
||||||
|
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> exponentOperations = new HashMap<>();
|
||||||
|
exponentOperations.put("^", (stringDoubleMap, first, second) -> Math.pow(first.apply(stringDoubleMap), second.apply(stringDoubleMap)));
|
||||||
|
parseRules.add(new SplitterParser(exponentOperations));
|
||||||
|
|
||||||
|
// H with H(0) = 1: https://en.wikipedia.org/wiki/Heaviside_step_function
|
||||||
|
parseRules.add(new FunctionParser("H", 1, 1, ((stringDoubleMap, equations) -> equations[0].apply(stringDoubleMap) >= 0 ? 1d : 0d)));
|
||||||
|
|
||||||
|
// floor
|
||||||
|
parseRules.add(new FunctionParser("floor", 1, 1, ((stringDoubleMap, equations) -> Math.floor(equations[0].apply(stringDoubleMap)))));
|
||||||
|
|
||||||
|
// ceil
|
||||||
|
parseRules.add(new FunctionParser("ceil", 1, 1, ((stringDoubleMap, equations) -> Math.ceil(equations[0].apply(stringDoubleMap)))));
|
||||||
|
|
||||||
|
// max
|
||||||
|
parseRules.add(new FunctionParser("max", 2, -1, ((stringDoubleMap, equations) -> {
|
||||||
|
Double max = equations[0].apply(stringDoubleMap);
|
||||||
|
for (int i = 1; i < equations.length; i++) {
|
||||||
|
max = Math.max(max, equations[i].apply(stringDoubleMap));
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
})));
|
||||||
|
|
||||||
|
// min
|
||||||
|
parseRules.add(new FunctionParser("min", 2, -1, ((stringDoubleMap, equations) -> {
|
||||||
|
Double min = equations[0].apply(stringDoubleMap);
|
||||||
|
for (int i = 1; i < equations.length; i++) {
|
||||||
|
min = Math.min(min, equations[i].apply(stringDoubleMap));
|
||||||
|
}
|
||||||
|
return min;
|
||||||
|
})));
|
||||||
|
|
||||||
|
// variable replacer
|
||||||
parseRules.add(new VariableReplacer());
|
parseRules.add(new VariableReplacer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,18 +135,27 @@ public class StringEquationParser {
|
||||||
|
|
||||||
private static class FunctionParser implements EquationParser {
|
private static class FunctionParser implements EquationParser {
|
||||||
private final String functionString;
|
private final String functionString;
|
||||||
private final BiFunction<Map<String, Double>, Equation, Double> function;
|
private final int minArguments;
|
||||||
|
private final int maxArguments;
|
||||||
|
private final BiFunction<Map<String, Double>, Equation[], Double> function;
|
||||||
|
|
||||||
public FunctionParser(String functionString, BiFunction<Map<String, Double>, Equation, Double> function) {
|
public FunctionParser(String functionString, int minArguments, int maxArguments, BiFunction<Map<String, Double>, Equation[], Double> function) {
|
||||||
this.functionString = functionString + "(";
|
this.functionString = functionString + "(";
|
||||||
|
this.minArguments = minArguments;
|
||||||
|
this.maxArguments = maxArguments;
|
||||||
this.function = function;
|
this.function = function;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Equation> tryParse(String toParse) throws EquationParseException {
|
public Optional<Equation> tryParse(String toParse) throws EquationParseException {
|
||||||
if (!toParse.startsWith(functionString) || !toParse.endsWith(")")) return Optional.empty();
|
if (!toParse.startsWith(functionString) || !toParse.endsWith(")")) return Optional.empty();
|
||||||
final Equation equation = parse(toParse.substring(functionString.length(), toParse.length()-1));
|
String[] arguments = toParse.substring(functionString.length(), toParse.length()-1).split(",");
|
||||||
return Optional.of(stringDoubleMap -> function.apply(stringDoubleMap, equation));
|
if (minArguments > arguments.length || (maxArguments < arguments.length && maxArguments != -1)) return Optional.empty();
|
||||||
|
final Equation[] argumentEquations = new Equation[arguments.length];
|
||||||
|
for (int i = 0; i < arguments.length; i++) {
|
||||||
|
argumentEquations[i] = parse(arguments[i]);
|
||||||
|
}
|
||||||
|
return Optional.of(stringDoubleMap -> function.apply(stringDoubleMap, argumentEquations));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue