我正在尝试构建一个将and
绑定到&&
的Groovy DSL:
def binding = new Binding([
and: &&
])
def shell = new GroovyShell(binding)
println shell.evaluate '''
true and false
'''
}
但是我遇到了编译时错误:
>groovyc AndOr.groovy
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
AndOr.groovy: 2: unexpected token: && @ line 2, column 7.
and: &&
^
1 error
如何将"and"
绑定到&&
运算符?
答案 0 :(得分:0)
Groovy将left operand right
解析为left(operand).getRight()
。将and
转换为&&
运算符与解析器相关,我怀疑如果不调整groovy源代码,antlr等,您将能够执行此操作。
为了让您的代码段有效,此代码会使用元编程拦截Boolean::call
,从而创建一个新的EBoolean
对象。然后,它使用getProperty
方法拦截getRight()
部分:
import org.codehaus.groovy.control.CompilerConfiguration
class EBoolean {
Boolean left
Op op
def getProperty(String property) {
def right = Boolean.parseBoolean(property)
op == Op.AND ? left && right : null
}
}
class Meta {
{
Boolean.metaClass.call { Op op ->
new EBoolean(left: delegate, op: op)
}
}
}
enum Op { AND }
binding = new Binding([ and: Op.AND ])
def compilerConfig = new CompilerConfiguration( scriptBaseClass: DelegatingScript.class.name)
def shell = new GroovyShell(this.class.classLoader, binding, compilerConfig)
script = shell.parse( '''
true and false
''' )
script.setDelegate new Meta()
assert script.run() == false
它有效,但它非常具体,一般难以使用。如果您想从上下文中获取另一个变量名称(例如a=false; true and a
),它将无法工作。绑定没有多大帮助,因为它不适用于脚本中用def
声明的变量: