boolean expression parser in java

后端 未结 5 761
北恋
北恋 2020-11-27 21:30

Are there any java libraries or techniques to parsing boolean expressions piecemeal?

What I mean is given an expression like this:

T &

相关标签:
5条回答
  • 2020-11-27 21:58

    I recently put together a library in Java specifically to manipulate boolean expressions: jbool_expressions.

    It includes a tool too parse expressions out of string input:

    Expression<String> expr = ExprParser.parse("( ( (! C) | C) & A & B)")
    

    You can also do some fairly simple simplification:

    Expression<String> simplified = RuleSet.simplify(expr);
    System.out.println(expr);
    

    gives

    (A & B)
    

    If you wanted to step through the assignment then, you could assign values one by one. For the example here,

    Expression<String> halfAssigned = RuleSet.assign(simplified, Collections.singletonMap("A", true));
    System.out.println(halfAssigned);
    

    shows

    B
    

    and you could resolve it by assigning B.

    Expression<String> resolved = RuleSet.assign(halfAssigned, Collections.singletonMap("B", true));
    System.out.println(resolved);
    

    shows

    true
    

    Not 100% what you were asking for, but hope it helps.

    0 讨论(0)
  • 2020-11-27 22:03

    I've coded this using Javaluator.
    It's not exactly the output you are looking for, but I think it could be a start point.

    package test;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    
    import net.astesana.javaluator.*;
    
    public class TreeBooleanEvaluator extends AbstractEvaluator<String> {
      /** The logical AND operator.*/
      final static Operator AND = new Operator("&&", 2, Operator.Associativity.LEFT, 2);
      /** The logical OR operator.*/
      final static Operator OR = new Operator("||", 2, Operator.Associativity.LEFT, 1);
        
      private static final Parameters PARAMETERS;
    
      static {
        // Create the evaluator's parameters
        PARAMETERS = new Parameters();
        // Add the supported operators
        PARAMETERS.add(AND);
        PARAMETERS.add(OR);
        // Add the parentheses
        PARAMETERS.addExpressionBracket(BracketPair.PARENTHESES);
      }
    
      public TreeBooleanEvaluator() {
        super(PARAMETERS);
      }
    
      @Override
      protected String toValue(String literal, Object evaluationContext) {
        return literal;
      }
            
      private boolean getValue(String literal) {
        if ("T".equals(literal) || literal.endsWith("=true")) return true;
        else if ("F".equals(literal) || literal.endsWith("=false")) return false;
        throw new IllegalArgumentException("Unknown literal : "+literal);
      }
        
      @Override
      protected String evaluate(Operator operator, Iterator<String> operands,
          Object evaluationContext) {
        List<String> tree = (List<String>) evaluationContext;
        String o1 = operands.next();
        String o2 = operands.next();
        Boolean result;
        if (operator == OR) {
          result = getValue(o1) || getValue(o2);
        } else if (operator == AND) {
          result = getValue(o1) && getValue(o2);
        } else {
          throw new IllegalArgumentException();
        }
        String eval = "("+o1+" "+operator.getSymbol()+" "+o2+")="+result;
        tree.add(eval);
        return eval;
      }
            
      public static void main(String[] args) {
        TreeBooleanEvaluator evaluator = new TreeBooleanEvaluator();
        doIt(evaluator, "T && ( F || ( F && T ) )");
        doIt(evaluator, "(T && T) || ( F && T )");
      }
        
      private static void doIt(TreeBooleanEvaluator evaluator, String expression) {
        List<String> sequence = new ArrayList<String>();
        evaluator.evaluate(expression, sequence);
        System.out.println ("Evaluation sequence for :"+expression);
        for (String string : sequence) {
          System.out.println (string);
        }
        System.out.println ();
      }
    }
    

    Here is the ouput:

    Evaluation sequence for :T && ( F || ( F && T ) )
    (F && T)=false
    (F || (F && T)=false)=false
    (T && (F || (F && T)=false)=false)=false

    Evaluation sequence for :(T && T) || ( F && T )
    (T && T)=true
    (F && T)=false
    ((T && T)=true || (F && T)=false)=true

    0 讨论(0)
  • 2020-11-27 22:04

    You could do this with MVEL or JUEL. Both are expression language libraries, examples below are using MVEL.

    Example:

    System.out.println(MVEL.eval("true && ( false || ( false && true ) )"));
    

    Prints: false

    If you literally want to use 'T' and 'F' you can do this:

    Map<String, Object> context = new java.util.HashMap<String, Object>();
    context.put("T", true);
    context.put("F", false);
    System.out.println(MVEL.eval("T && ( F || ( F && T ) )", context));
    

    Prints: false

    0 讨论(0)
  • 2020-11-27 22:04

    mXparser handles Boolean operators - please find few examples

    Example 1:

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

    Result 1:

    1 && (0 || (0 && 1)) = 0.0
    

    Example 2:

    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 2:

    T && (F || (F && T)) = 0.0
    

    For more details please follow mXparser tutorial.

    Best regards

    0 讨论(0)
  • 2020-11-27 22:21

    Check out BeanShell. It has expression parsing that accepts Java-like syntax.

    EDIT: Unless you're trying to actually parse T && F literally, though you could do this in BeanShell using the literals true and false.

    0 讨论(0)
提交回复
热议问题