Goで、ソースコードをASTにする
最終更新日:2018-01-13
ソースコードをASTに変換するには、`parser.ParseFile()`を使用します。変換の方法は2種類あります。
ファイル名を指定する方法
ファイル名を指定する場合は、第2引数にファイル名を指定し、第3引数を`nil`にします。例として自分自身(main.go)をASTに変換してみます。
package main
import (
"fmt"
"go/ast"
"go/parser"
"go/token"
)
func main() {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "./main.go", nil, 0)
if err != nil {
fmt.Printf("Failed to parse file\n")
return
}
ast.Print(fset, f)
}
ast.Print()`を使用すると、ASTを可視化することができます。
0 *ast.File {
1 . Package: ./main.go:1:1
2 . Name: *ast.Ident {
3 . . NamePos: ./main.go:1:9
4 . . Name: "main"
5 . }
6 . Decls: []ast.Decl (len = 2) {
7 . . 0: *ast.GenDecl {
8 . . . TokPos: ./main.go:3:1
9 . . . Tok: import
10 . . . Lparen: ./main.go:3:8
11 . . . Specs: []ast.Spec (len = 4) {
12 . . . . 0: *ast.ImportSpec {
13 . . . . . Path: *ast.BasicLit {
14 . . . . . . ValuePos: ./main.go:4:2
15 . . . . . . Kind: STRING
16 . . . . . . Value: "\"fmt\""
17 . . . . . }
18 . . . . . EndPos: -
19 . . . . }
20 . . . . 1: *ast.ImportSpec {
21 . . . . . Path: *ast.BasicLit {
22 . . . . . . ValuePos: ./main.go:5:2
23 . . . . . . Kind: STRING
24 . . . . . . Value: "\"go/ast\""
25 . . . . . }
26 . . . . . EndPos: -
27 . . . . }
...
ソースコードを文字列で指定する方法
ファイルからソースコードを文字列として読み込み、そこからASTを作る方法もあります。この場合、第3引数に文字列となったソースコードを指定します。
package main
import (
"fmt"
"go/ast"
"go/parser"
"go/token"
)
func main() {
src := `package moke
import ( "fmt")
func main() {
fmt.Printf("OK!")
}
`
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "", src, 0)
if err != nil {
fmt.Printf("Failed to parse file\n")
return
}
ast.Print(fset, f)
}