3.14 組み込みモジュール parser

  

parserモジュールは、パイソンの内部パーサとバイトコードコンパイラのインターフェイスを提供します。このインターフェイスの主な目的は、パイソンコードがパイソン表現の解析木を編集し、実行可能なコードを作ることを許可することです。これは、任意のパイソンコードの一部を、文字列として解析、修正しようとすることよりベターです。なぜなら解析は、アプリケ−ションの構成するコードとある意味同じだからです。また、より早いです。

parserモジュールは、Fred L. Drake, Jr.(fdrake@acm.org)によって作成、ドキュメント化されました。  

作成したデータ構造を使用するのに重要なこのモジュールについて、注意することがいくつかあります。この節はパイソンコードの解析木の編集に関するチュートリアルではありませんが、parserモジュールの使用例がいくつか紹介されています

最も重要なことには、内部パーサによって処理されたパイソンの文法をよく理解することが必要です。 構文に関する全ての情報は、Python Language Referenceを参照して下さい。 パーサ自身は、標準的なパイソンの配付物では、"Grammar/Grammar"ファイル中に定義されている文法仕様書から作られています。このモジュールによって作られたASTオブジェクトに保存されている解析木は、以下に書かれているexpr()関数やsuite()関数で作成したときの、内部パーサからの実際のアウトプットです。sequence2ast()によって作られたASTオブジェクトは、正確にこれらの機能をシミュレートします。正しいと見なされるシーケンスの値は、パイソンのバージョンによって言語の文法が変わるので、変化することを知っておいて下さい。しかしながら、ソースをパイソンのあるバージョンから他のバージョンに移せば、以前のバージョンのインタプリタへの移行は、新しい構文をサポートしないという制約だけで、いつも目的のバージョンで正しい解析木が作成されます。ソースコードは通常forward-compatibleであるのに、解析木はバージョン間で互換性はありません。

ast2list()ast2tuple()から返されたシーケンスの各要素は、簡単な形を持っています。文法中のnon-terminal elementsを表すシーケンスは、いつも1以上の長さを持っています。最初の要素は、文法中のproductionを識別する整数です。これらの整数は、Cヘッダーファイル"Include/graminit.h"やパイソンモジュールsymbol内でシンボリックネームを与えられています。シーケンスの各追加要素は、入力文字列中にrecognizedとして、a component of the productionを表します。これらは、いつも親と同じ形をしたシーケンスです。この機能で注意すべき重要なことは、if_stmt内のifキーワードのようなキーワードは、特別扱いなしでnode treeに含まれている親のノードタイプを識別するのに使われるということです。例えば、ifキーワードはタプル(1, 'if')によって表されます。1は、ユーザーによって定義された変数や関数名を含む全てのNAMEトークンと関連した数値です。行番号の情報をとりたい時に返される代わりの形では、同じトークンは、(1, 'if', 12)と表されます。12はterminal symbolのあった行数を表します。

Terminal elementsは、ほとんど同じ方法で、child elementsや識別されたソーステキストの追加無しで表されます。上のifキーワードの例は、その典型です。terminal symbolsのいろいろなタイプが、Cのヘッダファイル"Include/token.h"や、パイソンのtokenモジュールの中に定義されています。

ASTオブジェクトは、このモジュールの機能をサポートする必要はありませんが、3つの目的の為に提供されています。すなわち、アプリケーションに複雑な解析木を処理するコストを償却することを許可すること、リストやタプルを比較する時にメモリ空間を保護する解析木を提供すること、解析木を扱うCの追加モジュールの作成を簡単にすることです。 簡単なラッパークラスは、ASTオブジェクトの使用を隠す為に作成されているかもしれません。

parserモジュールは、いくつかの異なった目的の為の関数が定義されています。最も重要な目的は、ASTオブジェクトを作成したり、ASTオブジェクトを解析木やコンパイル済みコードオブジェクトのような他のものに変換することです。しかし、ASTオブジェクトによって表される解析木の型を尋ねるのに役立つ関数もあります。


guido@python.org