33. Python コンパイラパッケージ
*******************************

バージョン 2.6 で非推奨: "compiler" モジュールは Python 3 で削除されま
した。

Python コンパイラパッケージは Python のソースコードを分析したり Python
バイトコードを生成するためのツールです。compiler は Python のソースコ
ードから抽象的な構文木を生成し、その構文木から Python バイトコード
(*bytecode*) を生成するライブラリをそなえています。

"compiler" パッケージは、Python で書かれた Python ソースコードからバイ
トコードへの変換プログラムです。これは組み込みの構文解析器と標準ライブ
ラリの "parser" モジュールを使って、具象構文木を生成します。この構文木
から抽象構文木 AST (Abstract Syntax Tree) が生成され、その後 Python バ
イトコードが得られます。

このパッケージの機能は、Python インタプリタに内蔵されている組み込みの
コンパイラがすべて含んでいるものです。これはその機能と正確に同じものに
なるよう意図してつくられています。なぜ同じことをするコンパイラをもうひ
とつ作る必要があるのでしょうか? このパッケージはいろいろな目的に使うこ
とができるからです。これは組み込みのコンパイラよりも簡単に変更できます
し、これが生成する AST は Python ソースコードを解析するのに有用です。

この章では "compiler" パッケージのいろいろなコンポーネントがどのように
動作するのかを説明します。そのため説明はリファレンスマニュアル的なもの
と、チュートリアル的な要素がまざったものになっています。


33.1. 基本的なインターフェイス
==============================

このパッケージのトップレベルでは 4 つの関数が定義されています。
"compiler" モジュールを import すると、これらの関数およびこのパッケー
ジに含まれている一連のモジュールが使用可能になります。

compiler.parse(buf)

   *buf* 中の Python ソースコードから得られた抽象構文木 AST を返します
   。ソースコード中にエラーがある場合、この関数は "SyntaxError" を発生
   させます。返り値は "compiler.ast.Module" インスタンスであり、この中
   に構文木が格納されています。

compiler.parseFile(path)

   *path* で指定されたファイル中の Python ソースコードから得られた抽象
   構文木 AST を返します。これは "parse(open(path).read())" と等価な働
   きをします。

compiler.walk(ast, visitor[, verbose])

   *ast* に格納された抽象構文木の各ノードを先行順序 (pre-order) でたど
   っていきます。各ノードごとに *visitor* インスタンスの該当するメソッ
   ドが呼ばれます。

compiler.compile(source, filename, mode, flags=None, dont_inherit=None)

   文字列 *source* 、Python モジュール、文あるいは式を "exec" 文あるい
   は "eval()" 関数で実行可能なバイトコードオブジェクトにコンパイルし
   ます。この関数は組み込みの "compile()" 関数を置き換えるものです。

   *filename* は実行時のエラーメッセージに使用されます。

   *mode* は、モジュールをコンパイルする場合は 'exec'、 (対話的に実行
   される) 単一の文をコンパイルする場合は 'single'、式をコンパイルする
   場合には 'eval' を渡します。

   引数 *flags* および *dont_inherit* は将来的に使用される文に影響しま
   すが、いまのところはサポートされていません。

compiler.compileFile(source)

   ファイル *source* をコンパイルし、 ".pyc" ファイルを生成します。

"compiler" パッケージは以下のモジュールを含んでいます: "ast",
"consts", "future", "misc", "pyassem", "pycodegen", "symbols",
"transformer", そして "visitor" 。


33.2. 制限
==========

compiler パッケージにはエラーチェックにいくつか問題が存在します。構文
エラーはインタープリタの 2 つの別々のフェーズによって認識されます。ひ
とつはインタープリタのパーザによって認識されるもので、もうひとつはコン
パイラによって認識されるものです。 compiler パッケージはインタープリタ
のパーザに依存しているので、最初の段階のエラーチェックは労せずして実現
できています。しかしその次の段階は、実装されてはいますが、その実装は不
完全です。たとえば compiler パッケージは引数に同じ名前が 2 度以上出て
きていてもエラーを出しません: "def f(x, x): ..."

compiler の将来のバージョンでは、これらの問題は修正される予定です。


33.3. Python 抽象構文
=====================

"compiler.ast" モジュールは Python の抽象構文木 AST を定義します。 AST
では各ノードがそれぞれの構文要素をあらわします。木の根は "Module" オブ
ジェクトです。

