Goの標準パッケージではじめる静的解析入門①準備編

Mar 10, 2019 23:52 · 1205 words · 3 minutes read Go 静的解析

はじめに

Go言語では、標準パッケージであるgoパッケージが字句解析や構文解析を行う機能を提供しています。

go/astやgo/parserを使って構文解析のはじめの一歩を踏み出してみます。

参考


用語説明

静的解析とは

静的コード解析、静的プログラム解析とも言います。 ソースコードを 実行することなく 解析を行うことを指します。

対義語は動的解析で、ソースコードを実行して解析を行うことを表します。 こちらはプログラマが普段行なっているような検証方法です。

抽象構文木(AST)とは

abstract syntax tree. 構文解析の経過や結果から、言語の意味に関係ない情報を取り除き、意味に関係ある情報のみを取り出したツリー状(木)のデータ構造のことです。 Wikipedia | 抽象構文木

トラバース(走査)とは

抽象構文木のような木構造の各ノードを探索、調査することです。 ノードとは、下記の図でいうところのA,B,C…が書いてあるそれぞれの◯を指します。 Wikipedia | 木構造(データ構造)#走査法

木構造

やること

  • 字句解析/構文解析
  • 抽象構文木(AST)のトラバース
  • 位置情報の取得
  • 型情報の取得

静的解析を行うための機能が提供されている、goパッケージ配下のパッケージを使います。

やらないこと

  • 静的解析のモジュール化
  • golang.org/x/tools/go/analysisパッケージの解説

実用の視点に立ったモジュール化の手法については、tenntennさんの記事をご覧下さい。

Goにおける静的解析のモジュール化について


字句解析で利用するパッケージ

go/scanner

字句解析を行う際に使うパッケージです。

scanner/Scan関数を使い、ソースコードを読み込み、トークンの位置、トークン、srcで与えた値の文字列リテラルを取得します。

scanner/Scan

func (s *Scanner) Scan() (pos token.Pos, tok token.Token, lit string)

go/token

字句解析を行う際に使うパッケージです。

ファイルの位置や長さに関する情報を保持する構造体(token.FileSet型)です。

token/FileSet

type FileSet struct {
    // contains filtered or unexported fields
}

scanner/Scanなどを使って取得するトークンの位置情報は絶対的なものではなく、token.FileSetを基準として相対的に決められます。

構文解析で利用するパッケージ

go/parser

構文解析を行う際に使うパッケージです。

ソースコードを字句解析し、構文解析を行い、抽象構文木(AST)まで作ってくれます。

文字列をパースするために、parser.ParseExpr関数を使います。

parser/ParseExpr

func ParseExpr(x string) (ast.Expr, error)

go/ast

抽象構文木(AST)を定義したパッケージです。

抽象構文木(AST)をトラバースするために、ast.Inspect関数を使います。

ast/Inspect

func Inspect(node Node, f func(Node) bool)

おわりに

今回は用語や利用する標準パッケージについて説明しました。

次回は静的解析を行う際の流れを確認します。