4

我有一个 python 库,它从嵌套函数调用中构建特殊的迭代器(行为树)。虽然 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 必须表示一棵树,所以简单的深度优先遍历似乎是合适的。但是为了构建嵌套的函数调用,我必须以某种方式将其翻过来。它可能涉及一些巧妙的中间堆栈或类似的东西,但我不能完全掌握它。执行此转换的正确方法是什么?

4

1 回答 1

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 树的根作为参数传递,您应该会获得所需的行为。


略有不同的评估应用结构

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)
于 2011-09-08T23:04:23.237 回答