运行时的动态表达式计算器

时间:2018-06-18 10:42:45

标签: java algorithm groovy

我有一个应用程序,我想使用某种表达式评估程序自定义。 我想在不重新编译代码的情况下更改应用程序的某些部分。 我正在考虑使用groovy表达。

比如说,我有一个可以通过提供表达式启用/禁用的功能:

在这种情况下,将启用此功能

Example 1:
EXPRESSION : status = part-time || status = hourly
INPUT: status = part-time

在这种情况下,此功能将被禁用

Example 2:
EXPRESSION : status = part-time || status = hourly
INPUT: status = permanent

用户需要输入表达式和输入。表达式应该计算为布尔表达式

他们也可以改变表达式,程序会通过一些评估来获取它。 顺便说一下,这些表达式都记录在案,并由我向我的应用程序的用户公开

Example 3:
EXPRESSION : salary > 10000
INPUT: salary = 7000

我之前看过一个程序,他们说他们在引擎盖下使用groovy。 但我无法理解这个概念。

有人可以给我一个想法吗?

2 个答案:

答案 0 :(得分:1)

通常的groovy脚本调用:

import groovy.lang.Binding;
import groovy.lang.Script;
import groovy.lang.GroovyShell;

Binding binding = new Binding();
binding.setProperty("status", "part-time");
GroovyShell shell = new GroovyShell(binding);
Script script = shell.parse(" status == 'part-time' || status == 'hourly' ");
Object result = script.run();

运行后,绑定将填充新的变量值。

您可以缓存已解析的脚本(或已解析脚本的类),因为解析/编译是一个昂贵的过程。

作为替代 - 最简单的脚本评估:

Object result = groovy.util.Eval.me("status", "part-time", 
    " status == 'part-time' || status == 'hourly' ");

答案 1 :(得分:1)

使用evaluate的替代方法。您的变量在绑定中定义,evaluate包含表达式:

// setup binding
def emp = [status:'permanent', name:'Hugo']
def binding = new Binding()
binding.status = 'permanent'
binding.status2 = 'part-time'
binding.salary = 7000
binding.employee = emp
println binding.variables

// evaluate the script
def ret = new GroovyShell(binding).evaluate("status == 'part-time' || status == 'hourly'")
println ret

ret = new GroovyShell(binding).evaluate("status2 == 'part-time' || status2 == 'hourly'")
println ret

ret = new GroovyShell(binding).evaluate("salary > 10000")
println ret

ret = new GroovyShell(binding).evaluate("employee.status == 'permanent' || employee.status == 'hourly'")
println ret

返回

[status:permanent, status2:part-time, salary:7000, employee:[status:permanent, name:Hugo]]
false
true
false
true