抽象構文木 AST オブジェクトは、パーズされた Python ソースコードに対す
る高水準のインターフェイスを提供します。 Python インタプリタにおける
"parser" モジュールとコンパイラは C で書かれおり、具象構文木を使ってい
ます。具象構文木は Python のパーザ中で使われている構文と密接に関連して
います。ひとつの要素に単一のノードを割り当てる代わりに、ここでは
Python の優先順位に従って、何層にもわたるネストしたノードがしばしば使
われています。

抽象構文木 AST は、 "compiler.transformer" (変換器) モジュールによって
生成されます。 transformer は組み込みの Python パーザに依存しており、
これを使って具象構文木をまず生成します。つぎにそこから抽象構文木 AST
を生成します。

"transformer" モジュールは、実験的な Python-to-C コンパイラ用に Greg
Stein と Bill Tutt によって作られました。現行のバージョンではいくつも
の修正と改良がなされていますが、抽象構文木 AST と transformer の基本的
な構造は Stein と Tutt によるものです。


33.3.1. AST ノード
------------------

"compiler.ast" モジュールは、各ノードのタイプとその要素を記述したテキ
ストファイルからつくられます。各ノードのタイプはクラスとして表現され、
そのクラスは抽象基底クラス "compiler.ast.Node" を継承し子ノードの名前
属性を定義しています。

class compiler.ast.Node

   "Node" インスタンスはパーザジェネレータによって自動的に作成されます
   。ある特定の "Node" インスタンスに対する推奨されるインターフェイス
   とは、子ノードにアクセスするために public な属性を使うことです。
   public な属性は単一のノード、あるいは一連のノードのシーケンスに束縛
   されているかもしれませんが、これは "Node" のタイプによって違います
   。たとえば "Class" ノードの "bases" 属性は基底クラスのノードのリス
   トに束縛されており、 "doc" 属性は単一のノードのみに束縛されている、
   といった具合です。

   各 "Node" インスタンスは "lineno" 属性をもっており、これは "None"
   かもしれません。 XXX どういったノードが使用可能な lineno をもってい
   るかの規則は定かではない。

   全ての "Node" オブジェクトは以下のメソッドを提供します:

   getChildren()

      子ノードと子オブジェクトを、これらが出てきた順で、平らなリスト形
      式にして返します。とくにノードの順序は、 Python 文法中に現れるも
      のと同じになっています。すべての子が "Node" インスタンスなわけで
      はありません。たとえば関数名やクラス名といったものは、ただの文字
      列として表されます。

   getChildNodes()

      子ノードをこれらが出てきた順で平らなリスト形式にして返します。こ
      のメソッドは "getChildren()" に似ていますが、 "Node" インスタン
      スしか返さないという点で異なっています。

"Node" クラスの一般的な構造を説明するため、以下に 2 つの例を示します。
"while" 文は以下のような文法規則により定義されています:

   while_stmt:     "while" expression ":" suite
                  ["else" ":" suite]

"While" ノードは 3 つの属性をもっています: "test", "body" および
"else_" です。 (ある属性にふさわしい名前が Python の予約語としてすでに
使われているとき、その名前を属性名にすることはできません。そのため、こ
こでは名前が正規のものとして受けつけられるようにアンダースコアを後につ
けてあります、そのため "else_" は "else" のかわりです。)

"if" 文はもっとこみ入っています。なぜならこれはいくつもの条件判定を含
む可能性があるからです。

   if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]

"If" ノードでは、 "tests" および "else_" の 2つだけの属性が定義されて
います。 "tests" 属性には条件式とその後の動作のタプルがリスト形式で入
っています。おのおのの "if" / "elif" 節ごとに 1 タプルです。各タプルの
最初の要素は条件式で、2 番目の要素はもしその式が真ならば実行されるコー
ドをふくんだ "Stmt" ノードになっています。

"If" の "getChildren()" メソッドは、子ノードの平らなリストを返します。
"if" / "elif" 節が 3 つあって "else" 節がない場合なら、
"getChildren()" は 6 要素のリストを返すでしょう: 最初の条件式、最初の
"Stmt" 、2 番目の条件式…といった具合です。

以下の表は "compiler.ast" で定義されている "Node" サブクラスと、それら
のインスタンスに対して使用可能なパブリックな属性です。ほとんどの属性の
値自体は "Node" インスタンスか、インスタンスのリストです。この値がイン
スタンス型以外の場合、その型は備考の中で記されています。これら属性の順
序は、 "getChildren()" および "getChildNodes()" が返す順です。

