2012-08-30 13 views
15

Gibt es Java-Bibliotheken oder Techniken zu Booleschen Ausdrücken stückchenweise Parsen?boolean Ausdruck Parser in Java

Was ich meine, ist ein Ausdruck wie folgt gegeben:

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

Es in einen Ausdrucksbaum abgebaut werden könnten, um anzuzeigen, welche die ‚F‘ Wert verursacht Token, wie so (vielleicht etwas wie dieses):

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

Ich versuche, boolesche Ausdruckauswertungen zu Nichtprogrammierern zu kommunizieren. Ich habe mit Anlr herumgestochert, aber ich konnte es nicht dazu bringen, viel zu tun (es scheint ein bisschen eine Lernkurve zu haben).

Ich bin nicht zu schreiben, es selbst gegenüber, aber ich möchte lieber nicht das Rad neu erfinden.

Antwort

11

Ich habe dies mit Javaluator codiert.
Es ist nicht gerade die Ausgabe die Sie suchen, aber ich denke, es ist ein Startpunkt sein könnte.Hier

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

ist die ouput:

Evaluierungssequenz für: T & & (F || (F & & T))
(F & & T) = false
(F || (F & & T) = falsch) = falsch
(T & & (F || (F & & T) = false) = false) = false

Evaluierungssequenz für: (T & & T) || (F & & T)
(T & & T) = true
(F & & T) = false
((T & & T) = true || (F & & T) = false) = true

+0

Cool, werde ich es versuchen bald heraus, und akzeptieren, wenn es ist, was ich zu tun versuche. +1 – javamonkey79

+0

Ich habe ein paar Fehler behoben, aber insgesamt ist die Idee da. Vielen Dank! – javamonkey79

10

Sie können dies tun, mit MVEL oder JUEL. Beide sind Ausdrucksprachenbibliotheken, Beispiele unten verwenden MVEL.

Beispiel:

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

Drucke: falsch

Wenn Sie buchstäblich verwenden möchten 'T' und 'F', dies zu tun:

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

Drucke: falsch

1

prüfen BeanShell aus. Es hat Ausdruckanalyse, die Java-ähnliche Syntax akzeptiert.

EDIT: Es sei denn, Sie versuchen, tatsächlich T && F wahrsten Sinne des Wortes zu analysieren, wenn Sie dies in Beanshell tun könnte die Literale true und false verwenden.

3

Ich habe vor kurzem eine Bibliothek in Java speziell zur Manipulation boolescher Ausdrücke zusammengestellt: jbool_expressions.

Es enthält auch ein Tool Ausdrücke aus String-Eingang zu analysieren:

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

Sie auch einige ziemlich einfache Vereinfachung tun können:

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

gibt

(A & B) 

Wenn Sie wollten Um die Zuordnung zu durchlaufen, können Sie die Werte nacheinander zuweisen. Für das Beispiel hier

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

zeigt

B 

und man konnte es lösen, indem B. die Zuordnung

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

zeigt

true 

Nicht 100%, was Sie waren verlangen, aber hoffe es hilft.

+0

liebe deine Bibliothek - danke! –

0

mXparser Griffe Booleschen Operatoren - bitte einige Beispiele

Beispiel 1 finden:

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 

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

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

Für weitere Details folgen Sie bitte mXparser tutorial.

Mit freundlichen Grüßen