bosun.org@v0.0.0-20210513094433-e25bc3e69a1f/cmd/bosun/conf/rule/parse/node.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Parse nodes. 6 7 package parse 8 9 import ( 10 "bytes" 11 "fmt" 12 ) 13 14 var textFormat = "%s" // Changed to "%q" in tests for better error messages. 15 16 // A Node is an element in the parse tree. The interface is trivial. 17 // The interface contains an unexported method so that only 18 // types local to this package can satisfy it. 19 type Node interface { 20 Type() NodeType 21 String() string 22 Position() Pos // byte position of start of node in full original input string 23 // Make sure only functions in this package can create Nodes. 24 unexported() 25 } 26 27 // NodeType identifies the type of a parse tree node. 28 type NodeType int 29 30 // Pos represents a byte position in the original input text from which 31 // this template was parsed. 32 type Pos int 33 34 func (p Pos) Position() Pos { 35 return p 36 } 37 38 // unexported keeps Node implementations local to the package. 39 // All implementations embed Pos, so this takes care of it. 40 func (Pos) unexported() { 41 } 42 43 // Type returns itself and provides an easy default implementation 44 // for embedding in a Node. Embedded in all non-trivial Nodes. 45 func (t NodeType) Type() NodeType { 46 return t 47 } 48 49 const ( 50 NodePair NodeType = iota // key=value expression. 51 NodeList // A list of nodes. 52 NodeString // A string constant. 53 NodeSection // [section] definition. 54 ) 55 56 // Nodes. 57 58 // PairNode holds a key=value pair. 59 type PairNode struct { 60 NodeType 61 Pos 62 Key, Val *StringNode 63 } 64 65 func newPair(pos Pos) *PairNode { 66 return &PairNode{NodeType: NodePair, Pos: pos} 67 } 68 69 func (p *PairNode) String() string { 70 return fmt.Sprintf("%s = %s", p.Key, p.Val) 71 } 72 73 // ListNode holds a sequence of nodes. 74 type ListNode struct { 75 NodeType 76 Pos 77 Nodes []Node // The element nodes in lexical order. 78 } 79 80 func newList(pos Pos) *ListNode { 81 return &ListNode{NodeType: NodeList, Pos: pos} 82 } 83 84 func (l *ListNode) append(n Node) { 85 l.Nodes = append(l.Nodes, n) 86 } 87 88 func (l *ListNode) String() string { 89 b := new(bytes.Buffer) 90 for _, n := range l.Nodes { 91 fmt.Fprintln(b, n) 92 } 93 return b.String() 94 } 95 96 // SectionNode holds a section name and children 97 type SectionNode struct { 98 NodeType 99 Pos 100 RawText string 101 SectionType *StringNode 102 Name *StringNode 103 Nodes *ListNode 104 } 105 106 func newSection(pos Pos) *SectionNode { 107 return &SectionNode{NodeType: NodeSection, Pos: pos, Nodes: new(ListNode)} 108 } 109 110 func (s *SectionNode) String() string { 111 return s.RawText 112 } 113 114 // StringNode holds a string constant. The value has been "unquoted". 115 type StringNode struct { 116 NodeType 117 Pos 118 Quoted string // The original text of the string, with possible quotes. 119 Text string // The string, after quote processing. 120 } 121 122 func newString(pos Pos, orig, text string) *StringNode { 123 return &StringNode{NodeType: NodeString, Pos: pos, Quoted: orig, Text: text} 124 } 125 126 func (s *StringNode) String() string { 127 return s.Quoted 128 }