+-------------------------+----------------------+-----------------------------------+
| ノード型                | 属性                 | 値                                |
+=========================+======================+===================================+
| "Add"                   | "left"               | 左オペランド                      |
+-------------------------+----------------------+-----------------------------------+
|                         | "right"              | 右オペランド                      |
+-------------------------+----------------------+-----------------------------------+
| "And"                   | "nodes"              | オペランドのリスト                |
+-------------------------+----------------------+-----------------------------------+
| "AssAttr"               |                      | *代入のターゲットとなる属性*      |
+-------------------------+----------------------+-----------------------------------+
|                         | "expr"               | ドットの左側の式                  |
+-------------------------+----------------------+-----------------------------------+
|                         | "attrname"           | 属性名, 文字列                    |
+-------------------------+----------------------+-----------------------------------+
|                         | "flags"              | XXX                               |
+-------------------------+----------------------+-----------------------------------+
| "AssList"               | "nodes"              | 代入先のリスト要素のリスト        |
+-------------------------+----------------------+-----------------------------------+
| "AssName"               | "name"               | 代入先の名前                      |
+-------------------------+----------------------+-----------------------------------+
|                         | "flags"              | XXX                               |
+-------------------------+----------------------+-----------------------------------+
| "AssTuple"              | "nodes"              | 代入先のタプル要素のリスト        |
+-------------------------+----------------------+-----------------------------------+
| "Assert"                | "test"               | テストされる式                    |
+-------------------------+----------------------+-----------------------------------+
|                         | "fail"               | "AssertionError" の値             |
+-------------------------+----------------------+-----------------------------------+
| "Assign"                | "nodes"              | 代入ターゲットのリスト、等号ごと  |
|                         |                      | に一つ                            |
+-------------------------+----------------------+-----------------------------------+
|                         | "expr"               | 代入される値                      |
+-------------------------+----------------------+-----------------------------------+
| "AugAssign"             | "node"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "op"                 |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "expr"               |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Backquote"             | "expr"               |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Bitand"                | "nodes"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Bitor"                 | "nodes"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Bitxor"                | "nodes"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Break"                 |                      |                                   |
+-------------------------+----------------------+-----------------------------------+
| "CallFunc"              | "node"               | 呼び出される式                    |
+-------------------------+----------------------+-----------------------------------+
|                         | "args"               | 引数のリスト                      |
+-------------------------+----------------------+-----------------------------------+
|                         | "star_args"          | 拡張 *-引数の値                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "dstar_args"         | 拡張 **-引数の値                  |
+-------------------------+----------------------+-----------------------------------+
| "Class"                 | "name"               | クラス名, 文字列                  |
+-------------------------+----------------------+-----------------------------------+
|                         | "bases"              | 基底クラスのリスト                |
+-------------------------+----------------------+-----------------------------------+
|                         | "doc"                | ドキュメント文字列, 文字列または  |
|                         |                      | "None"                            |
+-------------------------+----------------------+-----------------------------------+
|                         | "code"               | クラス文の本体                    |
+-------------------------+----------------------+-----------------------------------+
| "Compare"               | "expr"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "ops"                |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Const"                 | "value"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Continue"              |                      |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Decorators"            | "nodes"              | 関数デコレータ式のリスト          |
+-------------------------+----------------------+-----------------------------------+
| "Dict"                  | "items"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Discard"               | "expr"               |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Div"                   | "left"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "right"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Ellipsis"              |                      |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Expression"            | "node"               |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Exec"                  | "expr"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "locals"             |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "globals"            |                                   |
+-------------------------+----------------------+-----------------------------------+
| "FloorDiv"              | "left"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "right"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "For"                   | "assign"             |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "list"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "body"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "else_"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "From"                  | "modname"            |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "names"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Function"              | "decorators"         | "Decorators" または "None"        |
+-------------------------+----------------------+-----------------------------------+
|                         | "name"               | def に使われた名前, 文字列        |
+-------------------------+----------------------+-----------------------------------+
|                         | "argnames"           | 引数名の文字列としてのリスト      |
+-------------------------+----------------------+-----------------------------------+
|                         | "defaults"           | デフォルト値のリスト              |
+-------------------------+----------------------+-----------------------------------+
|                         | "flags"              | xxx                               |
+-------------------------+----------------------+-----------------------------------+
|                         | "doc"                | ドキュメント文字列, 文字列または  |
|                         |                      | "None"                            |
+-------------------------+----------------------+-----------------------------------+
|                         | "code"               | 関数の本体                        |
+-------------------------+----------------------+-----------------------------------+
| "GenExpr"               | "code"               |                                   |
+-------------------------+----------------------+-----------------------------------+
| "GenExprFor"            | "assign"             |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "iter"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "ifs"                |                                   |
+-------------------------+----------------------+-----------------------------------+
| "GenExprIf"             | "test"               |                                   |
+-------------------------+----------------------+-----------------------------------+
| "GenExprInner"          | "expr"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "quals"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Getattr"               | "expr"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "attrname"           |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Global"                | "names"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "If"                    | "tests"              |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "else_"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Import"                | "names"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Invert"                | "expr"               |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Keyword"               | "name"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "expr"               |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Lambda"                | "argnames"           |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "defaults"           |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "flags"              |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "code"               |                                   |
+-------------------------+----------------------+-----------------------------------+
| "LeftShift"             | "left"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "right"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "List"                  | "nodes"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "ListComp"              | "expr"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "quals"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "ListCompFor"           | "assign"             |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "list"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "ifs"                |                                   |
+-------------------------+----------------------+-----------------------------------+
| "ListCompIf"            | "test"               |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Mod"                   | "left"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "right"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Module"                | "doc"                | ドキュメント文字列, 文字列または  |
|                         |                      | "None"                            |
+-------------------------+----------------------+-----------------------------------+
|                         | "node"               | モジュールの本体, "Stmt"          |
+-------------------------+----------------------+-----------------------------------+
| "Mul"                   | "left"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "right"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Name"                  | "name"               |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Not"                   | "expr"               |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Or"                    | "nodes"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Pass"                  |                      |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Power"                 | "left"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "right"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Print"                 | "nodes"              |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "dest"               |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Printnl"               | "nodes"              |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "dest"               |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Raise"                 | "expr1"              |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "expr2"              |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "expr3"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Return"                | "value"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "RightShift"            | "left"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "right"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Slice"                 | "expr"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "flags"              |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "lower"              |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "upper"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Sliceobj"              | "nodes"              | 文のリスト                        |
+-------------------------+----------------------+-----------------------------------+
| "Stmt"                  | "nodes"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Sub"                   | "left"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "right"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Subscript"             | "expr"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "flags"              |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "subs"               |                                   |
+-------------------------+----------------------+-----------------------------------+
| "TryExcept"             | "body"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "handlers"           |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "else_"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "TryFinally"            | "body"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "final"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Tuple"                 | "nodes"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "UnaryAdd"              | "expr"               |                                   |
+-------------------------+----------------------+-----------------------------------+
| "UnarySub"              | "expr"               |                                   |
+-------------------------+----------------------+-----------------------------------+
| "While"                 | "test"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "body"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "else_"              |                                   |
+-------------------------+----------------------+-----------------------------------+
| "With"                  | "expr"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "vars"               |                                   |
+-------------------------+----------------------+-----------------------------------+
|                         | "body"               |                                   |
+-------------------------+----------------------+-----------------------------------+
| "Yield"                 | "value"              |                                   |
+-------------------------+----------------------+-----------------------------------+


