JAVA - Expression Parsing and Evaluation Library

I am looking for a JAVA library for parsing and evaluating expressions. I searched and tried some libraries, such as Apache JEXL and Jeval, but they are not quite what I need.

My requirements:

  • Support all value types (i.e. int, double, boolean, String, etc.)
  • Support for all known mathematical and logical operators (+, -, *, <, <=, etc.)
  • Supported variables (without any special notation - for example, in the Jeval variable a should be written as # {a} - not enough for me)
  • Support for user-defined functions - with enforcement and type checking

Any recommendations?

+6
source share
4 answers

Try Janino . This is a RAM runtime compiler that can be used as a means of evaluating expressions. Perhaps this is right for you.

+5
source

As suggested, you can use JavaScript. But also you can take a look at Spring EL , which supports your requirements.

+3
source

You can try mXparser - it supports a significant portion of your requirements:

  • It is based on double, so int is supported, and boolean is supported as true = 1 and false = 0. Unfortunately, strings are not supported.

Boolean example:

import org.mariuszgromada.math.mxparser.*; ... ... Constant T = new Constant("T = 1"); Constant F = new Constant("F = 0"); Expression e = new Expression("T && (F || (F && T))", T, F); System.out.println(e.getExpressionString() + " = " + e.calculate()); 

Result:

 T && (F || (F && T)) = 0.0 
  1. mXparser has wide support for operators, functions , etc. Check out the mXparser math collection . It's good that you can use the help functionality inside the library.

Example:

 import org.mariuszgromada.math.mxparser.*; ... ... mXparser.consolePrintHelp("operator"); 

Result:

 Help content: 2. + <Operator> addition 3. - <Operator> subtraction 4. * <Operator> multiplication 5. / <Operator> division 6. ^ <Operator> exponentiation 7. ! <Operator> factorial 8. # <Operator> modulo function 9. & <Boolean Operator> logical conjunction (AND) 10. && <Boolean Operator> logical conjunction (AND) 11. /\ <Boolean Operator> logical conjunction (AND) 12. ~& <Boolean Operator> NAND - Sheffer stroke 13. ~&& <Boolean Operator> NAND - Sheffer stroke 14. ~/\ <Boolean Operator> NAND - Sheffer stroke 15. | <Boolean Operator> logical disjunction (OR) 16. || <Boolean Operator> logical disjunction (OR) 17. \/ <Boolean Operator> logical disjunction (OR) 18. ~| <Boolean Operator> logical NOR 19. ~|| <Boolean Operator> logical NOR 20. ~\/ <Boolean Operator> logical NOR 21. (+) <Boolean Operator> exclusive or (XOR) 22. --> <Boolean Operator> implication (IMP) 23. <-- <Boolean Operator> converse implication (CIMP) 24. -/> <Boolean Operator> material nonimplication (NIMP) 25. </- <Boolean Operator> converse nonimplication (CNIMP) 26. <-> <Boolean Operator> logical biconditional (EQV) 27. ~ <Boolean Operator> negation 28. Β¬ <Boolean Operator> negation 162. add <Variadic Function> (2.4) Summation operator add(a1,a2,a3,...,an) 168. sum <Calculus Operator> summation operator (SIGMA) sum(i, from, to, f(i,...)) 169. prod <Calculus Operator> product operator (PI) prod(i, from, to, f(i,...)) 170. int <Calculus Operator> definite integral operator ( int(f(x,...), x, a, b) ) 171. der <Calculus Operator> derivative operator ( der(f(x,...), x) ) 172. der- <Calculus Operator> left derivative operator ( der-(f(x,...), x) ) 173. der+ <Calculus Operator> right derivative operator ( der+(f(x,...), x) ) 174. dern <Calculus Operator> n-th derivative operator ( dern(f(x,...), x) ) 175. diff <Calculus Operator> forward difference operator 176. difb <Calculus Operator> backward difference operator 177. avg <Calculus Operator> (2.4) Average operator avg(i, from, to, f(i,...)) 178. vari <Calculus Operator> (2.4) Bias-corrected sample variance operator vari(i, from, to, f(i,...)) 179. stdi <Calculus Operator> (2.4) Bias-corrected sample standard deviation operator stdi(i, from, to, f(i,...)) 180. mini <Calculus Operator> (2.4) Minimum value mini(i, from, to, f(i,...)) 181. maxi <Calculus Operator> (2.4) Maximum value maxi(i, from, to, f(i,...)) 182. solve <Calculus Operator> (4.0) f(x) = 0 equation solving, function root finding: solve( f(x,...), x, a, b ) 301. @~ <Bitwise Operator> (4.0) Bitwise unary complement 302. @& <Bitwise Operator> (4.0) Bitwise AND 303. @^ <Bitwise Operator> (4.0) Bitwise exclusive OR 304. @| <Bitwise Operator> (4.0) Bitwise inclusive OR 305. @<< <Bitwise Operator> (4.0) Signed left shift 306. @>> <Bitwise Operator> (4.0) Signed right shift 
  1. User variables and user constants are created without any special form.

Example:

 import org.mariuszgromada.math.mxparser.*; ... ... Argument x = new Argument("x = 10"); Constant y = new Constant("y = 2"); Expression e = new Expression("x/y", x, y); System.out.println(e.getExpressionString() + " = " + e.calculate()); 

Result:

 x/y = 5.0 

Additionally check: a) Tutorial - User arguments , b) Tutorial - User constants .

  1. Custom features are fully supported.

Example 1 - a body defined at runtime:

 import org.mariuszgromada.math.mxparser.*; ... ... Function f = new Function("f(x,y) = x*y"); Expression e = new Expression("20-f(2,5)",f); System.out.println(e.getExpressionString() + " = " + e.calculate()); 

Result 1

 20-f(2,5) = 10.0 

Example 2 - the body is expanded through your own implementation:

 import org.mariuszgromada.math.mxparser.*; ... ... /* * Implementing FunctionExtension interface */ public class Addition implements FunctionExtension { double x; double y; public Addition() { x = Double.NaN; y = Double.NaN; } public Addition(double x, double y) { this.x = x; this.y = y; } public int getParametersNumber() { return 2; } public void setParameterValue(int argumentIndex, double argumentValue) { if (argumentIndex == 0) x = argumentValue; if (argumentIndex == 1) y = argumentValue; } public double calculate(double... params) { return x+y; } public FunctionExtension clone() { return new Addition(x, y); } } /* * Creating extended function */ Function f = new Function("f", new Addition()); mXparser.consolePrintln("f.calculate(1,2) = " + f.calculate(1,2) ); /* * Using extended function in expression */ Expression e = new Expression("f(2,3)", f); System.out.println(e.getExpressionString() + " = " + e.calculate() ); 

Result 2:

 f.calculate(1,2) = 3.0 f(2,3) = 5.0 

Additionally, it's worth keeping an eye on the entire mXparser Tutorial .

Best wishes

+1
source

Here are some solutions to the problem that you could choose if you did not find the actual Java expression evaluation library:

  • Evaluate your expressions with XPath.
    • Pros: XPath knows logical operators, and you can implement variables and user-defined functions using the Xalan extensions.
    • Cons: XPath has fewer types than Java
  • Rate your expressions with JavaScript.
    • Pros: Javascript is very flexible and still works when your requirements drag on. You can implement variables and custom functions using Javascript as well
    • Cons: Javascript has fewer types than Java
  • Evaluate your expressions using the JSP expression language (e.g. JUEL )
0
source

Source: https://habr.com/ru/post/922801/


All Articles