将'和'绑定到&&

时间:2014-12-06 04:54:02

标签: groovy

我正在尝试构建一个将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"绑定到&&运算符?

1 个答案:

答案 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声明的变量: