golang.tokyo #22+Okayama.go/Sendai.go 概要まとめ ~静的解析ハンズオン~
はじめに
今日はこれにきてます!https://t.co/37YE7MtfxD #22+Okayama.go/Sendai.go https://t.co/p7xAv5GJiz #golangtokyo
— nari@エンタメ系エンジニア (@fukubaka0825) March 23, 2019
今日はこれにきてます!https://t.co/37YE7MtfxD #22+Okayama.go/Sendai.go https://t.co/p7xAv5GJiz #golangtokyo
— nari@エンタメ系エンジニア (@fukubaka0825) March 23, 2019golang.tokyo #22+Okayama.go/Sendai.go - connpass
このイベントに行ってまいりました。
内容としては、このイベントの概要となります。
今回のテーマは、静的解析でした。
登壇者:
@tenntenn
資料:
A Tour of Static Analysis - Google スライド
このページについて | golang.tokyo コードラボ
そもそも静的解析ってなんの役に立つ
- go vetとかgolintみたいなツールを作るのに向いている
- コンパイラじゃ見つけてくれないバグを探すのに使える
- Goの文法に詳しくなれる
静的解析の流れ
- 字句解析
文字列をトークンへ!! 字句解析で、文字列の塊だったソースコードが予約語のfuncなのか、識別子(変数名や関数名など)なのか、数値リテラルなのかなどを区別することができるトークンの塊に変換される。
字句解析についてはgo/parserパッケージ内でgo/scannerパッケージを用いて行われています。
go/parserで自動でやられるので点線表記みたいですね
- 構文解析
トークンをASTへ!! 構文解析を行うと、どの部分が関数定義で、どの部分がその引数の定義なのか、などを抽象構文木から取得することができるようになる。 - 型チェック
最後に型チェックを行うことで、抽象構文木から型情報を抽出
型チェックは次の3つの工程から成る。
1.識別子の解決
2.型の推論
3.定数の評価
この3つの工程を行い、型情報を抽出することで、どの変数(識別子)がどういうデータ型でどこで定義され、どこで使用されているかなどを知ることができる。
Gopherを探せ!ハンズオン
概要
package main
import (
"fmt"
)
type Gopher struct {
Gopher string `json:"gopher"`
}
func main() {
const gopher = "GOPHER"
gogopher := GOPHER()
gogopher.Gopher = gopher
fmt.Println(gogopher)
}
func GOPHER() (gopher *Gopher) {
gopher = &Gopher{Gopher: "gopher"}
return
}
上記のファイルから、名前付き型かつGopherという名前の識別子だけを
サーチするにはどうしたらいいかが
- grepコマンドの限界
- 式の構造解析
- ファイルの構造解析
- 型チェック
という流れで学べる、すごくわかりやすいハンズオンになっていました。
ハンズオンを書き換えて、理解を深める
ここからは個人で勝手にやった内容となります。
リテラルの"gopher"文字列をサーチするように書き換えてみます。
package main
import (
"fmt"
"go/ast"
"go/importer"
"go/parser"
"go/token"
"go/types"
"log"
"strconv"
)
func main() {
// ファイルごとのトークンの位置を記録するFileSetを作成する
fset := token.NewFileSet()
// ファイル単位で構文解析を行う
f, err := parser.ParseFile(fset, "_gopher.go", nil, 0)
if err != nil {
log.Fatal("Error:", err)
}
// 識別子が定義または利用されてる部分を記録する
defsOrUses := map[*ast.Ident]types.Object{}
info := &types.Info{
Defs: defsOrUses,
Uses: defsOrUses,
}
// 型チェックを行うための設定
config := &types.Config{
Importer: importer.Default(),
}
// 型チェックを行う
_, err = config.Check("main", fset, []*ast.File{f}, info)
if err != nil {
log.Fatal("Error:", err)
}
// 抽象構文木を深さ優先で探索する
ast.Inspect(f, func(n ast.Node) bool {
// リテラルではない場合は無視
basic, ok := n.(*ast.BasicLit)
if !ok {
return true
}
basicValue,err := strconv.Unquote(basic.Value)
if err !=nil{
panic(err)
}
//リテラルが"gopher"という値でなければ無視
if basicValue != "gopher" && basicValue != `json:"gopher"` {
return true
}
fmt.Println(fset.Position(basic.Pos()))
return true
})
}
takafk9@narikawakiyoshinoMacBook-Pro [16時39分00秒] [~/go/src/github.com/golangtokyo/codelab/find-gophers/3_typecheck] [master *]
-> % go run main.go
_gopher.go:8:16
_gopher.go:19:27
きちんとリテラルを捕まえてますね
structタグのastが
Tag: *ast.BasicLit {
ValuePos: 70
Kind: STRING
Value: "`json:\"gopher\"`"
}
なようなので、
if basicValue != "gopher" && basicValue != `json:"gopher"`
という規制で、タグ内の"gopher"も捕まえられました
(slackで回答していただいた方々、ありがとうございました!)
感想
静的解析についてかなりディープで難しい領域に思っていましたが、今回のハンズオンで
少しイメージが変わりました。
(この流れをモジュール化したAnalyzerまで手を出せなかったので、時間あるときに、そちらもやっていきたい)
golang.tokyoのイベントにお邪魔するのは初めてなのですが、Slackでも疑問に即レスで答えていただけて、非常に素晴らしいイベントでした。
ちょっとastにおこして解析するだけで、かなり文法の知識を深められたので、
今度は自作で静的解析ツールを作りたいと思います。
ありがとうございました!
その他有益な資料まとめ
analysis.Analyzerを使っている今回のようなサンプルプログラム
なぜ SSA が扱いやすいのかについてのお気持ち的なやつ。#golangtokyo https://t.co/F7TjjOJ3Ot
— チェシャ猫 (@y_taka_23) March 23, 2019
tenntennさんが作ったAnalyzerを使った静的解析CLIを作り始めるのに便利奴
Goの標準パッケージではじめる静的解析入門①準備編 · mom0tomo
analysis pkgh設計者(“プログラミング言語Go”執筆者)によるtypesの説明
motemenさんによるgo/astパッケージやgo/typesパッケージ
余談
こんなサイトあるんや、、、
自分でカスタマイズしたgopher君入りのCapとか買えるししゅごい
I just Gopherized myself! #gopherize #golang https://t.co/R9bq9gRPCR
— nari@エンタメ系エンジニア (@fukubaka0825) March 23, 2019
こんなサイトあるんや、、、
自分でカスタマイズしたgopher君入りのCapとか買えるししゅごい
I just Gopherized myself! #gopherize #golang https://t.co/R9bq9gRPCR
Gopherオタクになりたて人間には最高のサイト、、、
Author And Source
この問題について(golang.tokyo #22+Okayama.go/Sendai.go 概要まとめ ~静的解析ハンズオン~), 我々は、より多くの情報をここで見つけました https://qiita.com/fukubaka0825/items/978ca41cd7c31c7597dc著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .