35

同僚から、AST をナビゲートするためのビジター パターンを作成するよう提案されました。どうすればそれを書き始めることができるか、誰か教えてもらえますか?

私が理解している限りでは、AST の各ノードには、visit()何らかの形で (どこから?) 呼び出されるメソッド (?) があります。以上で私の理解は終わりです。

すべてを単純化するために、ノードRootExpressionNumberOpあり、ツリーが次のようになっているとします。

       Root
        |
       Op(+)
      /   \
     /     \
 Number(5)  \
             Op(*)
             /   \
            /     \
           /       \
       Number(2)   Number(444)

訪問者パターンがこのツリーにアクセスして出力を生成する方法を考えられる人はいますか?

 5 + 2 * 444

ありがとう、ボダ・シド。

4

3 に答える 3

18

ウィキペディアには、ビジター パターンがどのように機能するかについての優れた概要がありますが、ウィキペディアが使用するサンプル実装は Java です。しかし、それを Python に簡単に移植できますよね?

基本的に、二重ディスパッチのメカニズムを実装する必要があります。AST の各ノードは、accept()メソッド (メソッドではないvisit()) を実装する必要があります。このメソッドは、引数として訪問者オブジェクトを取ります。このaccept()メソッドの実装では、ビジター オブジェクトのメソッドを呼び出しvisit()ます (AST ノード タイプごとに 1 つ存在します。Java ではパラメーターのオーバーロードを使用し、Python ではさまざまvisit_*()なメソッドを使用できると思います)。正しい訪問者は、正しい Node タイプを引数としてディスパッチされます。

于 2010-03-26T20:09:28.120 に答える
15

のドキュメントを参照してくださいast.NodeVisitor。たとえば、大まかな可能性は次のとおりです。

import ast

class MyVisitor(ast.NodeVisitor):
  def visit_BinaryOp(self, node):
    self.visit(node.left)
    print node.op,
    self.visit(node.right)
  def visit_Num(self, node):
    print node.n,

もちろん、これは必要な場所などでも括弧を発行しないため、実際にはさらに多くの作業が行われますが、それは始まりです;-)。

于 2010-03-26T18:32:54.440 に答える