モケラ

Tech Sheets

mokelab

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)
}

一覧に戻る