我看到你在Scala找到了答案,但在Groovy中,虽然需要点号(或AST自动插入点号),但做命令树并不难:
更新:添加了一个floatNode
方法,其优先级基于precedence
列表。具有较高优先级的节点“浮动”向上:
class Operation {
static final precedence = ['minus', 'add', 'multiply', 'divide']
def left, right, method
Operation parent
def invokeMethod(String method, args) {
def o = new Operation(
parent: this, left: right, method: method, right: args[0])
this.floatNode(o)
}
def floatNode(Operation op) {
if (op.hasHigherPrecedenceThan(this)) {
op.parent = this.parent
this.parent = op
if (op.parent) { this.parent = op.parent.floatNode(op) }
return this
}
else {
return op
}
}
def hasHigherPrecedenceThan(Operation o) {
return precedence.indexOf(this.method) > precedence.indexOf(o.method)
}
String toString() { "Operation($left $method $right, parent=$parent)" }
}
测试:
Integer.metaClass.invokeMethod = { String method, args ->
new Operation(parent: null, method: method, left: delegate, right: args.head())
}
a = 2.add 3 multiply 4 minus 5 divide 6 add 7
println a
println
会输出:
Operation(3 minus 5,
parent=Operation(5 add 7,
parent=Operation(2 add 3,
parent=Operation(3 multiply 4,
parent=Operation(5 divide 6, parent=null)))))