1// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. 2// Use of this file is governed by the BSD 3-clause license that 3// can be found in the LICENSE.txt file in the project root. 4 5package antlr 6 7import ( 8 "reflect" 9 "strconv" 10) 11 12type ParserRuleContext interface { 13 RuleContext 14 15 SetException(RecognitionException) 16 17 AddTokenNode(token Token) *TerminalNodeImpl 18 AddErrorNode(badToken Token) *ErrorNodeImpl 19 20 EnterRule(listener ParseTreeListener) 21 ExitRule(listener ParseTreeListener) 22 23 SetStart(Token) 24 GetStart() Token 25 26 SetStop(Token) 27 GetStop() Token 28 29 AddChild(child RuleContext) RuleContext 30 RemoveLastChild() 31} 32 33type BaseParserRuleContext struct { 34 *BaseRuleContext 35 36 start, stop Token 37 exception RecognitionException 38 children []Tree 39} 40 41func NewBaseParserRuleContext(parent ParserRuleContext, invokingStateNumber int) *BaseParserRuleContext { 42 prc := new(BaseParserRuleContext) 43 44 prc.BaseRuleContext = NewBaseRuleContext(parent, invokingStateNumber) 45 46 prc.RuleIndex = -1 47 // * If we are debugging or building a parse tree for a Visitor, 48 // we need to track all of the tokens and rule invocations associated 49 // with prc rule's context. This is empty for parsing w/o tree constr. 50 // operation because we don't the need to track the details about 51 // how we parse prc rule. 52 // / 53 prc.children = nil 54 prc.start = nil 55 prc.stop = nil 56 // The exception that forced prc rule to return. If the rule successfully 57 // completed, prc is {@code nil}. 58 prc.exception = nil 59 60 return prc 61} 62 63func (prc *BaseParserRuleContext) SetException(e RecognitionException) { 64 prc.exception = e 65} 66 67func (prc *BaseParserRuleContext) GetChildren() []Tree { 68 return prc.children 69} 70 71func (prc *BaseParserRuleContext) CopyFrom(ctx *BaseParserRuleContext) { 72 // from RuleContext 73 prc.parentCtx = ctx.parentCtx 74 prc.invokingState = ctx.invokingState 75 prc.children = nil 76 prc.start = ctx.start 77 prc.stop = ctx.stop 78} 79 80func (prc *BaseParserRuleContext) GetText() string { 81 if prc.GetChildCount() == 0 { 82 return "" 83 } 84 85 var s string 86 for _, child := range prc.children { 87 s += child.(ParseTree).GetText() 88 } 89 90 return s 91} 92 93// Double dispatch methods for listeners 94func (prc *BaseParserRuleContext) EnterRule(listener ParseTreeListener) { 95} 96 97func (prc *BaseParserRuleContext) ExitRule(listener ParseTreeListener) { 98} 99 100// * Does not set parent link other add methods do that/// 101func (prc *BaseParserRuleContext) addTerminalNodeChild(child TerminalNode) TerminalNode { 102 if prc.children == nil { 103 prc.children = make([]Tree, 0) 104 } 105 if child == nil { 106 panic("Child may not be null") 107 } 108 prc.children = append(prc.children, child) 109 return child 110} 111 112func (prc *BaseParserRuleContext) AddChild(child RuleContext) RuleContext { 113 if prc.children == nil { 114 prc.children = make([]Tree, 0) 115 } 116 if child == nil { 117 panic("Child may not be null") 118 } 119 prc.children = append(prc.children, child) 120 return child 121} 122 123// * Used by EnterOuterAlt to toss out a RuleContext previously added as 124// we entered a rule. If we have // label, we will need to remove 125// generic ruleContext object. 126// / 127func (prc *BaseParserRuleContext) RemoveLastChild() { 128 if prc.children != nil && len(prc.children) > 0 { 129 prc.children = prc.children[0 : len(prc.children)-1] 130 } 131} 132 133func (prc *BaseParserRuleContext) AddTokenNode(token Token) *TerminalNodeImpl { 134 135 node := NewTerminalNodeImpl(token) 136 prc.addTerminalNodeChild(node) 137 node.parentCtx = prc 138 return node 139 140} 141 142func (prc *BaseParserRuleContext) AddErrorNode(badToken Token) *ErrorNodeImpl { 143 node := NewErrorNodeImpl(badToken) 144 prc.addTerminalNodeChild(node) 145 node.parentCtx = prc 146 return node 147} 148 149func (prc *BaseParserRuleContext) GetChild(i int) Tree { 150 if prc.children != nil && len(prc.children) >= i { 151 return prc.children[i] 152 } 153 154 return nil 155} 156 157func (prc *BaseParserRuleContext) GetChildOfType(i int, childType reflect.Type) RuleContext { 158 if childType == nil { 159 return prc.GetChild(i).(RuleContext) 160 } 161 162 for j := 0; j < len(prc.children); j++ { 163 child := prc.children[j] 164 if reflect.TypeOf(child) == childType { 165 if i == 0 { 166 return child.(RuleContext) 167 } 168 169 i-- 170 } 171 } 172 173 return nil 174} 175 176func (prc *BaseParserRuleContext) ToStringTree(ruleNames []string, recog Recognizer) string { 177 return TreesStringTree(prc, ruleNames, recog) 178} 179 180func (prc *BaseParserRuleContext) GetRuleContext() RuleContext { 181 return prc 182} 183 184func (prc *BaseParserRuleContext) Accept(visitor ParseTreeVisitor) interface{} { 185 return visitor.VisitChildren(prc) 186} 187 188func (prc *BaseParserRuleContext) SetStart(t Token) { 189 prc.start = t 190} 191 192func (prc *BaseParserRuleContext) GetStart() Token { 193 return prc.start 194} 195 196func (prc *BaseParserRuleContext) SetStop(t Token) { 197 prc.stop = t 198} 199 200func (prc *BaseParserRuleContext) GetStop() Token { 201 return prc.stop 202} 203 204func (prc *BaseParserRuleContext) GetToken(ttype int, i int) TerminalNode { 205 206 for j := 0; j < len(prc.children); j++ { 207 child := prc.children[j] 208 if c2, ok := child.(TerminalNode); ok { 209 if c2.GetSymbol().GetTokenType() == ttype { 210 if i == 0 { 211 return c2 212 } 213 214 i-- 215 } 216 } 217 } 218 return nil 219} 220 221func (prc *BaseParserRuleContext) GetTokens(ttype int) []TerminalNode { 222 if prc.children == nil { 223 return make([]TerminalNode, 0) 224 } 225 226 tokens := make([]TerminalNode, 0) 227 228 for j := 0; j < len(prc.children); j++ { 229 child := prc.children[j] 230 if tchild, ok := child.(TerminalNode); ok { 231 if tchild.GetSymbol().GetTokenType() == ttype { 232 tokens = append(tokens, tchild) 233 } 234 } 235 } 236 237 return tokens 238} 239 240func (prc *BaseParserRuleContext) GetPayload() interface{} { 241 return prc 242} 243 244func (prc *BaseParserRuleContext) getChild(ctxType reflect.Type, i int) RuleContext { 245 if prc.children == nil || i < 0 || i >= len(prc.children) { 246 return nil 247 } 248 249 j := -1 // what element have we found with ctxType? 250 for _, o := range prc.children { 251 252 childType := reflect.TypeOf(o) 253 254 if childType.Implements(ctxType) { 255 j++ 256 if j == i { 257 return o.(RuleContext) 258 } 259 } 260 } 261 return nil 262} 263 264// Go lacks generics, so it's not possible for us to return the child with the correct type, but we do 265// check for convertibility 266 267func (prc *BaseParserRuleContext) GetTypedRuleContext(ctxType reflect.Type, i int) RuleContext { 268 return prc.getChild(ctxType, i) 269} 270 271func (prc *BaseParserRuleContext) GetTypedRuleContexts(ctxType reflect.Type) []RuleContext { 272 if prc.children == nil { 273 return make([]RuleContext, 0) 274 } 275 276 contexts := make([]RuleContext, 0) 277 278 for _, child := range prc.children { 279 childType := reflect.TypeOf(child) 280 281 if childType.ConvertibleTo(ctxType) { 282 contexts = append(contexts, child.(RuleContext)) 283 } 284 } 285 return contexts 286} 287 288func (prc *BaseParserRuleContext) GetChildCount() int { 289 if prc.children == nil { 290 return 0 291 } 292 293 return len(prc.children) 294} 295 296func (prc *BaseParserRuleContext) GetSourceInterval() *Interval { 297 if prc.start == nil || prc.stop == nil { 298 return TreeInvalidInterval 299 } 300 301 return NewInterval(prc.start.GetTokenIndex(), prc.stop.GetTokenIndex()) 302} 303 304//need to manage circular dependencies, so export now 305 306// Print out a whole tree, not just a node, in LISP format 307// (root child1 .. childN). Print just a node if b is a leaf. 308// 309 310func (prc *BaseParserRuleContext) String(ruleNames []string, stop RuleContext) string { 311 312 var p ParserRuleContext = prc 313 s := "[" 314 for p != nil && p != stop { 315 if ruleNames == nil { 316 if !p.IsEmpty() { 317 s += strconv.Itoa(p.GetInvokingState()) 318 } 319 } else { 320 ri := p.GetRuleIndex() 321 var ruleName string 322 if ri >= 0 && ri < len(ruleNames) { 323 ruleName = ruleNames[ri] 324 } else { 325 ruleName = strconv.Itoa(ri) 326 } 327 s += ruleName 328 } 329 if p.GetParent() != nil && (ruleNames != nil || !p.GetParent().(ParserRuleContext).IsEmpty()) { 330 s += " " 331 } 332 pi := p.GetParent() 333 if pi != nil { 334 p = pi.(ParserRuleContext) 335 } else { 336 p = nil 337 } 338 } 339 s += "]" 340 return s 341} 342 343var RuleContextEmpty = NewBaseParserRuleContext(nil, -1) 344 345type InterpreterRuleContext interface { 346 ParserRuleContext 347} 348 349type BaseInterpreterRuleContext struct { 350 *BaseParserRuleContext 351} 352 353func NewBaseInterpreterRuleContext(parent BaseInterpreterRuleContext, invokingStateNumber, ruleIndex int) *BaseInterpreterRuleContext { 354 355 prc := new(BaseInterpreterRuleContext) 356 357 prc.BaseParserRuleContext = NewBaseParserRuleContext(parent, invokingStateNumber) 358 359 prc.RuleIndex = ruleIndex 360 361 return prc 362} 363