Visitor
Expr provides an interface to traverse the AST of the expression before the compilation.
The Visitor
interface allows you to collect information about the expression, modify the expression, or even generate
a new expression.
Let's start with an ast.Visitor implementation which will collect all variables used in the expression.
Visitor must implement a single method Visit(*ast.Node)
, which will be called for each node in the AST.
type Visitor struct {
Identifiers []string
}
func (v *Visitor) Visit(node *ast.Node) {
if n, ok := (*node).(*ast.IdentifierNode); ok {
v.Identifiers = append(v.Identifiers, n.Value)
}
}
Full list of available AST nodes can be found in the ast documentation.
Let's parse the expression and use ast.Walk to traverse the AST:
tree, err := parser.Parse(`foo + bar`)
if err != nil {
panic(err)
}
v := &Visitor{}
ast.Walk(&tree.Node, v)
fmt.Println(v.Identifiers) // [foo, bar]
note
Although it is possible to access the AST of compiled program, it may be already be modified by patchers, optimizers, etc.
program, err := expr.Compile(`foo + bar`)
if err != nil {
panic(err)
}
node := program.Node()
v := &Visitor{}
ast.Walk(&node, v)