20

ブール式を断片的に解析するJavaライブラリまたはテクニックはありますか?

私が言いたいのは、次のような表現です。

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

式ツリーに分解して、「F」値の原因となったトークンを示すことができます (次のようなものかもしれません)。

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

ブール式の評価を非プログラマーに伝えようとしています。私は Anlr をいじり回しましたが、多くのことを行うことができませんでした (学習曲線が少しあるようです)。

私はそれを自分で書くことに反対しているわけではありませんが、車輪の再発明はしたくありません。

4

6 に答える 6

13

これは、 MVELまたはJUELを使用して行うことができます。どちらも式言語ライブラリです。以下の例ではMVELを使用しています。

例:

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

プリント:false

文字通り「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));

プリント:false

于 2012-08-30T18:17:27.193 に答える
12

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)=偽)=偽)=偽

:(T && T) || の評価シーケンス ( F && T )
(T && T)=true
(F && T)=false
((T && T)=true || (F && T)=false)=true

于 2012-08-31T23:16:26.247 に答える
10

私は最近、特にブール式を操作するために Java でライブラリをまとめました: jbool_expressions

文字列入力から式を解析するツールも含まれています。

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

かなり単純化することもできます。

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

与える

(A & B)

割り当てをステップ実行したい場合は、値を 1 つずつ割り当てることができます。ここの例では、

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

ショー

B

Bを割り当てることで解決できます。

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

ショー

true

あなたが求めていたものは 100% ではありませんが、お役に立てば幸いです。

于 2013-04-10T07:28:05.970 に答える
1

BeanShellをチェックしてください。Java のような構文を受け入れる式の解析があります。

編集:実際に文字どおりに解析しようとしている場合を除きますが、BeanShell でリテラルとT && Fを使用してこれを行うことができます。truefalse

于 2012-08-30T18:20:05.193 に答える