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  */
5 
6 
7 /// A rule context is a record of a single rule invocation.
8 ///
9 /// We form a stack of these context objects using the parent
10 /// pointer. A parent pointer of null indicates that the current
11 /// context is the bottom of the stack. The ParserRuleContext subclass
12 /// as a children list so that we can turn this data structure into a
13 /// tree.
14 ///
15 /// The root node always has a null pointer and invokingState of -1.
16 ///
17 /// Upon entry to parsing, the first invoked rule function creates a
18 /// context object (asubclass specialized for that rule such as
19 /// SContext) and makes it the root of a parse tree, recorded by field
20 /// Parser._ctx.
21 ///
22 /// public final SContext s() throws RecognitionException {
23 /// SContext _localctx = new SContext(_ctx, getState()); <-- create new node
24 /// enterRule(_localctx, 0, RULE_s);                     <-- push it
25 /// ...
26 /// exitRule();                                          <-- pop back to _localctx
27 /// return _localctx;
28 /// }
29 ///
30 /// A subsequent rule invocation of r from the start rule s pushes a
31 /// new context object for r whose parent points at s and use invoking
32 /// state is the state with r emanating as edge label.
33 ///
34 /// The invokingState fields from a context object to the root
35 /// together form a stack of rule indication states where the root
36 /// (bottom of the stack) has a -1 sentinel value. If we invoke start
37 /// symbol s then call r1, which calls r2, the  would look like
38 /// this:
39 ///
40 /// SContext[-1]   <- root node (bottom of the stack)
41 /// R1Context[p]   <- p in rule s called r1
42 /// R2Context[q]   <- q in rule r1 called r2
43 ///
44 /// So the top of the stack, _ctx, represents a call to the current
45 /// rule and it holds the return address from another rule that invoke
46 /// to this rule. To invoke a rule, we must always have a current context.
47 ///
48 /// The parent contexts are useful for computing lookahead sets and
49 /// getting error information.
50 ///
51 /// These objects are used during parsing and prediction.
52 /// For the special case of parsers, we use the subclass
53 /// ParserRuleContext.
54 ///
55 /// - SeeAlso: org.antlr.v4.runtime.ParserRuleContext
56 ///
57 
58 open class RuleContext: RuleNode {
59     public static let EMPTY = ParserRuleContext()
60 
61     /// What context invoked this rule?
62     public weak var parent: RuleContext?
63 
64     /// What state invoked the rule associated with this context?
65     /// The "return address" is the followState of invokingState
66     /// If parent is null, this should be -1 this context object represents
67     /// the start rule.
68     ///
69     public var invokingState = -1
70 
71     public init() {
72     }
73 
74     public init(_ parent: RuleContext?, _ invokingState: Int) {
75         self.parent = parent
76         //if ( parent!=null ) { print("invoke "+stateNumber+" from "+parent)}
77         self.invokingState = invokingState
78     }
79 
depthnull80     open func depth() -> Int {
81         var n = 0
82         var p: RuleContext? = self
83         while let pWrap = p {
84             p = pWrap.parent
85             n += 1
86         }
87         return n
88     }
89 
90     /// A context is empty if there is no invoking state; meaning nobody called
91     /// current context.
92     ///
isEmptynull93     open func isEmpty() -> Bool {
94         return invokingState == -1
95     }
96 
97     // satisfy the ParseTree / SyntaxTree interface
98 
getSourceIntervalnull99     open func getSourceInterval() -> Interval {
100         return Interval.INVALID
101     }
102 
getRuleContextnull103     open func getRuleContext() -> RuleContext {
104         return self
105     }
106 
getParentnull107     open func getParent() -> Tree? {
108         return parent
109     }
110 
setParentnull111     open func setParent(_ parent: RuleContext) {
112         self.parent = parent
113     }
114 
getPayloadnull115     open func getPayload() -> AnyObject {
116         return self
117     }
118 
119     /// Return the combined text of all child nodes. This method only considers
120     /// tokens which have been added to the parse tree.
121     ///
122     /// Since tokens on hidden channels (e.g. whitespace or comments) are not
123     /// added to the parse trees, they will not appear in the output of this
124     /// method.
125     ///
126 
getTextnull127     open func getText() -> String {
128         let length = getChildCount()
129         if length == 0 {
130             return ""
131         }
132 
133         var builder = ""
134         for i in 0..<length {
135             builder += self[i].getText()
136         }
137 
138         return builder
139     }
140 
getRuleIndexnull141     open func getRuleIndex() -> Int {
142         return -1
143     }
144 
getAltNumbernull145     open func getAltNumber() -> Int { return ATN.INVALID_ALT_NUMBER }
setAltNumbernull146     open func setAltNumber(_ altNumber: Int) { }
147 
getChildnull148     open func getChild(_ i: Int) -> Tree? {
149         return nil
150     }
151 
152 
getChildCountnull153     open func getChildCount() -> Int {
154         return 0
155     }
156 
157 
158     open subscript(index: Int) -> ParseTree {
159         preconditionFailure("Index out of range (RuleContext never has children, though its subclasses may).")
160     }
161 
162 
accept<T>null163     open func accept<T>(_ visitor: ParseTreeVisitor<T>) -> T? {
164         return visitor.visitChildren(self)
165     }
166 
167     /// Print out a whole tree, not just a node, in LISP format
168     /// (root child1 .. childN). Print just a node if this is a leaf.
169     /// We have to know the recognizer so we can get rule names.
170     ///
toStringTreenull171     open func toStringTree(_ recog: Parser) -> String {
172         return Trees.toStringTree(self, recog)
173     }
174 
175     /// Print out a whole tree, not just a node, in LISP format
176     /// (root child1 .. childN). Print just a node if this is a leaf.
177     ///
toStringTreenull178     public func toStringTree(_ ruleNames: [String]?) -> String {
179         return Trees.toStringTree(self, ruleNames)
180     }
181 
toStringTreenull182     open func toStringTree() -> String {
183         return toStringTree(nil)
184     }
185 
186     open var description: String {
187         return toString(nil, nil)
188     }
189 
190      open var debugDescription: String {
191          return description
192     }
193 
toString<T>null194     public final func toString<T>(_ recog: Recognizer<T>) -> String {
195         return toString(recog, ParserRuleContext.EMPTY)
196     }
197 
toStringnull198     public final func toString(_ ruleNames: [String]) -> String {
199         return toString(ruleNames, nil)
200     }
201 
202     // recog null unless ParserRuleContext, in which case we use subclass toString(...)
toString<T>null203     open func toString<T>(_ recog: Recognizer<T>?, _ stop: RuleContext) -> String {
204         let ruleNames = recog?.getRuleNames()
205         return toString(ruleNames, stop)
206     }
207 
toStringnull208     open func toString(_ ruleNames: [String]?, _ stop: RuleContext?) -> String {
209         var buf = ""
210         var p: RuleContext? = self
211         buf += "["
212         while let pWrap = p, pWrap !== stop {
213             if let ruleNames = ruleNames {
214                 let ruleIndex = pWrap.getRuleIndex()
215                 let ruleIndexInRange = (ruleIndex >= 0 && ruleIndex < ruleNames.count)
216                 let ruleName = (ruleIndexInRange ? ruleNames[ruleIndex] : String(ruleIndex))
217                 buf += ruleName
218             }
219             else {
220                 if !pWrap.isEmpty() {
221                     buf += String(pWrap.invokingState)
222                 }
223             }
224 
225             if pWrap.parent != nil && (ruleNames != nil || !pWrap.parent!.isEmpty()) {
226                 buf += " "
227             }
228 
229             p = pWrap.parent
230         }
231 
232         buf += "]"
233         return buf
234     }
235 
castdown<T>null236     open func castdown<T>(_ subType: T.Type) -> T {
237         return self as! T
238     }
239 
240 }
241