1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using System.Collections.Generic;
using System.Text;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
using Antlr4.Runtime.Tree;
namespace Antlr4.Runtime
{
/// <summary>A rule context is a record of a single rule invocation.</summary>
/// <remarks>
/// A rule context is a record of a single rule invocation. It knows
/// which context invoked it, if any. If there is no parent context, then
/// naturally the invoking state is not valid. The parent link
/// provides a chain upwards from the current rule invocation to the root
/// of the invocation tree, forming a stack. We actually carry no
/// information about the rule associated with this context (except
/// when parsing). We keep only the state number of the invoking state from
/// the ATN submachine that invoked this. Contrast this with the s
/// pointer inside ParserRuleContext that tracks the current state
/// being "executed" for the current rule.
/// The parent contexts are useful for computing lookahead sets and
/// getting error information.
/// These objects are used during parsing and prediction.
/// For the special case of parsers, we use the subclass
/// ParserRuleContext.
/// </remarks>
/// <seealso cref="ParserRuleContext"/>
public class RuleContext : IRuleNode
{
/// <summary>What context invoked this rule?</summary>
private Antlr4.Runtime.RuleContext _parent;
/// <summary>
/// What state invoked the rule associated with this context?
/// The "return address" is the followState of invokingState
/// If parent is null, this should be -1.
/// </summary>
/// <remarks>
/// What state invoked the rule associated with this context?
/// The "return address" is the followState of invokingState
/// If parent is null, this should be -1.
/// </remarks>
public int invokingState = -1;
public RuleContext()
{
}
public RuleContext(Antlr4.Runtime.RuleContext parent, int invokingState)
{
this._parent = parent;
//if ( parent!=null ) System.out.println("invoke "+stateNumber+" from "+parent);
this.invokingState = invokingState;
}
public static Antlr4.Runtime.RuleContext GetChildContext(Antlr4.Runtime.RuleContext parent, int invokingState)
{
return new Antlr4.Runtime.RuleContext(parent, invokingState);
}
public virtual int Depth()
{
int n = 0;
Antlr4.Runtime.RuleContext p = this;
while (p != null)
{
p = p._parent;
n++;
}
return n;
}
/// <summary>
/// A context is empty if there is no invoking state; meaning nobody call
/// current context.
/// </summary>
/// <remarks>
/// A context is empty if there is no invoking state; meaning nobody call
/// current context.
/// </remarks>
public virtual bool IsEmpty
{
get
{
return invokingState == -1;
}
}
public virtual Interval SourceInterval
{
get
{
// satisfy the ParseTree / SyntaxTree interface
return Interval.Invalid;
}
}
RuleContext IRuleNode.RuleContext
{
get
{
return this;
}
}
public virtual Antlr4.Runtime.RuleContext Parent
{
get
{
return _parent;
}
set
{
_parent = value;
}
}
IRuleNode IRuleNode.Parent
{
get
{
return Parent;
}
}
IParseTree IParseTree.Parent
{
get
{
return Parent;
}
}
ITree ITree.Parent
{
get
{
return Parent;
}
}
public virtual Antlr4.Runtime.RuleContext Payload
{
get
{
return this;
}
}
object ITree.Payload
{
get
{
return Payload;
}
}
/// <summary>Return the combined text of all child nodes.</summary>
/// <remarks>
/// Return the combined text of all child nodes. This method only considers
/// tokens which have been added to the parse tree.
/// <p/>
/// Since tokens on hidden channels (e.g. whitespace or comments) are not
/// added to the parse trees, they will not appear in the output of this
/// method.
/// </remarks>
public virtual string GetText()
{
if (ChildCount == 0)
{
return string.Empty;
}
StringBuilder builder = new StringBuilder();
for (int i = 0; i < ChildCount; i++)
{
builder.Append(GetChild(i).GetText());
}
return builder.ToString();
}
public virtual int RuleIndex
{
get
{
return -1;
}
}
/* For rule associated with this parse tree internal node, return
* the outer alternative number used to match the input. Default
* implementation does not compute nor store this alt num. Create
* a subclass of ParserRuleContext with backing field and set
* option contextSuperClass.
* to set it.
*/
public virtual int getAltNumber() { return Atn.ATN.INVALID_ALT_NUMBER; }
/* Set the outer alternative number for this context node. Default
* implementation does nothing to avoid backing field overhead for
* trees that don't need it. Create
* a subclass of ParserRuleContext with backing field and set
* option contextSuperClass.
*/
public virtual void setAltNumber(int altNumber) { }
public virtual IParseTree GetChild(int i)
{
return null;
}
ITree ITree.GetChild(int i)
{
return GetChild(i);
}
public virtual int ChildCount
{
get
{
return 0;
}
}
public virtual T Accept<T>(IParseTreeVisitor<T> visitor)
{
return visitor.VisitChildren(this);
}
/// <summary>
/// Print out a whole tree, not just a node, in LISP format
/// (root child1 ..
/// </summary>
/// <remarks>
/// Print out a whole tree, not just a node, in LISP format
/// (root child1 .. childN). Print just a node if this is a leaf.
/// We have to know the recognizer so we can get rule names.
/// </remarks>
public virtual string ToStringTree(Parser recog)
{
return Trees.ToStringTree(this, recog);
}
/// <summary>
/// Print out a whole tree, not just a node, in LISP format
/// (root child1 ..
/// </summary>
/// <remarks>
/// Print out a whole tree, not just a node, in LISP format
/// (root child1 .. childN). Print just a node if this is a leaf.
/// </remarks>
public virtual string ToStringTree(IList<string> ruleNames)
{
return Trees.ToStringTree(this, ruleNames);
}
public virtual string ToStringTree()
{
return ToStringTree((IList<string>)null);
}
public override string ToString()
{
return ToString((IList<string>)null, (Antlr4.Runtime.RuleContext)null);
}
public string ToString(IRecognizer recog)
{
return ToString(recog, ParserRuleContext.EmptyContext);
}
public string ToString(IList<string> ruleNames)
{
return ToString(ruleNames, null);
}
// recog null unless ParserRuleContext, in which case we use subclass toString(...)
public virtual string ToString(IRecognizer recog, Antlr4.Runtime.RuleContext stop)
{
string[] ruleNames = recog != null ? recog.RuleNames : null;
IList<string> ruleNamesList = ruleNames != null ? Arrays.AsList(ruleNames) : null;
return ToString(ruleNamesList, stop);
}
public virtual string ToString(IList<string> ruleNames, Antlr4.Runtime.RuleContext stop)
{
StringBuilder buf = new StringBuilder();
Antlr4.Runtime.RuleContext p = this;
buf.Append("[");
while (p != null && p != stop)
{
if (ruleNames == null)
{
if (!p.IsEmpty)
{
buf.Append(p.invokingState);
}
}
else
{
int ruleIndex = p.RuleIndex;
string ruleName = ruleIndex >= 0 && ruleIndex < ruleNames.Count ? ruleNames[ruleIndex] : ruleIndex.ToString();
buf.Append(ruleName);
}
if (p.Parent != null && (ruleNames != null || !p.Parent.IsEmpty))
{
buf.Append(" ");
}
p = p.Parent;
}
buf.Append("]");
return buf.ToString();
}
}
}