terraform/vendor/github.com/ChrisTrenkamp/goxpath/parser/ast.go

114 lines
2.2 KiB
Go

package parser
import "github.com/ChrisTrenkamp/goxpath/lexer"
//NodeType enumerations
const (
Empty lexer.XItemType = ""
)
//Node builds an AST tree for operating on XPath expressions
type Node struct {
Val lexer.XItem
Left *Node
Right *Node
Parent *Node
next *Node
}
var beginPathType = map[lexer.XItemType]bool{
lexer.XItemAbsLocPath: true,
lexer.XItemAbbrAbsLocPath: true,
lexer.XItemAbbrRelLocPath: true,
lexer.XItemRelLocPath: true,
lexer.XItemFunction: true,
}
func (n *Node) add(i lexer.XItem) {
if n.Val.Typ == Empty {
n.Val = i
} else if n.Left == nil && n.Right == nil {
n.Left = &Node{Val: n.Val, Parent: n}
n.Val = i
} else if beginPathType[n.Val.Typ] {
next := &Node{Val: n.Val, Left: n.Left, Right: n.Right, Parent: n}
n.Left, n.Right = next, nil
n.Val = i
} else if n.Right == nil {
n.Right = &Node{Val: i, Parent: n}
} else {
next := &Node{Val: n.Val, Left: n.Left, Right: n.Right, Parent: n}
n.Left, n.Right = next, nil
n.Val = i
}
n.next = n
}
func (n *Node) push(i lexer.XItem) {
if n.Left == nil {
n.Left = &Node{Val: i, Parent: n}
n.next = n.Left
} else if n.Right == nil {
n.Right = &Node{Val: i, Parent: n}
n.next = n.Right
} else {
next := &Node{Val: i, Left: n.Right, Parent: n}
n.Right = next
n.next = n.Right
}
}
func (n *Node) pushNotEmpty(i lexer.XItem) {
if n.Val.Typ == Empty {
n.add(i)
} else {
n.push(i)
}
}
/*
func (n *Node) prettyPrint(depth, width int) {
nodes := []*Node{}
n.getLine(depth, &nodes)
fmt.Printf("%*s", (width-depth)*2, "")
toggle := true
if len(nodes) > 1 {
for _, i := range nodes {
if i != nil {
if toggle {
fmt.Print("/ ")
} else {
fmt.Print("\\ ")
}
}
toggle = !toggle
}
fmt.Println()
fmt.Printf("%*s", (width-depth)*2, "")
}
for _, i := range nodes {
if i != nil {
fmt.Print(i.Val.Val, " ")
}
}
fmt.Println()
}
func (n *Node) getLine(depth int, ret *[]*Node) {
if depth <= 0 && n != nil {
*ret = append(*ret, n)
return
}
if n.Left != nil {
n.Left.getLine(depth-1, ret)
} else if depth-1 <= 0 {
*ret = append(*ret, nil)
}
if n.Right != nil {
n.Right.getLine(depth-1, ret)
} else if depth-1 <= 0 {
*ret = append(*ret, nil)
}
}
*/