Java 中的布尔表达式解析器

2022-09-02 09:23:37

是否有任何Java库或技术可以逐个解析布尔表达式?

我的意思是给出这样的表达式:

T && ( F || ( F && T ) )

它可以分解为一个表达式树,以显示哪个标记导致了“F”值,如下所示(可能是这样的):

T &&               <- rhs false
    ( F ||         <- rhs false
        ( F && T ) <- eval, false
    )

我正在尝试将布尔表达式计算传达给非程序员。我已经用Anlr四处摸索,但我无法让它做很多事情(它似乎有一点学习曲线)。

我不反对自己写,但我宁愿不重新发明轮子。


答案 1

你可以用MVELJUEL来做到这一点。两者都是表达式语言库,下面的示例使用MVEL。

例:

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

打印:假

如果你真的想使用'T'和'F',你可以这样做:

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));

打印:假


答案 2

我已经使用Javaluator对此进行了编码。
这并不完全是你正在寻找的输出,但我认为这可能是一个起点。

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 ();
  }
}

下面是输出:

的评估顺序 :T && ( F ||( F && T ) )
(F && T)=false
(F ||(F && T)=false)=false
(T && (F ||(F && T)=false)=false)=false

:(T&T)||的评估顺序( F && T )
(T && T)=true
(F && T)=false
((T && T)=true ||(F && T)=false)=true