func Inspect(node Node, f inspector) {
	Walk(inspector(f), node, nil)
}
Inspect traverses an AST in depth-first order: It starts by calling
f(node, path); node must not be nil. If f returns a nil error, Inspect invokes f
for all the non-nil children of node, recursively.
package promql
import (
	"time"
	"github.com/pkg/errors"
	"github.com/prometheus/prometheus/pkg/labels"
	"github.com/prometheus/prometheus/storage"
)
type Node interface {
	String() string
}
type Statement interface {
	Node
	stmt()
}
type EvalStmt struct {
	Expr Expr  
	Start, End time.Time
	Interval time.Duration
}
func (*EvalStmt) stmt() {}
type Expr interface {
	Node
	Type() ValueType
	expr()
}
type Expressions []Expr
type AggregateExpr struct {
	Op       ItemType  
	Expr     Expr      
	Param    Expr      
	Grouping []string  
	Without  bool      
}
type BinaryExpr struct {
	Op       ItemType  
	LHS, RHS Expr      
	VectorMatching *VectorMatching
	ReturnBool bool
}
type Call struct {
	Func *Function    
	Args Expressions  
}
type MatrixSelector struct {
	Name          string
	Range         time.Duration
	Offset        time.Duration
	LabelMatchers []*labels.Matcher
	unexpandedSeriesSet storage.SeriesSet
	series              []storage.Series
}
type SubqueryExpr struct {
	Expr   Expr
	Range  time.Duration
	Offset time.Duration
	Step   time.Duration
}
type NumberLiteral struct {
	Val float64
}
type ParenExpr struct {
	Expr Expr
}
type StringLiteral struct {
	Val string
}
type UnaryExpr struct {
	Op   ItemType
	Expr Expr
}
type VectorSelector struct {
	Name          string
	Offset        time.Duration
	LabelMatchers []*labels.Matcher
	unexpandedSeriesSet storage.SeriesSet
	series              []storage.Series
}
func (e *AggregateExpr) Type() ValueType  { return ValueTypeVector }
func (e *Call) Type() ValueType           { return e.Func.ReturnType }
func (e *MatrixSelector) Type() ValueType { return ValueTypeMatrix }
func (e *SubqueryExpr) Type() ValueType   { return ValueTypeMatrix }
func (e *NumberLiteral) Type() ValueType  { return ValueTypeScalar }
func (e *ParenExpr) Type() ValueType      { return e.Expr.Type() }
func (e *StringLiteral) Type() ValueType  { return ValueTypeString }
func (e *UnaryExpr) Type() ValueType      { return e.Expr.Type() }
func (e *VectorSelector) Type() ValueType { return ValueTypeVector }
func (e *BinaryExpr) Type() ValueType {
	if e.LHS.Type() == ValueTypeScalar && e.RHS.Type() == ValueTypeScalar {
		return ValueTypeScalar
	}
	return ValueTypeVector
}
func (*AggregateExpr) expr()  {}
func (*BinaryExpr) expr()     {}
func (*Call) expr()           {}
func (*MatrixSelector) expr() {}
func (*SubqueryExpr) expr()   {}
func (*NumberLiteral) expr()  {}
func (*ParenExpr) expr()      {}
func (*StringLiteral) expr()  {}
func (*UnaryExpr) expr()      {}
func (*VectorSelector) expr() {}
type VectorMatchCardinality int
const (
	CardOneToOne VectorMatchCardinality = iota
	CardManyToOne
	CardOneToMany
	CardManyToMany
)
func (vmc VectorMatchCardinality) String() string {
	switch vmc {
	case CardOneToOne:
		return "one-to-one"
	case CardManyToOne:
		return "many-to-one"
	case CardOneToMany:
		return "one-to-many"
	case CardManyToMany:
		return "many-to-many"
	}
	panic("promql.VectorMatchCardinality.String: unknown match cardinality")
}
type VectorMatching struct {
	Card VectorMatchCardinality
	MatchingLabels []string
	On bool
	Include []string
}
type Visitor interface {
	Visit(node Node, path []Node) (w Visitor, err error)
}
func Walk(v Visitor, node Node, path []Node) error {
	var err error
	if v, err = v.Visit(node, path); v == nil || err != nil {
		return err
	}
	path = append(path, node)
	switch n := node.(type) {
	case *EvalStmt:
		if err := Walk(v, n.Expr, path); err != nil {
			return err
		}
	case Expressions:
		for _, e := range n {
			if err := Walk(v, e, path); err != nil {
				return err
			}
		}
	case *AggregateExpr:
		if n.Param != nil {
			if err := Walk(v, n.Param, path); err != nil {
				return err
			}
		}
		if err := Walk(v, n.Expr, path); err != nil {
			return err
		}
	case *BinaryExpr:
		if err := Walk(v, n.LHS, path); err != nil {
			return err
		}
		if err := Walk(v, n.RHS, path); err != nil {
			return err
		}
	case *Call:
		if err := Walk(v, n.Args, path); err != nil {
			return err
		}
	case *SubqueryExpr:
		if err := Walk(v, n.Expr, path); err != nil {
			return err
		}
	case *ParenExpr:
		if err := Walk(v, n.Expr, path); err != nil {
			return err
		}
	case *UnaryExpr:
		if err := Walk(v, n.Expr, path); err != nil {
			return err
		}
	case *MatrixSelector, *NumberLiteral, *StringLiteral, *VectorSelector:
	default:
		panic(errors.Errorf("promql.Walk: unhandled node type %T", node))
	}
	_, err = v.Visit(nil, nil)
	return err
}
type inspector func(Node, []Node) error
func (f inspector) Visit(node Node, path []Node) (Visitor, error) {
	if err := f(node, path); err != nil {
		return nil, err
	}
	return f, nil
}