-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathRuleContext.js
157 lines (135 loc) · 4.63 KB
/
RuleContext.js
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
/* 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.
*/
///
// 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.
//
// @see ParserRuleContext
///
var RuleNode = require('./tree/Tree').RuleNode;
var INVALID_INTERVAL = require('./tree/Tree').INVALID_INTERVAL;
var INVALID_ALT_NUMBER = require('./atn/ATN').INVALID_ALT_NUMBER;
function RuleContext(parent, invokingState) {
RuleNode.call(this);
// What context invoked this rule?
this.parentCtx = parent || null;
// 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.
this.invokingState = invokingState || -1;
return this;
}
RuleContext.prototype = Object.create(RuleNode.prototype);
RuleContext.prototype.constructor = RuleContext;
RuleContext.prototype.depth = function() {
var n = 0;
var p = this;
while (p !== null) {
p = p.parentCtx;
n += 1;
}
return n;
};
// A context is empty if there is no invoking state; meaning nobody call
// current context.
RuleContext.prototype.isEmpty = function() {
return this.invokingState === -1;
};
// satisfy the ParseTree / SyntaxTree interface
RuleContext.prototype.getSourceInterval = function() {
return INVALID_INTERVAL;
};
RuleContext.prototype.getRuleContext = function() {
return this;
};
RuleContext.prototype.getPayload = function() {
return this;
};
// 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.
// /
RuleContext.prototype.getText = function() {
if (this.getChildCount() === 0) {
return "";
} else {
return this.children.map(function(child) {
return child.getText();
}).join("");
}
};
// 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.
RuleContext.prototype.getAltNumber = function() { return 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.
RuleContext.prototype.setAltNumber = function(altNumber) { }
RuleContext.prototype.getChild = function(i) {
return null;
};
RuleContext.prototype.getChildCount = function() {
return 0;
};
RuleContext.prototype.accept = function(visitor) {
return visitor.visitChildren(this);
};
//need to manage circular dependencies, so export now
exports.RuleContext = RuleContext;
var Trees = require('./tree/Trees').Trees;
// Print out a whole tree, not just a node, in LISP format
// (root child1 .. childN). Print just a node if this is a leaf.
//
RuleContext.prototype.toStringTree = function(ruleNames, recog) {
return Trees.toStringTree(this, ruleNames, recog);
};
RuleContext.prototype.toString = function(ruleNames, stop) {
ruleNames = ruleNames || null;
stop = stop || null;
var p = this;
var s = "[";
while (p !== null && p !== stop) {
if (ruleNames === null) {
if (!p.isEmpty()) {
s += p.invokingState;
}
} else {
var ri = p.ruleIndex;
var ruleName = (ri >= 0 && ri < ruleNames.length) ? ruleNames[ri]
: "" + ri;
s += ruleName;
}
if (p.parentCtx !== null && (ruleNames !== null || !p.parentCtx.isEmpty())) {
s += " ";
}
p = p.parentCtx;
}
s += "]";
return s;
};