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 ツリーのルートをパラメーターとして渡して呼び出すと、目的の動作が得られるはずです。


少し異なる 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)
于 2011-09-08T23:04:23.237 に答える