2012-08-30 19 views
15

ブール式を断片的に解析するJavaライブラリやテクニックはありますか?私は何を意味Javaのブール式パーサ

は次のように表現を与えられます。

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

がそうかもしれない(のように、「F」値を引き起こしたトークンどの示すために、式ツリーに分けることができこのようなもの):

私はブール式の評価評価を非プログラマに伝えようとしています。私はAnlrと一緒に突き刺しましたが、それほど多くすることはできませんでした(少し習熟しているようです)。

私はそれを自分で書くのに反対ではありませんが、私はむしろホイールを再発明しません。

答えて

11

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

はouputをある:

評価シーケンスのために:T & &(F ||(F & & T))
(F & & T)が偽
(Fを= ||(F & & T)=偽)=偽
(T &(F || (F & & T))が偽= FALSE =)のために偽

評価シーケンスを=(T & & T)|| (F & & T)
(T & & T)が真
(F & & T)が偽
を= =((T & & T)= TRUE ||(F & & T)が偽=)真=

+0

クールで、私はすぐに試してみて、私がしようとしていることを受け入れるでしょう。 +1 – javamonkey79

+0

私はいくつかのバグを修正しましたが、全体的な考え方はそこにあります。ありがとう! – javamonkey79

10

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

例:

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

プリント:

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

プリント: 偽 偽

あなたは文字通り 'T' を使用したいと 'F' の場合、あなたはこれを行うことができます

1

チェックアウトBeanShellこれは、Javaのような構文を受け入れる式解析を持っています。

EDIT:あなたはリテラルtruefalseを使用してBeanShellの中でこれを行うことができても、実際に、文字通りT && Fを解析しようとしている場合を除き。

3

私は最近、ブール式を操作するために、具体的には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%を示し頼むが、助けてくれることを願う。

+0

あなたのライブラリが大好きです - ありがとう! –

0

mXparserは、ブール演算子を処理します - いくつかの例を見つけてください

例1:

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

結果1:

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

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

RES超2:

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

詳細はmXparser tutorialを参照してください。

お礼