Created
December 31, 2016 01:55
-
-
Save tenntenn/f938d5849157fc44790321b6ae9246cc to your computer and use it in GitHub Desktop.
抽象構文木(AST)をトラバースする #golang ref: http://qiita.com/tenntenn/items/f029425a844687a0e64b
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func Inspect(node Node, f func(Node) bool) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
expr, err := parser.ParseExpr(`1+1`) | |
if err != nil { | |
log.Fatalln("Error:", err) | |
} | |
ast.Inspect(expr, func(n ast.Node) bool { | |
fmt.Printf("%[1]T %[1]v\n", n) | |
return true | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*ast.BinaryExpr (+) | |
├── *ast.BasicLit (1) | |
└── *ast.BasicLit (1) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*ast.BinaryExpr &{0x1050e150 2 + 0x1050e160} | |
*ast.BasicLit &{1 INT 1} | |
<nil> <nil> | |
*ast.BasicLit &{3 INT 1} | |
<nil> <nil> | |
<nil> <nil> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
expr, err := parser.ParseExpr(`1+1`) | |
if err != nil { | |
log.Fatalln("Error:", err) | |
} | |
var i int | |
ast.Inspect(expr, func(n ast.Node) bool { | |
fmt.Printf("%s%[2]T %[2]v\n", strings.Repeat(" ", i), n) | |
if n != nil { | |
i++ | |
} else { | |
i-- | |
} | |
return true | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*ast.BinaryExpr &{0x1050e150 2 + 0x1050e160} | |
*ast.BasicLit &{1 INT 1} | |
<nil> <nil> | |
*ast.BasicLit &{3 INT 1} | |
<nil> <nil> | |
<nil> <nil> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type inspector func(Node) bool | |
func (f inspector) Visit(node Node) Visitor { | |
if f(node) { | |
return f | |
} | |
return nil | |
} | |
// Inspect traverses an AST in depth-first order: It starts by calling | |
// f(node); node must not be nil. If f returns true, Inspect invokes f | |
// recursively for each of the non-nil children of node, followed by a | |
// call of f(nil). | |
// | |
func Inspect(node Node, f func(Node) bool) { | |
Walk(inspector(f), node) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func Walk(v Visitor, node Node) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Visitor interface { | |
Visit(node Node) (w Visitor) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"go/ast" | |
"go/parser" | |
"log" | |
) | |
type visitorFunc func(node ast.Node) (w ast.Visitor) | |
func (f visitorFunc) Visit(node ast.Node) (w ast.Visitor) { | |
return f(node) | |
} | |
func main() { | |
expr, err := parser.ParseExpr(`1+1`) | |
if err != nil { | |
log.Fatalln("Error:", err) | |
} | |
var v1, v2 visitorFunc | |
v1 = visitorFunc(func(node ast.Node) (w ast.Visitor) { | |
fmt.Printf("%T\n", node) | |
switch node.(type) { | |
case *ast.BinaryExpr: | |
return v2 | |
} | |
return nil | |
}) | |
v2 = visitorFunc(func(node ast.Node) (w ast.Visitor) { | |
if node == nil { | |
return nil | |
} | |
lit := node.(*ast.BasicLit) | |
fmt.Printf("BasicLit: %s\n", lit.Value) | |
return nil | |
}) | |
ast.Walk(v1, expr) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment