문제

How to evaluate complex boolean expressions generated at runtime in a Java program?

Example:

(x and y or z) and s

with x, y, z boolean variables ...

Thanks

도움이 되었습니까?

해결책

Use http://docs.codehaus.org/display/JANINO/Home for minimum work. I can do much more than simple expressions.

다른 팁

Very briefly, you need an "intermediate representation" of the Boolean expressions. This is a tree formed of Node objects. Node has ths subclasses AndNode, OrNode, NotNode, and VariableNode. An AndNode has two child Nodes, an OrNode has two child Nodes, and a NotNode has one child Node.

A VariableNode has just a variable name String, eg, "x". You would have a HashMap<String, Boolean> where each variable name key has an associated Boolean value.

Each Node class has an eval() method that evaluates its expression and returns a boolean. The VariableNode.eval() method looks up the value of the variable in your HashMap and returns it. NotNode.eval() returns !child.eval(). AndNode.evaluate() returns child1.eval() && child2.eval(), while OrNode.evaluate() returns child1.eval() || child2.eval(). To evaluate an entire Boolean expression tree, just call the root node's eval() method.

You can build these Boolean expression trees programmatically, using Java constructors, etc.

If you want to build your expression trees from strings, you'll need to write a parser that produces a tree from a string. Terence Parr's Language Implementation Patterns is a very simple and clear introduction to this.

How to evaluate a logical expression? Logical expressions such as those can be evaluated as a syntax tree, and I think that there's some good information in this related question Logic expression parser

The other thing that springs to mind is that you want to be able to handle logical expressions as data, which seems like something more suited to a scripting language like maybe Jython, JRuby, Groovy or Scala (assuming you're restricted to the JVM). Although I doubt it'd be very hard to write a parser to handle basic and/or/not logical expressions.

You will have to generate an expression tree and bind each leaf to a boolean value. For parsing this expression and generating an AST take a look at Dijkstra's Shunting Yard algorithm. Everything is explained in there and is fairly straight forward to implement.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top