analizador de expresiones booleanas en java

¿Existen bibliotecas o técnicas de java para analizar expresiones booleanas por partes?

Lo que quiero decir tiene una expresión como esta:

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

Se puede dividir en un árbol de expresiones para mostrar qué token causó el valor ‘F’, como tal ( tal vez algo como esto):

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

Estoy tratando de comunicar evaluaciones de expresiones booleanas a no progtwigdores. He hurgado con Anlr, pero no pude hacer que hiciera mucho (parece tener una curva de aprendizaje).

No me opongo a escribirlo, pero prefiero no reinventar la rueda.

He codificado esto usando Javaluator .
No es exactamente el resultado que está buscando, pero creo que podría ser un punto de partida.

 package test; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import net.astesana.javaluator.*; public class TreeBooleanEvaluator extends AbstractEvaluator { /** 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 operands, Object evaluationContext) { List tree = (List) 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 sequence = new ArrayList(); evaluator.evaluate(expression, sequence); System.out.println ("Evaluation sequence for :"+expression); for (String string : sequence) { System.out.println (string); } System.out.println (); } } 

Aquí está la salida:

Secuencia de evaluación para: T && (F || (F && T))
(F && T) = falso
(F || (F && T) = falso) = falso
(T && (F || (F && T) = falso) = falso) = falso

Secuencia de evaluación para: (T && T) || (F && T)
(T && T) = verdadero
(F && T) = falso
((T && T) = verdadero || (F && T) = falso) = verdadero

Puedes hacer esto con MVEL o JUEL . Ambas son bibliotecas de lenguaje de expresión, los ejemplos a continuación usan MVEL.

Ejemplo:

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

Impresiones: falso

Si, literalmente, quiere usar ‘T’ y ‘F’, puede hacer esto:

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

Impresiones: falso

Recientemente armé una biblioteca en Java específicamente para manipular expresiones booleanas: jbool_expressions .

Incluye una herramienta que también analiza expresiones fuera de la entrada de cadena:

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

También puedes hacer una simplificación bastante simple:

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

da

 (A & B) 

Si quería pasar por la tarea, podría asignar valores uno por uno. Para el ejemplo aquí,

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

muestra

 B 

y podrías resolverlo asignando B.

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

muestra

 true 

No es el 100% de lo que estaba pidiendo, pero espero que ayude.

Echa un vistazo a BeanShell . Tiene un análisis de expresiones que acepta la syntax similar a Java.

EDITAR: A menos que intente analizar realmente T && F literalmente, aunque podría hacerlo en BeanShell utilizando los literales true y false .

mXparser maneja operadores Booleanos – encuentre algunos ejemplos

Ejemplo 1:

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

Resultado 1:

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

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

Resultado 2:

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

Para más detalles, siga el tutorial de mXparser .

Atentamente

    Intereting Posts