goProject/.svn/pristine/da/da0127ddf0fa01fadb0e50628107f55f6ea1526a.svn-base
2025-01-06 16:21:36 +08:00

133 lines
2.3 KiB
Plaintext

package parse
import (
"bytes"
"fmt"
)
// A Node is an element in the parse tree.
type Node interface {
Type() NodeType
String() string
}
// NodeType identifies the type of a parse tree node.
type NodeType int
func (t NodeType) Type() NodeType {
return t
}
const (
NodeRoot NodeType = iota
NodeAxis
NodeFilter
NodeFunction
NodeOperator
NodeVariable
NodeConstantOperand
)
// RootNode holds a top-level node of tree.
type RootNode struct {
NodeType
slash string
}
func (r *RootNode) String() string {
return r.slash
}
// OperatorNode holds two Nodes operator.
type OperatorNode struct {
NodeType
Op string
Left Node
Right Node
}
func (o *OperatorNode) String() string {
return fmt.Sprintf("%v%s%v", o.Left, o.Op, o.Right)
}
// AxisNode holds a location step.
type AxisNode struct {
NodeType
Input Node
Prop string // node-test name.[comment|text|processing-instruction|node]
AxeType string // name of the axes.[attribute|ancestor|child|....]
LocalName string // local part name of node.
Prefix string // prefix name of node.
}
func (a *AxisNode) String() string {
var b bytes.Buffer
if a.AxeType != "" {
b.Write([]byte(a.AxeType + "::"))
}
if a.Prefix != "" {
b.Write([]byte(a.Prefix + ":"))
}
b.Write([]byte(a.LocalName))
if a.Prop != "" {
b.Write([]byte("/" + a.Prop + "()"))
}
return b.String()
}
// OperandNode holds a constant operand.
type OperandNode struct {
NodeType
Val interface{}
}
func (o *OperandNode) String() string {
return fmt.Sprintf("%v", o.Val)
}
// FilterNode holds a condition filter.
type FilterNode struct {
NodeType
Input, Condition Node
}
func (f *FilterNode) String() string {
return fmt.Sprintf("%s[%s]", f.Input, f.Condition)
}
// VariableNode holds a variable.
type VariableNode struct {
NodeType
Name, Prefix string
}
func (v *VariableNode) String() string {
if v.Prefix == "" {
return v.Name
}
return fmt.Sprintf("%s:%s", v.Prefix, v.Name)
}
// FunctionNode holds a function call.
type FunctionNode struct {
NodeType
Args []Node
Prefix string
FuncName string // function name
}
func (f *FunctionNode) String() string {
var b bytes.Buffer
// fun(arg1, ..., argn)
b.Write([]byte(f.FuncName))
b.Write([]byte("("))
for i, arg := range f.Args {
if i > 0 {
b.Write([]byte(","))
}
b.Write([]byte(fmt.Sprintf("%s", arg)))
}
b.Write([]byte(")"))
return b.String()
}