我有一个python库,可以从nested function calls构建特殊的迭代器(行为树)。虽然API具有相当好的轻量级语法(由于它是python),但它确实可以使用声明性的DSL。
这是我正在想象的草图:
DSL(使用YAML):
tree:
- sequence:
- do_action1
- do_action2
- select:
- do_action3
- sequence:
- do_action4
- do_action5
- do_action6
将导致以下嵌套函数调用:
visit(
sequence(
do_action1(),
do_action2(),
select(
do_action3(),
sequence(
do_action4(),
do_action5(),
),
do_action6(),
)
)
)
我无法直观地看到如何做到这一点。因为DSL必须代表树,所以简单的深度优先遍历似乎是合适的。但是为了构建嵌套函数调用,我必须以某种方式将其内部转换出来。它可能涉及一些聪明的中间堆栈或某些东西,但我不能完全掌握它。执行此转换的正确方法是什么?
答案 0 :(得分:3)
我认为你可以让python跟踪函数调用和参数,而不是自己使用堆栈。
假设您有一个YAML分析树,其中每个节点代表一个函数调用,并且该节点的每个子节点都是一个参数(它也是一个函数调用,因此它可能有自己的参数)。
然后定义函数evaluate
,它评估此树的节点,如下所示(伪代码):
def evaluate(node):
# evaluate parameters of the call
params = []
for child in node:
params.append(evaluate(child))
# now make the call to whatever function this node represents,
# passing the parameters
return node.function.call(*params)
最后,调用evaluate
传递YAML树的根作为参数,你应该得到所需的行为。
略微不同的eval-apply结构
def evaluate(node):
# evaluate parameters of the call
params = [ evaluate(child) for child in node ]
# apply whatever function this node represents
return node.function.call(*params)