>
とのような演算子を=
フェイスレットのような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
式を開始するためにインターセプトを試みることができます。スクリプトに不足しているプロパティを操作に解決することで、新しいキーワードの問題を解決できます。次に、式を作成してリストに保存し、スクリプトの最後で実行できます。それは終わっていませんが、私はこれと一緒に来ました:
// 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()
失敗する前に 2 つの命令オブジェクトを構築できます。
[Instruction(12, gt, 10), Instruction(19, eq, 20)]
それだけの価値があるかどうかはわかりません。