1package ast 2 3import ( 4 "bytes" 5 "fmt" 6) 7 8type Node struct { 9 Parent *Node 10 Children []*Node 11 Value interface{} 12 Kind Kind 13} 14 15func NewNode(k Kind, v interface{}, ch ...*Node) *Node { 16 n := &Node{ 17 Kind: k, 18 Value: v, 19 } 20 for _, c := range ch { 21 Insert(n, c) 22 } 23 return n 24} 25 26func (a *Node) Equal(b *Node) bool { 27 if a.Kind != b.Kind { 28 return false 29 } 30 if a.Value != b.Value { 31 return false 32 } 33 if len(a.Children) != len(b.Children) { 34 return false 35 } 36 for i, c := range a.Children { 37 if !c.Equal(b.Children[i]) { 38 return false 39 } 40 } 41 return true 42} 43 44func (a *Node) String() string { 45 var buf bytes.Buffer 46 buf.WriteString(a.Kind.String()) 47 if a.Value != nil { 48 buf.WriteString(" =") 49 buf.WriteString(fmt.Sprintf("%v", a.Value)) 50 } 51 if len(a.Children) > 0 { 52 buf.WriteString(" [") 53 for i, c := range a.Children { 54 if i > 0 { 55 buf.WriteString(", ") 56 } 57 buf.WriteString(c.String()) 58 } 59 buf.WriteString("]") 60 } 61 return buf.String() 62} 63 64func Insert(parent *Node, children ...*Node) { 65 parent.Children = append(parent.Children, children...) 66 for _, ch := range children { 67 ch.Parent = parent 68 } 69} 70 71type List struct { 72 Not bool 73 Chars string 74} 75 76type Range struct { 77 Not bool 78 Lo, Hi rune 79} 80 81type Text struct { 82 Text string 83} 84 85type Kind int 86 87const ( 88 KindNothing Kind = iota 89 KindPattern 90 KindList 91 KindRange 92 KindText 93 KindAny 94 KindSuper 95 KindSingle 96 KindAnyOf 97) 98 99func (k Kind) String() string { 100 switch k { 101 case KindNothing: 102 return "Nothing" 103 case KindPattern: 104 return "Pattern" 105 case KindList: 106 return "List" 107 case KindRange: 108 return "Range" 109 case KindText: 110 return "Text" 111 case KindAny: 112 return "Any" 113 case KindSuper: 114 return "Super" 115 case KindSingle: 116 return "Single" 117 case KindAnyOf: 118 return "AnyOf" 119 default: 120 return "" 121 } 122} 123