github.com/jhump/protocompile@v0.0.0-20221021153901-4f6f732835e8/parser/ast.go (about) 1 package parser 2 3 import "github.com/jhump/protocompile/ast" 4 5 // the types below are accumulator types: linked lists that are 6 // constructed during parsing and then converted to slices of AST nodes 7 // once the whole list has been parsed 8 // TODO: change grammer to use slices of nodes instead of these constructions 9 10 type compactOptionList struct { 11 option *ast.OptionNode 12 comma *ast.RuneNode 13 next *compactOptionList 14 } 15 16 func (list *compactOptionList) toNodes() ([]*ast.OptionNode, []*ast.RuneNode) { 17 l := 0 18 for cur := list; cur != nil; cur = cur.next { 19 l++ 20 } 21 opts := make([]*ast.OptionNode, l) 22 commas := make([]*ast.RuneNode, l-1) 23 for cur, i := list, 0; cur != nil; cur, i = cur.next, i+1 { 24 opts[i] = cur.option 25 if cur.comma != nil { 26 commas[i] = cur.comma 27 } 28 } 29 return opts, commas 30 } 31 32 type stringList struct { 33 str *ast.StringLiteralNode 34 next *stringList 35 } 36 37 func (list *stringList) toStringValueNode() ast.StringValueNode { 38 if list.next == nil { 39 // single name 40 return list.str 41 } 42 43 l := 0 44 for cur := list; cur != nil; cur = cur.next { 45 l++ 46 } 47 strs := make([]*ast.StringLiteralNode, l) 48 for cur, i := list, 0; cur != nil; cur, i = cur.next, i+1 { 49 strs[i] = cur.str 50 } 51 return ast.NewCompoundLiteralStringNode(strs...) 52 } 53 54 type nameList struct { 55 name ast.StringValueNode 56 comma *ast.RuneNode 57 next *nameList 58 } 59 60 func (list *nameList) toNodes() ([]ast.StringValueNode, []*ast.RuneNode) { 61 l := 0 62 for cur := list; cur != nil; cur = cur.next { 63 l++ 64 } 65 names := make([]ast.StringValueNode, l) 66 commas := make([]*ast.RuneNode, l-1) 67 for cur, i := list, 0; cur != nil; cur, i = cur.next, i+1 { 68 names[i] = cur.name 69 if cur.comma != nil { 70 commas[i] = cur.comma 71 } 72 } 73 return names, commas 74 } 75 76 type rangeList struct { 77 rng *ast.RangeNode 78 comma *ast.RuneNode 79 next *rangeList 80 } 81 82 func (list *rangeList) toNodes() ([]*ast.RangeNode, []*ast.RuneNode) { 83 l := 0 84 for cur := list; cur != nil; cur = cur.next { 85 l++ 86 } 87 ranges := make([]*ast.RangeNode, l) 88 commas := make([]*ast.RuneNode, l-1) 89 for cur, i := list, 0; cur != nil; cur, i = cur.next, i+1 { 90 ranges[i] = cur.rng 91 if cur.comma != nil { 92 commas[i] = cur.comma 93 } 94 } 95 return ranges, commas 96 } 97 98 type valueList struct { 99 val ast.ValueNode 100 comma *ast.RuneNode 101 next *valueList 102 } 103 104 func (list *valueList) toNodes() ([]ast.ValueNode, []*ast.RuneNode) { 105 if list == nil { 106 return nil, nil 107 } 108 l := 0 109 for cur := list; cur != nil; cur = cur.next { 110 l++ 111 } 112 vals := make([]ast.ValueNode, l) 113 commas := make([]*ast.RuneNode, l-1) 114 for cur, i := list, 0; cur != nil; cur, i = cur.next, i+1 { 115 vals[i] = cur.val 116 if cur.comma != nil { 117 commas[i] = cur.comma 118 } 119 } 120 return vals, commas 121 } 122 123 type fieldRefList struct { 124 ref *ast.FieldReferenceNode 125 dot *ast.RuneNode 126 next *fieldRefList 127 } 128 129 func (list *fieldRefList) toNodes() ([]*ast.FieldReferenceNode, []*ast.RuneNode) { 130 l := 0 131 for cur := list; cur != nil; cur = cur.next { 132 l++ 133 } 134 refs := make([]*ast.FieldReferenceNode, l) 135 dots := make([]*ast.RuneNode, l-1) 136 for cur, i := list, 0; cur != nil; cur, i = cur.next, i+1 { 137 refs[i] = cur.ref 138 if cur.dot != nil { 139 dots[i] = cur.dot 140 } 141 } 142 143 return refs, dots 144 } 145 146 type identList struct { 147 ident *ast.IdentNode 148 dot *ast.RuneNode 149 next *identList 150 } 151 152 func (list *identList) toIdentValueNode(leadingDot *ast.RuneNode) ast.IdentValueNode { 153 if list.next == nil && leadingDot == nil { 154 // single name 155 return list.ident 156 } 157 158 l := 0 159 for cur := list; cur != nil; cur = cur.next { 160 l++ 161 } 162 idents := make([]*ast.IdentNode, l) 163 dots := make([]*ast.RuneNode, l-1) 164 for cur, i := list, 0; cur != nil; cur, i = cur.next, i+1 { 165 idents[i] = cur.ident 166 if cur.dot != nil { 167 dots[i] = cur.dot 168 } 169 } 170 171 return ast.NewCompoundIdentNode(leadingDot, idents, dots) 172 } 173 174 type messageFieldEntry struct { 175 field *ast.MessageFieldNode 176 delimiter *ast.RuneNode 177 } 178 179 type messageFieldList struct { 180 field *messageFieldEntry 181 next *messageFieldList 182 } 183 184 func (list *messageFieldList) toNodes() ([]*ast.MessageFieldNode, []*ast.RuneNode) { 185 if list == nil { 186 return nil, nil 187 } 188 l := 0 189 for cur := list; cur != nil; cur = cur.next { 190 l++ 191 } 192 fields := make([]*ast.MessageFieldNode, l) 193 delimiters := make([]*ast.RuneNode, l) 194 for cur, i := list, 0; cur != nil; cur, i = cur.next, i+1 { 195 fields[i] = cur.field.field 196 if cur.field.delimiter != nil { 197 delimiters[i] = cur.field.delimiter 198 } 199 } 200 201 return fields, delimiters 202 }