在Groovy表达式中使用文字操作符(例如“和”,“或”)? [英] Use literal operators (eg "and", "or") in Groovy expressions?

查看:809
本文介绍了在Groovy表达式中使用文字操作符(例如“和”,“或”)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前的工作项目允许用户提供的表达式在特定的上下文中进行评估,作为扩展和影响工作流程的一种方式。这些表达式通常是逻辑的。为了让它对非程序员来说可口,我想给他们选择使用文字操作符(例如和,或者,而不是&,|,!!)。

一个简单的搜索&替换是不够的,因为数据可能包含引号内的单词并构建解析器,而可行,可能不是最优雅和有效的解决方案。



为了明确问题:Groovy中有没有一种方法可以让用户编写

  x> 10和y = 20或者不是z 

,但Groovy将它评估为:

  x> 10&& y == 20 || !z 

谢谢。

解决方案

最近版本的Groovy支持命令链,所以确实可以这样写:

  compute x> 10和y == 20或不是(z)

这里的compute一词是任意的,但它不能被省略,因为它是命令链中的第一个动词。接下来的所有动词和名词之间的交替:

  compute x> 10和y == 20或者不是(z)
─────────┬────┬────┬────┬───────
动词名词动词名词动词名词

一条命令链如下编译:

  verb(名词).verb(名词).verb(名词)... 

$ b

所以上面的例子被编译为:

  compute(x> ; 10).and(y == 20)。或(not(z))

许多方法来实现这一点。这里只是一个快速&肮脏的概念证明,它不会实现运算符的优先级等等:

  class Compute {
private value
Compute(boolean v){value = v}
def或(boolean w){value = value ||瓦; this}
def和(boolean w){value = value&&瓦; this}
String toString(){value}
}

def compute(v){new Compute(v)}
def not(boolean v){! v}

您可以单独使用命令链(作为顶级语句) (局部变量或属性赋值),但不在其他表达式中。


My current work project allows user-provided expressions to be evaluated in specific contexts, as a way for them to extend and influence the workflow. These expressions the usual logical ones f. To make it a bit palatable for non-programmers, I'd like to give them the option of using literal operators (e.g. and, or, not instead of &, |, !).

A simple search & replace is not sufficient, as the data might contains those words within quotes and building a parser, while doable, may not be the most elegant and efficient solution.

To make the question clear: is there a way in Groovy to allow the users to write

x > 10 and y = 20 or not z 

but have Groovy evaluate it as if it were:

x > 10 && y == 20 || !z

Thank you.

解决方案

Recent versions of Groovy support Command chains, so it's indeed possible to write this:

compute x > 10 and y == 20 or not(z)

The word "compute" here is arbitrary, but it cannot be omitted, because it's the first "verb" in the command chain. Everything that follows alternates between verb and noun:

 compute  x > 10  and  y == 20  or   not(z)
 ───┬───  ──┬───  ─┬─  ───┬───  ─┬─  ──┬───
   verb    noun   verb   noun   verb  noun

A command chain is compiled like this:

verb(noun).verb(noun).verb(noun)...

so the example above is compiled to:

compute(x > 10).and(y == 20).or(not(z))

There are many ways to implement this. Here is just a quick & dirty proof of concept, that doesn't implement operator precedence, among other things:

class Compute {
    private value
    Compute(boolean v) { value = v }
    def or (boolean w) { value = value || w; this }
    def and(boolean w) { value = value && w; this }
    String  toString() { value }
}

def compute(v) { new Compute(v) }
def not(boolean v) { !v }

You can use command chains by themselves (as top-level statements) or to the right-hand side of an assignment operator (local variable or property assignment), but not inside other expressions.

这篇关于在Groovy表达式中使用文字操作符(例如“和”,“或”)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