[英]boolean expression parser in java
Are there any java libraries or techniques to parsing boolean expressions piecemeal?是否有任何 java 库或技术来解析布尔表达式?
What I mean is given an expression like this:我的意思是给出这样的表达式:
T && ( F || ( F && T ) )
It could be broken down into a expression tree to show which token caused the 'F' value, like so ( maybe something like this):它可以分解为一个表达式树,以显示哪个标记导致了 'F' 值,如下所示(可能是这样的):
T && <- rhs false
( F || <- rhs false
( F && T ) <- eval, false
)
I am trying to communicate boolean expression evaluations to non-programmers.我正在尝试将布尔表达式评估传达给非程序员。 I have poked around with Anlr, but I couldn't get it to do much (it seems to have a bit of a learning curve).
我在 Anlr 上闲逛,但我无法让它做太多事情(它似乎有一点学习曲线)。
I'm not opposed to writing it myself, but I'd rather not reinvent the wheel.我不反对自己写它,但我宁愿不重新发明轮子。
I've coded this using Javaluator . 我用Javaluator编写了这个代码 。
It's not exactly the output you are looking for, but I think it could be a start point. 它并不完全是您正在寻找的输出,但我认为它可能是一个起点。
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 ();
}
}
Here is the ouput: 这是输出:
Evaluation sequence for :T && ( F || ( F && T ) )
评估顺序为:T &&(F ||(F && T))
(F && T)=false(F && T)=假
(F || (F && T)=false)=false(F ||(F && T)= false)= false
(T && (F || (F && T)=false)=false)=false(T &&(F ||(F && T)= false)= false)= false
Evaluation sequence for :(T && T) ||
评估顺序为:(T && T)|| ( F && T )
(F && T)
(T && T)=true(T && T)=真
(F && T)=false(F && T)=假
((T && T)=true || (F && T)=false)=true((T && T)= true ||(F && T)= false)=真
You could do this with MVEL or JUEL . 你可以用MVEL或JUEL做到这一点 。 Both are expression language libraries, examples below are using MVEL.
两者都是表达式语言库,下面的示例使用MVEL。
Example: 例:
System.out.println(MVEL.eval("true && ( false || ( false && true ) )"));
Prints: false 打印:错误
If you literally want to use 'T' and 'F' you can do this: 如果您真的想要使用'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));
Prints: false 打印:错误
I recently put together a library in Java specifically to manipulate boolean expressions: jbool_expressions . 我最近专门用Java 编写了一个库来操作布尔表达式: jbool_expressions 。
It includes a tool too parse expressions out of string input: 它包含一个工具,也解析了字符串输入中的表达式:
Expression<String> expr = ExprParser.parse("( ( (! C) | C) & A & B)")
You can also do some fairly simple simplification: 您还可以进行一些相当简单的简化:
Expression<String> simplified = RuleSet.simplify(expr);
System.out.println(expr);
gives 给
(A & B)
If you wanted to step through the assignment then, you could assign values one by one. 如果您想逐步完成任务,可以逐个分配值。 For the example here,
对于这里的例子,
Expression<String> halfAssigned = RuleSet.assign(simplified, Collections.singletonMap("A", true));
System.out.println(halfAssigned);
shows 节目
B
and you could resolve it by assigning B. 你可以通过分配B.来解决它。
Expression<String> resolved = RuleSet.assign(halfAssigned, Collections.singletonMap("B", true));
System.out.println(resolved);
shows 节目
true
Not 100% what you were asking for, but hope it helps. 不是100%你所要求的,但希望它有所帮助。
Check out BeanShell . 查看BeanShell 。 It has expression parsing that accepts Java-like syntax.
它具有接受类似Java语法的表达式解析。
EDIT: Unless you're trying to actually parse T && F
literally, though you could do this in BeanShell using the literals true
and false
. 编辑:除非你试图实际解析
T && F
字面意思,尽管你可以使用文字true
和false
在BeanShell中执行此操作。
mXparser handles Boolean operators - please find few examples mXparser处理布尔运算符 - 请找几个例子
Example 1: 例1:
import org.mariuszgromada.math.mxparser.*;
...
...
Expression e = new Expression("1 && (0 || (0 && 1))");
System.out.println(e.getExpressionString() + " = " + e.calculate());
Result 1: 结果1:
1 && (0 || (0 && 1)) = 0.0
Example 2: 例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());
Result 2: 结果2:
T && (F || (F && T)) = 0.0
For more details please follow mXparser tutorial . 有关更多详细信息,请参阅mXparser教程 。
Best regards 最好的祝福
Try this.尝试这个。
static boolean parseBooleanExpression(String s) {
return new Object() {
int length = s.length(), index = 0;
boolean match(String expect) {
while (index < length && Character.isWhitespace(s.charAt(index)))
++index;
if (index >= length)
return false;
if (s.startsWith(expect, index)) {
index += expect.length();
return true;
}
return false;
}
boolean element() {
if (match("T"))
return true;
else if (match("F"))
return false;
else if (match("(")) {
boolean result = expression();
if (!match(")"))
throw new RuntimeException("')' expected");
return result;
} else
throw new RuntimeException("unknown token");
}
boolean term() {
if (match("!"))
return !element();
else
return element();
}
boolean factor() {
boolean result = term();
while (match("&&"))
result &= term();
return result;
}
boolean expression() {
boolean result = factor();
while (match("||"))
result |= factor();
return result;
}
boolean parse() {
boolean result = expression();
if (index < length)
throw new RuntimeException(
"extra string '" + s.substring(index) + "'");
return result;
}
}.parse();
}
And和
public static void main(String[] args) {
String s = "T && ( F || ( F && T ) )";
boolean result = parseBooleanExpression(s);
System.out.println(result);
}
output:输出:
false
The syntax is语法是
expression = factor { "||" factor }
factor = term { "&&" term }
term = [ "!" ] element
element = "T" | "F" | "(" expression ")"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.