antlr4 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +27 -0
- data/README.md +46 -0
- data/lib/antlr4.rb +262 -0
- data/lib/antlr4/BufferedTokenStream.rb +306 -0
- data/lib/antlr4/CommonTokenFactory.rb +53 -0
- data/lib/antlr4/CommonTokenStream.rb +56 -0
- data/lib/antlr4/FileStream.rb +14 -0
- data/lib/antlr4/InputStream.rb +82 -0
- data/lib/antlr4/IntervalSet.rb +341 -0
- data/lib/antlr4/LL1Analyzer.rb +177 -0
- data/lib/antlr4/Lexer.rb +335 -0
- data/lib/antlr4/ListTokenSource.rb +140 -0
- data/lib/antlr4/Parser.rb +562 -0
- data/lib/antlr4/ParserInterpreter.rb +149 -0
- data/lib/antlr4/ParserRuleContext.rb +162 -0
- data/lib/antlr4/PredictionContext.rb +690 -0
- data/lib/antlr4/Recognizer.rb +162 -0
- data/lib/antlr4/RuleContext.rb +226 -0
- data/lib/antlr4/Token.rb +124 -0
- data/lib/antlr4/TokenFactory.rb +3 -0
- data/lib/antlr4/TokenSource.rb +4 -0
- data/lib/antlr4/TokenStream.rb +3 -0
- data/lib/antlr4/TraceListener.rb +23 -0
- data/lib/antlr4/atn/ATN.rb +133 -0
- data/lib/antlr4/atn/ATNConfig.rb +146 -0
- data/lib/antlr4/atn/ATNConfigSet.rb +215 -0
- data/lib/antlr4/atn/ATNDeserializationOptions.rb +62 -0
- data/lib/antlr4/atn/ATNDeserializer.rb +604 -0
- data/lib/antlr4/atn/ATNSimulator.rb +43 -0
- data/lib/antlr4/atn/ATNState.rb +253 -0
- data/lib/antlr4/atn/ATNType.rb +22 -0
- data/lib/antlr4/atn/LexerATNSimulator.rb +612 -0
- data/lib/antlr4/atn/LexerAction.rb +311 -0
- data/lib/antlr4/atn/LexerActionExecutor.rb +134 -0
- data/lib/antlr4/atn/ParserATNSimulator.rb +1622 -0
- data/lib/antlr4/atn/PredictionMode.rb +525 -0
- data/lib/antlr4/atn/SemanticContext.rb +355 -0
- data/lib/antlr4/atn/Transition.rb +297 -0
- data/lib/antlr4/base.rb +60 -0
- data/lib/antlr4/dfa/DFA.rb +128 -0
- data/lib/antlr4/dfa/DFASerializer.rb +77 -0
- data/lib/antlr4/dfa/DFAState.rb +133 -0
- data/lib/antlr4/error.rb +151 -0
- data/lib/antlr4/error/DiagnosticErrorListener.rb +136 -0
- data/lib/antlr4/error/ErrorListener.rb +109 -0
- data/lib/antlr4/error/ErrorStrategy.rb +742 -0
- data/lib/antlr4/tree/Chunk.rb +31 -0
- data/lib/antlr4/tree/ParseTreeMatch.rb +105 -0
- data/lib/antlr4/tree/ParseTreePattern.rb +70 -0
- data/lib/antlr4/tree/ParseTreePatternMatcher.rb +334 -0
- data/lib/antlr4/tree/RuleTagToken.rb +39 -0
- data/lib/antlr4/tree/TokenTagToken.rb +38 -0
- data/lib/antlr4/tree/Tree.rb +204 -0
- data/lib/antlr4/tree/Trees.rb +111 -0
- data/lib/antlr4/version.rb +5 -0
- data/lib/antlr4/xpath/XPath.rb +354 -0
- data/lib/double_key_map.rb +78 -0
- data/lib/java_symbols.rb +24 -0
- data/lib/uuid.rb +87 -0
- data/test/test_intervalset.rb +664 -0
- data/test/test_tree.rb +140 -0
- data/test/test_uuid.rb +122 -0
- metadata +109 -0
@@ -0,0 +1,355 @@
|
|
1
|
+
# A tree structure used to record the semantic context in which
|
2
|
+
# an ATN configuration is valid. It's either a single predicate,
|
3
|
+
# a conjunction {@code p1&&p2}, or a sum of products {@code p1||p2}.
|
4
|
+
#
|
5
|
+
# <p>I have scoped the {@link AND}, {@link OR}, and {@link Predicate} subclasses of
|
6
|
+
# {@link SemanticContext} within the scope of this outer class.</p>
|
7
|
+
|
8
|
+
class SemanticContext
|
9
|
+
# The default {@link SemanticContext}, which is semantically equivalent to
|
10
|
+
# a predicate of the form {@code {true}?}.
|
11
|
+
@@NONE = nil
|
12
|
+
def self.NONE
|
13
|
+
@@NONE = SemanticContext.new if @@NONE.nil?
|
14
|
+
@@NONE
|
15
|
+
end
|
16
|
+
attr_accessor :opnds
|
17
|
+
# For context independent predicates, we evaluate them without a local
|
18
|
+
# context (i.e., null context). That way, we can evaluate them without
|
19
|
+
# having to create proper rule-specific context during prediction (as
|
20
|
+
# opposed to the parser, which creates them naturally). In a practical
|
21
|
+
# sense, this avoids a cast exception from RuleContext to myruleContext.
|
22
|
+
#
|
23
|
+
# <p>For context dependent predicates, we must pass in a local context so that
|
24
|
+
# references such as $arg evaluate properly as _localctx.arg. We only
|
25
|
+
# capture context dependent predicates in the context in which we begin
|
26
|
+
# prediction, so we passed in the outer context here in case of context
|
27
|
+
# dependent predicate evaluation.</p>
|
28
|
+
#
|
29
|
+
def eval(parser, outerContext)
|
30
|
+
end
|
31
|
+
#
|
32
|
+
# Evaluate the precedence predicates for the context and reduce the result.
|
33
|
+
#
|
34
|
+
# @param parser The parser instance.
|
35
|
+
# @param outerContext The current parser context object.
|
36
|
+
# @return The simplified semantic context after precedence predicates are
|
37
|
+
# evaluated, which will be one of the following values.
|
38
|
+
# <ul>
|
39
|
+
# <li>{@link #NONE}: if the predicate simplifies to {@code true} after
|
40
|
+
# precedence predicates are evaluated.</li>
|
41
|
+
# <li>{@code null}: if the predicate simplifies to {@code false} after
|
42
|
+
# precedence predicates are evaluated.</li>
|
43
|
+
# <li>{@code this}: if the semantic context is not changed as a result of
|
44
|
+
# precedence predicate evaluation.</li>
|
45
|
+
# <li>A non-{@code null} {@link SemanticContext}: the new simplified
|
46
|
+
# semantic context after precedence predicates are evaluated.</li>
|
47
|
+
# </ul>
|
48
|
+
#
|
49
|
+
def evalPrecedence(parser, outerContext)
|
50
|
+
return self
|
51
|
+
end
|
52
|
+
|
53
|
+
def simplify
|
54
|
+
if self.opnds.length == 1 then
|
55
|
+
self.opnds.first
|
56
|
+
else
|
57
|
+
self
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def andContext(b)
|
62
|
+
SemanticContext.andContext(self, b)
|
63
|
+
end
|
64
|
+
def self.andContext(a, b)
|
65
|
+
return b if a.nil? or a.equal? SemanticContext.NONE
|
66
|
+
return a if b.nil? or b.equal? SemanticContext.NONE
|
67
|
+
result = AND.new(a, b)
|
68
|
+
return result.simplify
|
69
|
+
end
|
70
|
+
def orContext(b)
|
71
|
+
SemanticContext.orContext(self, b)
|
72
|
+
end
|
73
|
+
def self.orContext(a, b)
|
74
|
+
return b if a.nil?
|
75
|
+
return a if b.nil?
|
76
|
+
if a.equal? SemanticContext.NONE or b.equal? SemanticContext.NONE
|
77
|
+
return SemanticContext.NONE
|
78
|
+
end
|
79
|
+
result = OR.new(a, b)
|
80
|
+
return result.simplify
|
81
|
+
end
|
82
|
+
def filterPrecedencePredicates(collection)
|
83
|
+
self.class.filterPrecedencePredicates(collection)
|
84
|
+
end
|
85
|
+
def self.filterPrecedencePredicates(collection)
|
86
|
+
collection.map {|context|
|
87
|
+
if context.kind_of? PrecedencePredicate then
|
88
|
+
context
|
89
|
+
end
|
90
|
+
}.compact
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class Predicate < SemanticContext
|
95
|
+
|
96
|
+
attr_accessor :ruleIndex, :predIndex, :isCtxDependent
|
97
|
+
def initialize(rule_index=-1, pred_index=-1, is_ctx_dependent=false)
|
98
|
+
self.ruleIndex = rule_index
|
99
|
+
self.predIndex = pred_index
|
100
|
+
self.isCtxDependent = is_ctx_dependent # e.g., $i ref in pred
|
101
|
+
end
|
102
|
+
|
103
|
+
def eval(parser, outerContext)
|
104
|
+
#localctx = outerContext if self.isCtxDependent else None
|
105
|
+
if self.isCtxDependent
|
106
|
+
localctx = outerContext
|
107
|
+
else
|
108
|
+
localctx = nil
|
109
|
+
end
|
110
|
+
return parser.sempred(localctx, self.ruleIndex, self.predIndex)
|
111
|
+
end
|
112
|
+
def hash
|
113
|
+
StringIO.open do |buf|
|
114
|
+
buf.write(self.ruleIndex.to_s)
|
115
|
+
buf.write("/")
|
116
|
+
buf.write(self.predIndex.to_s)
|
117
|
+
buf.write("/")
|
118
|
+
buf.write(self.isCtxDependent.to_s)
|
119
|
+
return buf.string().hash
|
120
|
+
end
|
121
|
+
end
|
122
|
+
def eql?(other)
|
123
|
+
self == other
|
124
|
+
end
|
125
|
+
def ==(other)
|
126
|
+
self.equal?(other)or other.kind_of?(Predicate) and \
|
127
|
+
self.ruleIndex == other.ruleIndex and \
|
128
|
+
self.predIndex == other.predIndex and \
|
129
|
+
self.isCtxDependent == other.isCtxDependent
|
130
|
+
end
|
131
|
+
def to_s
|
132
|
+
"{#{self.ruleIndex}:#{self.predIndex}}?"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
class PrecedencePredicate < SemanticContext
|
137
|
+
|
138
|
+
attr_accessor :precedence
|
139
|
+
def initialize(_precedence=0)
|
140
|
+
self.precedence = _precedence
|
141
|
+
end
|
142
|
+
|
143
|
+
def eval(parser, outer_context)
|
144
|
+
return parser.precpred(outer_context, self.precedence)
|
145
|
+
end
|
146
|
+
|
147
|
+
def evalPrecedence(parser, outer_context)
|
148
|
+
if parser.precpred(outer_context, self.precedence)
|
149
|
+
return SemanticContext.NONE
|
150
|
+
else
|
151
|
+
return nil
|
152
|
+
end
|
153
|
+
end
|
154
|
+
def <=>(other)
|
155
|
+
return self.precedence - other.precedence
|
156
|
+
end
|
157
|
+
|
158
|
+
def hash
|
159
|
+
return 31
|
160
|
+
end
|
161
|
+
|
162
|
+
def eql?(other)
|
163
|
+
self == other
|
164
|
+
end
|
165
|
+
def ==(other)
|
166
|
+
self.equal?(other) or (other.kind_of?(PrecedencePredicate) and self.precedence == other.precedence )
|
167
|
+
end
|
168
|
+
end
|
169
|
+
# A semantic context which is true whenever none of the contained contexts
|
170
|
+
# is false.
|
171
|
+
#
|
172
|
+
class AND < SemanticContext
|
173
|
+
|
174
|
+
def initialize(a, b)
|
175
|
+
operands = Set.new()
|
176
|
+
if a.kind_of? AND then
|
177
|
+
a.opnds.each {|o| operands.add(o) }
|
178
|
+
else
|
179
|
+
operands.add(a)
|
180
|
+
end
|
181
|
+
if b.kind_of? AND then
|
182
|
+
b.opnds.each {|o| operands.add(o) }
|
183
|
+
else
|
184
|
+
operands.add(b)
|
185
|
+
end
|
186
|
+
precedencePredicates = filterPrecedencePredicates(operands)
|
187
|
+
if precedencePredicates.length>0 then
|
188
|
+
# interested in the transition with the lowest precedence
|
189
|
+
reduced = precedencePredicates.min
|
190
|
+
operands.add(reduced)
|
191
|
+
end
|
192
|
+
@opnds = operands.to_a
|
193
|
+
end
|
194
|
+
|
195
|
+
def eql?(other)
|
196
|
+
self == other
|
197
|
+
end
|
198
|
+
def ==(other)
|
199
|
+
self.equal?(other) or \
|
200
|
+
( other.kind_of?(AND) and self.opnds == other.opnds )
|
201
|
+
end
|
202
|
+
|
203
|
+
def hash
|
204
|
+
"#{self.opnds}/AND".hash
|
205
|
+
end
|
206
|
+
|
207
|
+
#
|
208
|
+
# {@inheritDoc}
|
209
|
+
#
|
210
|
+
# <p>
|
211
|
+
# The evaluation of predicates by this context is short-circuiting, but
|
212
|
+
# unordered.</p>
|
213
|
+
#
|
214
|
+
def eval(parser, outerContext)
|
215
|
+
self.opnds.each {|opnd|
|
216
|
+
if not opnd.eval(parser, outerContext)
|
217
|
+
return false
|
218
|
+
end
|
219
|
+
}
|
220
|
+
return true
|
221
|
+
end
|
222
|
+
|
223
|
+
def evalPrecedence(parser, outerContext)
|
224
|
+
differs = false
|
225
|
+
operands = Array.new
|
226
|
+
self.opnds.each {|context|
|
227
|
+
evaluated = context.evalPrecedence(parser, outerContext)
|
228
|
+
if evaluated.equal? context then
|
229
|
+
differs = false
|
230
|
+
else
|
231
|
+
differs = true
|
232
|
+
end
|
233
|
+
# differs = differs || (! (evaluated.equal? context))
|
234
|
+
# The AND context is false if any element is false
|
235
|
+
return nil if evaluated.nil?
|
236
|
+
if evaluated.equal? SemanticContext.NONE
|
237
|
+
# Reduce the result by skipping true elements
|
238
|
+
operands.push(evaluated)
|
239
|
+
end
|
240
|
+
}
|
241
|
+
if not differs
|
242
|
+
return self
|
243
|
+
end
|
244
|
+
|
245
|
+
if operands.length()==0
|
246
|
+
# all elements were true, so the AND context is true
|
247
|
+
return SemanticContext.NONE
|
248
|
+
end
|
249
|
+
|
250
|
+
result = nil
|
251
|
+
operands.each {|o|
|
252
|
+
if result.nil?
|
253
|
+
result = o
|
254
|
+
else
|
255
|
+
result = result.andContext(o)
|
256
|
+
end
|
257
|
+
}
|
258
|
+
return result
|
259
|
+
end
|
260
|
+
def to_s
|
261
|
+
self.opnds.map(&:to_s).join("&&")
|
262
|
+
end
|
263
|
+
end
|
264
|
+
#
|
265
|
+
# A semantic context which is true whenever at least one of the contained
|
266
|
+
# contexts is true.
|
267
|
+
#
|
268
|
+
class OR < SemanticContext
|
269
|
+
|
270
|
+
def initialize(a, b)
|
271
|
+
operands = Set.new()
|
272
|
+
if a.kind_of? OR then
|
273
|
+
a.opnds.each {|o| operands.add(o) }
|
274
|
+
else
|
275
|
+
operands.add(a)
|
276
|
+
end
|
277
|
+
if b.kind_of? OR then
|
278
|
+
b.opnds.each {|o| operands.add(o) }
|
279
|
+
else
|
280
|
+
operands.add(b)
|
281
|
+
end
|
282
|
+
precedencePredicates = filterPrecedencePredicates(operands)
|
283
|
+
if precedencePredicates.length() > 0 then
|
284
|
+
# interested in the transition with the highest precedence
|
285
|
+
s = precedencePredicates.sort()
|
286
|
+
reduced = s[-1]
|
287
|
+
operands.add(reduced)
|
288
|
+
end
|
289
|
+
self.opnds = operands.to_a
|
290
|
+
end
|
291
|
+
|
292
|
+
def eql?(other)
|
293
|
+
self == other
|
294
|
+
end
|
295
|
+
def ==(other)
|
296
|
+
self.equal?(other) or other.kind_of?(OR) and self.opnds == other.opnds
|
297
|
+
end
|
298
|
+
def hash
|
299
|
+
"#{self.opnds}/OR".hash
|
300
|
+
end
|
301
|
+
|
302
|
+
# <p>
|
303
|
+
# The evaluation of predicates by this context is short-circuiting, but
|
304
|
+
# unordered.</p>
|
305
|
+
#
|
306
|
+
def eval(parser, outerContext)
|
307
|
+
|
308
|
+
self.opnds.each {|opnd|
|
309
|
+
if opnd.eval(parser, outerContext)
|
310
|
+
return true
|
311
|
+
end
|
312
|
+
}
|
313
|
+
return false
|
314
|
+
end
|
315
|
+
|
316
|
+
def evalPrecedence(parser, outerContext)
|
317
|
+
differs = false
|
318
|
+
operands = Array.new
|
319
|
+
operands = self.opnds.map {|context|
|
320
|
+
evaluated = context.evalPrecedence(parser, outerContext)
|
321
|
+
if evaluated.equal? context then
|
322
|
+
differs = false
|
323
|
+
else
|
324
|
+
differs = true
|
325
|
+
end
|
326
|
+
#differs = differs || not (evaluated.equal? context)
|
327
|
+
# The OR context is true if any element is true
|
328
|
+
return SemanticContext.NONE if evaluate.equal? SemanticContext.NONE
|
329
|
+
if not evaluated.nil? then
|
330
|
+
# Reduce the result by skipping false elements
|
331
|
+
evaluated
|
332
|
+
end
|
333
|
+
}.compact
|
334
|
+
return self unless differs
|
335
|
+
|
336
|
+
if operands.empty?
|
337
|
+
# all elements were false, so the OR context is false
|
338
|
+
return nil
|
339
|
+
end
|
340
|
+
|
341
|
+
result = nil
|
342
|
+
operands.each {|o|
|
343
|
+
if result.nil?
|
344
|
+
result = o
|
345
|
+
else
|
346
|
+
result = result.orContext(o)
|
347
|
+
end
|
348
|
+
}
|
349
|
+
return result
|
350
|
+
end
|
351
|
+
def to_s
|
352
|
+
self.opnds.map(&:to_s).join("||")
|
353
|
+
end
|
354
|
+
end
|
355
|
+
# SemanticContext.NONE = Predicate()
|
@@ -0,0 +1,297 @@
|
|
1
|
+
# An ATN transition between any two ATN states. Subclasses define
|
2
|
+
# atom, set, epsilon, action, predicate, rule transitions.
|
3
|
+
#
|
4
|
+
# <p>This is a one way link. It emanates from a state (usually via a list of
|
5
|
+
# transitions) and has a target state.</p>
|
6
|
+
#
|
7
|
+
# <p>Since we never have to change the ATN transitions once we construct it,
|
8
|
+
# we can fix these transitions as specific classes. The DFA transitions
|
9
|
+
# on the other hand need to update the labels as it adds transitions to
|
10
|
+
# the states. We'll use the term Edge for the DFA to distinguish them from
|
11
|
+
# ATN transitions.</p>
|
12
|
+
|
13
|
+
class Transition
|
14
|
+
# constants for serialization
|
15
|
+
EPSILON = 1
|
16
|
+
RANGE = 2
|
17
|
+
RULE = 3
|
18
|
+
PREDICATE = 4 # e.g., {isType(input.LT(1))}?
|
19
|
+
ATOM = 5
|
20
|
+
ACTION = 6
|
21
|
+
SET = 7 # ~(A|B) or ~atom, wildcard, which convert to next 2
|
22
|
+
NOT_SET = 8
|
23
|
+
WILDCARD = 9
|
24
|
+
PRECEDENCE = 10
|
25
|
+
|
26
|
+
@@serializationNames = [
|
27
|
+
"INVALID",
|
28
|
+
"EPSILON",
|
29
|
+
"RANGE",
|
30
|
+
"RULE",
|
31
|
+
"PREDICATE",
|
32
|
+
"ATOM",
|
33
|
+
"ACTION",
|
34
|
+
"SET",
|
35
|
+
"NOT_SET",
|
36
|
+
"WILDCARD",
|
37
|
+
"PRECEDENCE"
|
38
|
+
]
|
39
|
+
def self.serializationNames
|
40
|
+
@@serializationNames
|
41
|
+
end
|
42
|
+
|
43
|
+
@@serializationTypes = nil
|
44
|
+
def self.serializationTypes
|
45
|
+
@@serializationTypes
|
46
|
+
end
|
47
|
+
def self.serializationTypes=(newhash)
|
48
|
+
@@serializationTypes = newhash
|
49
|
+
end
|
50
|
+
|
51
|
+
attr_accessor :target, :isEpsilon, :serializationType, :ruleIndex
|
52
|
+
def initialize(target)
|
53
|
+
# The target of this transition.
|
54
|
+
raise Exception.new("target cannot be null.") if target.nil?
|
55
|
+
self.target = target
|
56
|
+
# Are we epsilon, action, sempred?
|
57
|
+
self.isEpsilon = false
|
58
|
+
@ruleIndex = 0
|
59
|
+
end
|
60
|
+
def label
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
# TODO: make all transitions sets? no, should remove set edges
|
67
|
+
class AtomTransition < Transition
|
68
|
+
|
69
|
+
attr_accessor :label_
|
70
|
+
def initialize(_target, _label)
|
71
|
+
super(_target)
|
72
|
+
@label_ = _label # The token type or character value; or, signifies special label.
|
73
|
+
@serializationType = Transition::ATOM
|
74
|
+
end
|
75
|
+
|
76
|
+
def label
|
77
|
+
s = IntervalSet.new()
|
78
|
+
s.addOne(self.label_)
|
79
|
+
return s
|
80
|
+
end
|
81
|
+
|
82
|
+
def matches( symbol, minVocabSymbol, maxVocabSymbol)
|
83
|
+
return self.label_ == symbol
|
84
|
+
end
|
85
|
+
|
86
|
+
def to_s
|
87
|
+
return self.label_.to_s
|
88
|
+
end
|
89
|
+
end
|
90
|
+
class RuleTransition < Transition
|
91
|
+
|
92
|
+
attr_accessor :ruleIndex, :precedence, :followState
|
93
|
+
def initialize(rule_start, rule_index, _precedence, follow_state)
|
94
|
+
super(rule_start)
|
95
|
+
self.ruleIndex = rule_index # ptr to the rule definition object for this rule ref
|
96
|
+
self.precedence = _precedence
|
97
|
+
self.followState = follow_state # what node to begin computations following ref to rule
|
98
|
+
@serializationType = Transition::RULE
|
99
|
+
@isEpsilon = true
|
100
|
+
end
|
101
|
+
|
102
|
+
def matches( symbol, minVocabSymbol, maxVocabSymbol)
|
103
|
+
return false
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
class EpsilonTransition < Transition
|
109
|
+
|
110
|
+
def initialize(_target)
|
111
|
+
super(_target)
|
112
|
+
self.serializationType = Transition::EPSILON
|
113
|
+
self.isEpsilon = true
|
114
|
+
end
|
115
|
+
|
116
|
+
def matches(symbol, minVocabSymbol, maxVocabSymbol)
|
117
|
+
return false
|
118
|
+
end
|
119
|
+
|
120
|
+
def to_s
|
121
|
+
return "epsilon"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
class RangeTransition < Transition
|
126
|
+
|
127
|
+
attr_accessor :start, :stop
|
128
|
+
def initialize(_target, _start, _stop)
|
129
|
+
super(_target)
|
130
|
+
self.serializationType = Transition::RANGE
|
131
|
+
self.start = _start
|
132
|
+
self.stop = _stop
|
133
|
+
end
|
134
|
+
|
135
|
+
def label()
|
136
|
+
s = IntervalSet.new()
|
137
|
+
s.addRange(self.start..self.stop)
|
138
|
+
return s
|
139
|
+
end
|
140
|
+
|
141
|
+
def matches( symbol, minVocabSymbol, maxVocabSymbol)
|
142
|
+
symbol >= self.start and symbol <= self.stop
|
143
|
+
end
|
144
|
+
|
145
|
+
def to_s
|
146
|
+
return "'#{self.start.chr}'..'#{self.stop.chr}'"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
class AbstractPredicateTransition < Transition
|
151
|
+
|
152
|
+
def initialize(_target)
|
153
|
+
super(_target)
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
class PredicateTransition < AbstractPredicateTransition
|
159
|
+
|
160
|
+
attr_accessor :ruleIndex, :predIndex, :isCtxDependent
|
161
|
+
def initialize(_target, rule_index, pred_index, is_ctx_dependent)
|
162
|
+
super(_target)
|
163
|
+
self.serializationType = Transition::PREDICATE
|
164
|
+
self.ruleIndex = rule_index
|
165
|
+
self.predIndex = pred_index
|
166
|
+
self.isCtxDependent = is_ctx_dependent # e.g., $i ref in pred
|
167
|
+
self.isEpsilon = true
|
168
|
+
end
|
169
|
+
|
170
|
+
def matches( symbol, minVocabSymbol, maxVocabSymbol)
|
171
|
+
return false
|
172
|
+
end
|
173
|
+
|
174
|
+
def getPredicate()
|
175
|
+
return Predicate.new(self.ruleIndex, self.predIndex, self.isCtxDependent)
|
176
|
+
end
|
177
|
+
|
178
|
+
def to_s
|
179
|
+
return "pred_#{self.ruleIndex}:#{self.predIndex}"
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
class ActionTransition < Transition
|
184
|
+
|
185
|
+
|
186
|
+
attr_accessor :ruleIndex, :actionIndex, :isCtxDependent
|
187
|
+
def initialize(_target, rule_index, action_index=-1, is_ctx_dependent=false)
|
188
|
+
super(_target)
|
189
|
+
self.serializationType = Transition::ACTION
|
190
|
+
self.ruleIndex = rule_index
|
191
|
+
self.actionIndex = action_index
|
192
|
+
self.isCtxDependent = is_ctx_dependent # e.g., $i ref in pred
|
193
|
+
self.isEpsilon = true
|
194
|
+
end
|
195
|
+
def matches( symbol, minVocabSymbol, maxVocabSymbol)
|
196
|
+
return false
|
197
|
+
end
|
198
|
+
|
199
|
+
def to_s
|
200
|
+
return "action_#{self.ruleIndex}:#{self.actionIndex}"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
# A transition containing a set of values.
|
204
|
+
class SetTransition < Transition
|
205
|
+
|
206
|
+
attr_accessor :set
|
207
|
+
def initialize(_target, _set)
|
208
|
+
super(_target)
|
209
|
+
self.serializationType = Transition::SET
|
210
|
+
if _set then
|
211
|
+
@set = _set
|
212
|
+
else
|
213
|
+
@set = IntervalSet.of(Token::INVALID_TYPE)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
def label
|
217
|
+
self.set
|
218
|
+
end
|
219
|
+
def matches(symbol, minVocabSymbol, maxVocabSymbol)
|
220
|
+
self.set.member? symbol
|
221
|
+
end
|
222
|
+
|
223
|
+
def to_s
|
224
|
+
self.set.to_s
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
class NotSetTransition < SetTransition
|
229
|
+
|
230
|
+
def initialize(_target, _set)
|
231
|
+
super(_target, _set)
|
232
|
+
self.serializationType = Transition::NOT_SET
|
233
|
+
end
|
234
|
+
|
235
|
+
def matches( symbol, minVocabSymbol, maxVocabSymbol)
|
236
|
+
symbol >= minVocabSymbol \
|
237
|
+
and symbol <= maxVocabSymbol \
|
238
|
+
and not (self.set.member? symbol)
|
239
|
+
end
|
240
|
+
|
241
|
+
def to_s
|
242
|
+
return '~' + super()
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
class WildcardTransition < Transition
|
247
|
+
|
248
|
+
def initialize(_target)
|
249
|
+
super(_target)
|
250
|
+
self.serializationType = Transition::WILDCARD
|
251
|
+
end
|
252
|
+
|
253
|
+
def matches( symbol, minVocabSymbol, maxVocabSymbol)
|
254
|
+
symbol >= minVocabSymbol and symbol <= maxVocabSymbol
|
255
|
+
end
|
256
|
+
|
257
|
+
def to_s
|
258
|
+
return "."
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
class PrecedencePredicateTransition < AbstractPredicateTransition
|
263
|
+
|
264
|
+
attr_accessor :precedence
|
265
|
+
def initialize(_target, precedence)
|
266
|
+
super(_target)
|
267
|
+
self.serializationType = Transition::PRECEDENCE
|
268
|
+
self.precedence = precedence
|
269
|
+
self.isEpsilon = true
|
270
|
+
end
|
271
|
+
|
272
|
+
def matches( symbol, minVocabSymbol, maxVocabSymbol)
|
273
|
+
return false
|
274
|
+
end
|
275
|
+
|
276
|
+
|
277
|
+
def getPredicate()
|
278
|
+
return PrecedencePredicate.new(self.precedence)
|
279
|
+
end
|
280
|
+
|
281
|
+
def to_s
|
282
|
+
return "#{self.precedence} >= _p"
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
Transition.serializationTypes = {
|
287
|
+
EpsilonTransition => Transition::EPSILON,
|
288
|
+
RangeTransition => Transition::RANGE,
|
289
|
+
RuleTransition => Transition::RULE,
|
290
|
+
PredicateTransition => Transition::PREDICATE,
|
291
|
+
AtomTransition => Transition::ATOM,
|
292
|
+
ActionTransition => Transition::ACTION,
|
293
|
+
SetTransition => Transition::SET,
|
294
|
+
NotSetTransition => Transition::NOT_SET,
|
295
|
+
WildcardTransition => Transition::WILDCARD,
|
296
|
+
PrecedencePredicateTransition => Transition::PRECEDENCE
|
297
|
+
}
|