【问题标题】:Looking for an expression evaluator寻找表达式评估器
【发布时间】:2010-10-24 21:59:00
【问题描述】:

我正在寻找简单条件表达式的求值器。 表达式应包括变量(只读)、字符串、数字和一些基本运算符。

例如类似这样的表达方式:

${a} == "Peter" && ( ${b} == null || ${c} > 10 )

到目前为止,我实现了一个相当“神奇”的解析器,它返回一个我可以评估的 AST,但我不敢相信我是第一个解决这个问题的人。

我可以使用哪些现有代码?

【问题讨论】:

  • 您希望评估哪种语言/语法?是你编出来的吗? Java 与此有什么关系?
  • 我猜 OP 想要在 JVM 上运行的东西。
  • 我们在一个项目中使用了 JEP (singularsys.com/jep),但我真的很想要一个小的、适应性强的等价物,出于性能原因,它实际上可以为函数生成字节码。出于这个原因,我们放弃了 JEP,最终手工编码了大量的 Java 类。也许拥有 ANTLR 和 BCEL 的进取精神可以做到这一点?
  • @Matt Ball:这个例子是我现在正在使用的一个虚构的语法。但是当我找到一个满足我要求的解析器​​时,我可以使用它接受的任何语法。我在语法方面的主要目标是使其尽可能简约,因为我们可能在一个集合中拥有许多(最多 200 个)这些微小的条件。因此,可读性和性能是一个问题。

标签: java


【解决方案1】:

你看过MVEL吗?他们提供了getting started guideperformance analysis

这是他们的一个简单示例:

// The compiled expression is serializable and can be cached for re-use.
CompiledExpression compiled = MVEL.compileExpression("x * y"); 

Map vars = new HashMap();
vars.put("x", new Integer(5));
vars.put("y", new Integer(10));

// Executes the compiled expression
Integer result = (Integer) MVEL.executeExpression(compiled, vars); 
assert result.intValue() == 50; 

另外(回答我自己的问题)MVEL 似乎为bytecode generation 提供了一些支持。

其他选择,从上述答案和我自己的答案中挑选出来:

【讨论】:

【解决方案2】:

听起来像JEXL 可能对你很有效。查看它的syntax reference.

【讨论】:

    【解决方案3】:

    【讨论】:

    • 现在为时已晚,但这看起来正是我想要的。它专注于评估,但您有一个返回表达式结构的 getAST 方法。
    【解决方案4】:

    为什么不使用 Rhino?它是 JDK 中已经存在的 JavaScript 引擎。

    它可以评估任何你喜欢用 JS 写的东西。看看here

    【讨论】:

    • 事实上,我们已经将 Rhino 用于更大的自定义脚本。但我不想让这些小表达式拥有脚本语言的全部力量。
    【解决方案5】:

    这个简单的recursive descent parser 将常量计算为没有参数的命名函数。

    【讨论】:

    • 当我用科学代替魔法时,我会走那条路。但现在我正在寻找一个现有的解决方案。
    【解决方案6】:

    一个非常简单易用的alternative,具有许多用于字符串、日期和数字格式的内置 Excel 函数。

    该库还允许轻松添加自定义函数。 git 页面上有很多示例。一个使用变量的简单示例

      ExpressionsEvaluator evalExpr = ExpressionsFactory.create("LEFT(City, 3)");
      Map<String, Object> variables = new HashMap<String, Object>();
      variables.put("City", "New York");
      assertEquals("New", evalExpr.eval(variables));
    

    【讨论】:

    • 对于开箱即用的解决方案来说,这看起来很有希望。但我最终选择了 Antlr 并建立了自己的表达语言。
    【解决方案7】:

    Here 是我开发的一个支持表达式求值(包括变量、字符串、布尔值等)的小库。

    一个小例子:

    String expression = "EXP(var)";
    ExpressionEvaluator evaluator = new ExpressionEvaluator();
    evaluator.putVariable(new Variable("var", VariableType.NUMBER, new BigDecimal(20)));
    
    System.out.println("Value of exp(var) : " + evaluator.evaluate(expression).getValue());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多