如果您可以分别将操作符和操作符换成facelets -like>
和,我认为您的情况可能是可行的,尽管这需要付出很多努力:=
gt
eq
x gt 10 and y eq 20 or not z
决议:
x(gt).10(and).y(eq).20(or).not(z)
这将是地狱解析。
@Brian Henry 建议的方式是最简单的方式,虽然不是用户友好的,因为它需要括号和圆点。
好吧,考虑到我们可以交换运算符,您可以尝试拦截Integer.call
to start 表达式。将脚本中缺少的属性解析为操作可以解决您的新关键字问题。然后您可以构建表达式并将它们保存到列表中,在脚本末尾执行它们。它还没有完成,但我伴随着这个:
// the operators that can be used in the script
enum Operation { eq, and, gt, not }
// every unresolved variable here will try to be resolved as an Operation
def propertyMissing(String property) { Operation.find { it.name() == property} }
// a class to contain what should be executed in the end of the script
@groovy.transform.ToString
class Instruction { def left; Operation operation; def right }
// a class to handle the next allowed tokens
class Expression {
Closure handler; Instruction instruction
def methodMissing(String method, args) {
println "method=$method, args=$args"
handler method, args
}
}
// a list to contain the instructions that will need to be parsed
def instructions = []
// the start of the whole mess: an integer will get this called
Integer.metaClass {
call = { Operation op ->
instruction = new Instruction(operation: op, left: delegate)
instructions << instruction
new Expression(
instruction: instruction,
handler:{ String method, args ->
instruction.right = method.toInteger()
println instructions
this
})
}
}
x = 12
y = 19
z = false
x gt 10 and y eq 20 or not z
由于部分未实现,这将给出异常,not()
但它可以在失败之前构建两个指令对象:
[Instruction(12, gt, 10), Instruction(19, eq, 20)]
不确定是否值得。