Files
sjy01-image-proc/vendor/github.com/go-latex/latex/ast/walk.go
2024-10-24 15:46:01 +08:00

89 lines
1.8 KiB
Go

// Copyright ©2020 The go-latex Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ast
import "fmt"
// A Visitor's Visit method is invoked for each node encountered by Walk.
// If the result visitor w is not nil, Walk visits each of the children
// of node with the visitor w, followed by a call of w.Visit(nil).
type Visitor interface {
Visit(node Node) (w Visitor)
}
// Walk traverses an AST in depth-first order: It starts by calling
// v.Visit(node); node must not be nil. If the visitor w returned by
// v.Visit(node) is not nil, Walk is invoked recursively with visitor
// w for each of the non-nil children of node, followed by a call of
// w.Visit(nil).
func Walk(v Visitor, node Node) {
if v = v.Visit(node); v == nil {
return
}
switch n := node.(type) {
case List:
for _, x := range n {
Walk(v, x)
}
case *Macro:
if n.Name != nil {
Walk(v, n.Name)
}
walkNodes(v, n.Args)
case *Arg:
walkNodes(v, n.List)
case *OptArg:
walkNodes(v, n.List)
case *Ident:
// nothing to do.
case *MathExpr:
walkNodes(v, n.List)
case *Word, *Literal, *Symbol:
// nothing to do.
case *Sub:
Walk(v, n.Node)
case *Sup:
Walk(v, n.Node)
default:
panic(fmt.Errorf("unknown ast node %#v (type=%T)", n, n))
}
v.Visit(nil)
}
func walkNodes(v Visitor, nodes []Node) {
for _, x := range nodes {
Walk(v, x)
}
}
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)
}