はじめに
Go言語では、標準パッケージであるgoパッケージが字句解析や構文解析を行う機能を提供しています。
go/astやgo/parserを使って構文解析のはじめの一歩を踏み出してみます。
参考
- Qiita | goパッケージで簡単に静的解析して世界を広げよう #golang
静的解析を学ぶ際に参考になる記事のまとめ(tenntennさん筆)
用語説明
静的解析とは
静的コード解析、静的プログラム解析とも言います。
ソースコードを 実行することなく 解析を行うことを指します。
対義語は動的解析で、ソースコードを実行して解析を行うことを表します。
こちらはプログラマが普段行なっているような検証方法です。
抽象構文木(AST)とは
abstract syntax tree.
構文解析の経過や結果から、言語の意味に関係ない情報を取り除き、意味に関係ある情報のみを取り出したツリー状(木)のデータ構造のことです。
Wikipedia | 抽象構文木
トラバース(走査)とは
抽象構文木のような木構造の各ノードを探索、調査することです。
ノードとは、下記の図でいうところのA,B,C…が書いてあるそれぞれの◯を指します。
Wikipedia | 木構造(データ構造)#走査法
やること
- 字句解析/構文解析
- 抽象構文木(AST)のトラバース
- 位置情報の取得
- 型情報の取得
静的解析を行うための機能が提供されている、goパッケージ配下のパッケージを使います。
やらないこと
- 静的解析のモジュール化
- golang.org/x/tools/go/analysisパッケージの解説
実用の視点に立ったモジュール化の手法については、tenntennさんの記事をご覧下さい。
字句解析で利用するパッケージ
go/scanner
字句解析を行う際に使うパッケージです。
scanner/Scan
関数を使い、ソースコードを読み込み、トークンの位置、トークン、srcで与えた値の文字列リテラルを取得します。
func (s *Scanner) Scan() (pos token.Pos, tok token.Token, lit string)
go/token
字句解析を行う際に使うパッケージです。
ファイルの位置や長さに関する情報を保持する構造体(token.FileSet型)です。
type FileSet struct {
// contains filtered or unexported fields
}
scanner/Scan
などを使って取得するトークンの位置情報は絶対的なものではなく、token.FileSet
を基準として相対的に決められます。
構文解析で利用するパッケージ
go/parser
構文解析を行う際に使うパッケージです。
ソースコードを字句解析し、構文解析を行い、抽象構文木(AST)まで作ってくれます。
文字列をパースするために、parser.ParseExpr
関数を使います。
func ParseExpr(x string) (ast.Expr, error)
go/ast
抽象構文木(AST)を定義したパッケージです。
抽象構文木(AST)をトラバースするために、ast.Inspect
関数を使います。
func Inspect(node Node, f func(Node) bool)
おわりに
今回は用語や利用する標準パッケージについて説明しました。
次回は静的解析を行う際の流れを確認します。