🧌

AST について調べてみた

に公開

AST(Abstract Syntax Tree) とは

  • プログラムの文法構造を木構造で表したもの
    • ソースコード:人間が読みやすいもの
    • AST:コンピュータが読みやすいもの

下記は簡単な Python のソースコードを AST を用いて表現した例です.

AST 変換

Python には AST ライブラリが用意されているため,AST を簡単に生成することができます.
まず,print('Hello, World!') というコードを AST に変換してみます.

import ast

code = "print('Hello, World!')"

parsed_src = ast.parse(code)
print(ast.dump(parsed_src, indent=4))

アウトプットは以下のようになります.

Module(
    body=[
        Expr(
            value=Call(
                func=Name(id='print', ctx=Load()),
                args=[
                    Constant(value='Hello, World!')],
                keywords=[]))],
    type_ignores=[])

各ノードの説明は以下の通りです.

  • Module: プログラム全体が一つのモジュールとして扱われる
  • body: 実行される文(statement)が配列として格納される
  • Expr: 式(expression)を表すノード
  • Call: 関数呼び出しを表現(print() の部分)
  • func: 呼び出される関数名(print
  • Name: 変数名や関数名を表すノード
  • ctx=Load(): 値を読み込むコンテキストを示す(値を取得して使用)
  • args: 関数の引数を配列として管理
  • Constant: 文字列や数値などのリテラル値('Hello, World!'
  • keywords: 名前付き引数(今回は空の配列)
  • type_ignores: 型チェックの無視指定(今回は空の配列)

AST 変換 ~ 関数 ~

次に簡単な Python 関数を AST に変換してみます.

import ast

code = """
def add(a, b):
    return a + b
"""

parsed_src = ast.parse(code)
print(ast.dump(parsed_src, indent=4))

アウトプットは以下のようになります.

Module(
    body=[
        FunctionDef(
            name='add',
            args=arguments(
                posonlyargs=[],
                args=[
                    arg(arg='a'),
                    arg(arg='b')],
                kwonlyargs=[],
                kw_defaults=[],
                defaults=[]),
            body=[
                Return(
                    value=BinOp(
                        left=Name(id='a', ctx=Load()),
                        op=Add(),
                        right=Name(id='b', ctx=Load())))],
            decorator_list=[],
            type_params=[])],
    type_ignores=[])

この結果からわかることは以下の通りです.

  • Module ノードがプログラム全体を表す
  • FunctionDef ノードで add 関数が定義されている
    • args に引数 a, b が含まれる
    • bodyReturn ノードが 1 つだけあり,戻り値として BinOp(Add)a + b を計算している
  • 装飾子(decorator_list)や型パラメータ(type_params)は無く,シンプルな関数定義である
  • type_ignores が空なので型無視指示も無い

AST 視覚化

先ほどご紹介した add 関数を視覚化すると以下のようになります.
ちなみに,こちらから簡単に作成可能です.使用時は,parserpython に変更することを忘れないようにしてください.

まとめ

  • プログラムの文法構造を木構造で表したもの
  • Python の AST ライブラリを用いて,AST を生成することができる

参考文献

http://note.shiftinc.jp/n/n70f6970cfeac
https://hireroo.io/journal/tech/abstract-syntax-tree-for-machine-learning

NISLab 小板研究室

Discussion