33.3.2. 代入ノード
------------------

代入をあらわすのに使われる一群のノードが存在します。ソースコードにおけ
るそれぞれの代入文は、抽象構文木 AST では単一のノード "Assign" になっ
ています。 "nodes" 属性は各代入の対象にたいするノードのリストです。こ
れが必要なのは、たとえば "a = b = 2" のように代入が連鎖的に起こるため
です。このリスト中における各 "Node" は、次のうちどれかのクラスになりま
す: "AssAttr", "AssList", "AssName" または "AssTuple" 。

代入対象の各ノードには代入されるオブジェクトの種類が記録されています。
"AssName" は "a = 1" などの単純な変数名、 "AssAttr" は "a.x = 1" など
の属性に対する代入、 "AssList" および "AssTuple" はそれぞれ、 "a, b, c
= a_tuple" などのようなリストとタプルの展開をあらわします。

代入対象ノードはまた、そのノードが代入で使われるのか、それとも削除文で
使われるのかをあらわす属性 "flags" も持っています。 "AssName" は "del
x" などのような削除文をあらわすのにも使われます。

ある式がいくつかの属性への参照をふくんでいるときは、代入あるいは削除文
はただひとつだけの "AssAttr" ノードをもちます -- 最終的な属性への参照
としてです。それ以外の属性への参照は "AssAttr" インスタンスの "expr"
属性にある "Getattr" ノードによってあらわされます。


33.3.3. 例
----------

この節では、Python ソースコードに対する抽象構文木 AST のかんたんな例を
いくつかご紹介します。これらの例では "parse()" 関数をどうやって使うか
、AST の repr 表現はどんなふうになっているか、そしてある AST ノードの
属性にアクセスするにはどうするかを説明します。

最初のモジュールでは単一の関数を定義しています。かりにこれは
"/tmp/doublelib.py" に格納されていると仮定しましょう。

   """This is an example module.

   This is the docstring.
   """

   def double(x):
       "Return twice the argument"
       return x * 2

以下の対話的インタプリタのセッションでは、見やすさのため長い AST の
repr を整形しなおしてあります。 AST の repr では qualify されていない
クラス名が使われています。 repr 表現からインスタンスを作成したい場合は
、 "compiler.ast" モジュールからそれらのクラス名を import しなければな
りません。

   >>> import compiler
   >>> mod = compiler.parseFile("doublelib.py")
   >>> mod
   Module('This is an example module.\n\nThis is the docstring.\n',
          Stmt([Function(None, 'double', ['x'], [], 0,
                         'Return twice the argument',
                         Stmt([Return(Mul((Name('x'), Const(2))))]))]))
   >>> from compiler.ast import *
   >>> Module('This is an example module.\n\nThis is the docstring.\n',
   ...    Stmt([Function(None, 'double', ['x'], [], 0,
   ...                   'Return twice the argument',
   ...                   Stmt([Return(Mul((Name('x'), Const(2))))]))]))
   Module('This is an example module.\n\nThis is the docstring.\n',
          Stmt([Function(None, 'double', ['x'], [], 0,
                         'Return twice the argument',
                         Stmt([Return(Mul((Name('x'), Const(2))))]))]))
   >>> mod.doc
   'This is an example module.\n\nThis is the docstring.\n'
   >>> for node in mod.node.nodes:
   ...     print node
   ...
   Function(None, 'double', ['x'], [], 0, 'Return twice the argument',
            Stmt([Return(Mul((Name('x'), Const(2))))]))
   >>> func = mod.node.nodes[0]
   >>> func.code
   Stmt([Return(Mul((Name('x'), Const(2))))])


33.4. Visitor を使って AST をわたり歩く
=======================================

visitor パターンは… "compiler" パッケージは、Python のイントロスペクシ
ョン機能を利用して visitor のために必要な大部分のインフラを省略した、
visitor パターンの変種を使っています。

visit されるクラスは、visitor を受け入れるようにプログラムされている必
要はありません。 visitor が必要なのはただそれがとくに興味あるクラスに
対して visit メソッドを定義することだけです。それ以外はデフォルトの
visit メソッドが処理します。

XXX visitor 用の魔法の "visit()" メソッド。

compiler.visitor.walk(tree, visitor[, verbose])

class compiler.visitor.ASTVisitor

   "ASTVisitor" は構文木を正しい順序でわたり歩くようにします。それぞれ
   のノードはまず "preorder()" の呼び出しではじまります。各ノードに対
   して、これは 'visitNodeType' という名前のメソッドに対する
   "preorder()" 関数への *visitor* 引数をチェックします。ここで
   NodeType の部分はそのノードのクラス名です。たとえば "While" ノード
   なら、 "visitWhile()" が呼ばれるわけです。もしそのメソッドが存在し
   ている場合、それはそのノードを第一引数として呼び出されます。

   ある特定のノード型に対する visitor メソッドでは、その子ノードをどの
   ようにわたり歩くかが制御できます。 "ASTVisitor" は visitor に visit
   メソッドを追加することで、その visitor 引数を修正します; このメソッ
   ドは特定の子ノードを訪問するのに使われるでしょう。特定のノード型に
   対する visitor が存在しない場合、 "default()" メソッドが呼び出され
   ます。

   "ASTVisitor" オブジェクトには以下のようなメソッドがあります:

   XXX 追加の引数を記述

   default(node[, ...])

   dispatch(node[, ...])

   preorder(tree, visitor)


33.5. バイトコード生成
======================

バイトコード生成器はバイトコードを出力する visitor です。 visit メソッ
ドが呼ばれるたびにこれは "emit()" メソッドを呼び出し、バイトコードを出
力します。基本的なバイトコード生成器はモジュール、クラス、および関数の
ために特殊化されます。アセンブラがこれらの出力された命令を低レベルのバ
イトコードに変換します。これはコードオブジェクトからなる定数のリスト生
成や、分岐のオフセット計算といった処理をおこないます。
