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,53 @@
|
|
1
|
+
# This default implementation of {@link TokenFactory} creates
|
2
|
+
# {@link CommonToken} objects.
|
3
|
+
|
4
|
+
class CommonTokenFactory < TokenFactory
|
5
|
+
#
|
6
|
+
# The default {@link CommonTokenFactory} instance.
|
7
|
+
#
|
8
|
+
# <p>
|
9
|
+
# This token factory does not explicitly copy token text when constructing
|
10
|
+
# tokens.</p>
|
11
|
+
#
|
12
|
+
@@default = nil
|
13
|
+
def self.DEFAULT
|
14
|
+
@@default = new() if @@default.nil?
|
15
|
+
@@default
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_accessor :copyText
|
19
|
+
def initialize(_copyText=false)
|
20
|
+
# Indicates whether {@link CommonToken#setText} should be called after
|
21
|
+
# constructing tokens to explicitly set the text. This is useful for cases
|
22
|
+
# where the input stream might not be able to provide arbitrary substrings
|
23
|
+
# of text from the input after the lexer creates a token (e.g. the
|
24
|
+
# implementation of {@link CharStream#getText} in
|
25
|
+
# {@link UnbufferedCharStream} throws an
|
26
|
+
# {@link UnsupportedOperationException}). Explicitly setting the token text
|
27
|
+
# allows {@link Token#getText} to be called at any time regardless of the
|
28
|
+
# input stream implementation.
|
29
|
+
#
|
30
|
+
# <p>
|
31
|
+
# The default value is {@code false} to avoid the performance and memory
|
32
|
+
# overhead of copying text for every token unless explicitly requested.</p>
|
33
|
+
#
|
34
|
+
@copyText = _copyText
|
35
|
+
end
|
36
|
+
def create(source, type, text, channel, start, stop, line, column)
|
37
|
+
t = CommonToken.new(source, type, channel, start, stop)
|
38
|
+
t.line = line
|
39
|
+
t.column = column
|
40
|
+
if not text.nil? then
|
41
|
+
t.text = text
|
42
|
+
elsif self.copyText and not source[1].nil? then
|
43
|
+
t.text = source[1].getText(start,stop)
|
44
|
+
end
|
45
|
+
return t
|
46
|
+
end
|
47
|
+
|
48
|
+
def createThin(type, text)
|
49
|
+
t = CommonToken.new(type)
|
50
|
+
t.text = text
|
51
|
+
return t
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
|
2
|
+
class CommonTokenStream < BufferedTokenStream
|
3
|
+
|
4
|
+
attr_accessor :channel
|
5
|
+
def initialize(lexer, _channel=Token::DEFAULT_CHANNEL)
|
6
|
+
super(lexer)
|
7
|
+
@channel = _channel
|
8
|
+
end
|
9
|
+
|
10
|
+
def adjustSeekIndex(i)
|
11
|
+
return self.nextTokenOnChannel(i, self.channel)
|
12
|
+
end
|
13
|
+
|
14
|
+
def LB(k)
|
15
|
+
return nil if k==0 or (self.index-k)<0
|
16
|
+
i = self.index
|
17
|
+
n = 1
|
18
|
+
# find k good tokens looking backwards
|
19
|
+
while n <= k do
|
20
|
+
# skip off-channel tokens
|
21
|
+
i = self.previousTokenOnChannel(i - 1, self.channel)
|
22
|
+
n = n + 1
|
23
|
+
end
|
24
|
+
return nil if i < 0
|
25
|
+
return self.tokens[i]
|
26
|
+
end
|
27
|
+
def LT(k)
|
28
|
+
self.lazyInit()
|
29
|
+
return nil if k == 0
|
30
|
+
return self.LB(-k) if k < 0
|
31
|
+
i = self.index
|
32
|
+
n = 1 # we know tokens[pos] is a good one
|
33
|
+
# find k good tokens
|
34
|
+
while n < k do
|
35
|
+
# skip off-channel tokens, but make sure to not look past EOF
|
36
|
+
if self.sync(i + 1)
|
37
|
+
i = self.nextTokenOnChannel(i + 1, self.channel)
|
38
|
+
end
|
39
|
+
n = n + 1
|
40
|
+
end
|
41
|
+
return self.tokens[i]
|
42
|
+
end
|
43
|
+
# Count EOF just once.#/
|
44
|
+
def getNumberOfOnChannelTokens
|
45
|
+
n = 0
|
46
|
+
self.fill()
|
47
|
+
for i in 0..self.tokens.length-1 do
|
48
|
+
t = self.tokens[i]
|
49
|
+
if t.channel==self.channel
|
50
|
+
n = n + 1
|
51
|
+
end
|
52
|
+
break if t.type==Token::EOF
|
53
|
+
end
|
54
|
+
return n
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# This is an InputStream that is loaded from a file all at once
|
2
|
+
# when you construct the object.
|
3
|
+
class FileStream < InputStream
|
4
|
+
|
5
|
+
def initialize(fileName, encoding=nil)
|
6
|
+
# read binary to avoid line ending conversion
|
7
|
+
bytes = nil
|
8
|
+
File.open(fileName, 'rb') do |file|
|
9
|
+
bytes = file.read()
|
10
|
+
end
|
11
|
+
super(bytes)
|
12
|
+
@name = fileName
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# Vacuum all input from a string and then treat it like a buffer.
|
2
|
+
|
3
|
+
class InputStream
|
4
|
+
|
5
|
+
attr_accessor :index, :strdata, :name, :size, :data
|
6
|
+
def initialize(data)
|
7
|
+
@name = "<empty>"
|
8
|
+
@strdata = data
|
9
|
+
@index = 0
|
10
|
+
@data = @strdata.bytes
|
11
|
+
@size = @data.length
|
12
|
+
end
|
13
|
+
|
14
|
+
# Reset the stream so that it's in the same state it was
|
15
|
+
# when the object was created *except* the data array is not
|
16
|
+
# touched.
|
17
|
+
#
|
18
|
+
def reset()
|
19
|
+
@index = 0
|
20
|
+
end
|
21
|
+
|
22
|
+
def consume()
|
23
|
+
if self.index >= self.size then
|
24
|
+
# assert self.LA(1) == Token::EOF
|
25
|
+
raise Exception.new("cannot consume EOF")
|
26
|
+
end
|
27
|
+
self.index = self.index + 1
|
28
|
+
end
|
29
|
+
def LA(offset)
|
30
|
+
if offset==0 then
|
31
|
+
return 0 # undefined
|
32
|
+
end
|
33
|
+
if offset<0 then
|
34
|
+
offset = offset + 1 # e.g., translate LA(-1) to use offset=0
|
35
|
+
end
|
36
|
+
pos = self.index + offset - 1
|
37
|
+
if pos < 0 or pos >= @size then # invalid
|
38
|
+
return Token::EOF
|
39
|
+
end
|
40
|
+
return self.data[pos]
|
41
|
+
end
|
42
|
+
|
43
|
+
def LT(offset)
|
44
|
+
return self.LA(offset)
|
45
|
+
end
|
46
|
+
|
47
|
+
# mark/release do nothing; we have entire buffer
|
48
|
+
def mark()
|
49
|
+
return -1
|
50
|
+
end
|
51
|
+
|
52
|
+
def release(marker)
|
53
|
+
end
|
54
|
+
|
55
|
+
# consume() ahead until p==_index; can't just set p=_index as we must
|
56
|
+
# update line and column. If we seek backwards, just set p
|
57
|
+
#
|
58
|
+
def seek(_index)
|
59
|
+
if _index<=self.index then
|
60
|
+
self.index = _index # just jump; don't update stream state (line, ...)
|
61
|
+
return
|
62
|
+
end
|
63
|
+
# seek forward
|
64
|
+
self.index = [_index, self.size].min
|
65
|
+
end
|
66
|
+
|
67
|
+
def getText(start, stop)
|
68
|
+
if stop >= self.size then
|
69
|
+
stop = self.size - 1
|
70
|
+
end
|
71
|
+
if start >= self.size then
|
72
|
+
return ""
|
73
|
+
else
|
74
|
+
return self.strdata[start..stop] # start = inital, stop == offset?
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def to_s
|
79
|
+
return self.strdata
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
@@ -0,0 +1,341 @@
|
|
1
|
+
class IntervalSet
|
2
|
+
extend Forwardable
|
3
|
+
|
4
|
+
attr_accessor :intervals , :readonly
|
5
|
+
attr_accessor :_internal
|
6
|
+
def initialize
|
7
|
+
self.intervals = Array.new
|
8
|
+
self.readonly = false
|
9
|
+
@_internal = Set.new
|
10
|
+
end
|
11
|
+
def_delegators :@intervals, :each, :map
|
12
|
+
include Enumerable
|
13
|
+
|
14
|
+
def self.copy(other)
|
15
|
+
s = IntervalSet.new
|
16
|
+
s.intervals = other.intervals.clone
|
17
|
+
s.readonly = other.readonly
|
18
|
+
s._internal = other._internal.clone
|
19
|
+
s
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.of(a,b=nil)
|
23
|
+
s = IntervalSet.new
|
24
|
+
if b.nil? then
|
25
|
+
b = a
|
26
|
+
end
|
27
|
+
s.addRange(a..b)
|
28
|
+
s
|
29
|
+
end
|
30
|
+
|
31
|
+
def getMinElement
|
32
|
+
intervals.first
|
33
|
+
end
|
34
|
+
def addOne(v)
|
35
|
+
self.addRange(v..v)
|
36
|
+
end
|
37
|
+
|
38
|
+
def addRange(v)
|
39
|
+
type_check(v, Range)
|
40
|
+
if self.intervals.empty? then
|
41
|
+
self.intervals.push(v)
|
42
|
+
else
|
43
|
+
# find insert pos
|
44
|
+
k = 0
|
45
|
+
for i in self.intervals do
|
46
|
+
# distinct range -> insert
|
47
|
+
if v.stop<i.start then
|
48
|
+
self.intervals.insert(k, v)
|
49
|
+
return
|
50
|
+
# contiguous range -> adjust
|
51
|
+
elsif v.stop==i.start
|
52
|
+
self.intervals[k] = v.start..i.stop
|
53
|
+
return
|
54
|
+
# overlapping range -> adjust and reduce
|
55
|
+
elsif v.start<=i.stop
|
56
|
+
self.intervals[k] = [i.start,v.start].min() .. ([i.stop,v.stop].max())
|
57
|
+
self.reduce(k)
|
58
|
+
return
|
59
|
+
end
|
60
|
+
k = k + 1
|
61
|
+
end
|
62
|
+
# greater than any existing
|
63
|
+
self.intervals.push(v)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def addSet(other) # IntervalSet):
|
68
|
+
if other.kind_of?(IntervalSet) then
|
69
|
+
if other.intervals and not other.isNil then
|
70
|
+
other.intervals.each {|i| self.addRange(i) }
|
71
|
+
end
|
72
|
+
else
|
73
|
+
raise Exception.new("can't add a non-IntervalSet #{other.class}")
|
74
|
+
end
|
75
|
+
return self
|
76
|
+
end
|
77
|
+
|
78
|
+
def reduce(k)
|
79
|
+
# only need to reduce if k is not the last
|
80
|
+
if k<self.intervals.length()-1 then
|
81
|
+
l = self.intervals[k]
|
82
|
+
r = self.intervals[k+1]
|
83
|
+
# if r contained in l
|
84
|
+
if l.stop >= r.stop
|
85
|
+
self.intervals.pop(k+1)
|
86
|
+
self.reduce(k)
|
87
|
+
elsif l.stop >= r.start
|
88
|
+
self.intervals[k] = l.start..r.stop
|
89
|
+
self.intervals.pop(k+1)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
def member?(item)
|
94
|
+
return false if self.intervals.empty?
|
95
|
+
self.intervals.each do |i|
|
96
|
+
if i.member? item then
|
97
|
+
return true
|
98
|
+
end
|
99
|
+
end
|
100
|
+
false
|
101
|
+
end
|
102
|
+
|
103
|
+
def length
|
104
|
+
xlen = 0
|
105
|
+
self.intervals.each do |i|
|
106
|
+
xlen = xlen + i.length
|
107
|
+
end
|
108
|
+
return xlen
|
109
|
+
end
|
110
|
+
# public int size() {
|
111
|
+
# int n = 0;
|
112
|
+
# int numIntervals = intervals.size();
|
113
|
+
# if ( numIntervals==1 ) {
|
114
|
+
# Interval firstInterval = this.intervals.get(0);
|
115
|
+
# return firstInterval.b-firstInterval.a+1;
|
116
|
+
# }
|
117
|
+
# for (int i = 0; i < numIntervals; i++) {
|
118
|
+
# Interval I = intervals.get(i);
|
119
|
+
# n += (I.b-I.a+1);
|
120
|
+
# }
|
121
|
+
# return n;
|
122
|
+
# }
|
123
|
+
|
124
|
+
|
125
|
+
def remove(v)
|
126
|
+
if not self.intervals.empty? then
|
127
|
+
k = 0
|
128
|
+
for i in self.intervals do
|
129
|
+
# intervals is ordered
|
130
|
+
if v<i.start then
|
131
|
+
return
|
132
|
+
# check for single value range
|
133
|
+
# elsif v==i.start and v==i.stop-1
|
134
|
+
elsif v==i.start and v==i.stop
|
135
|
+
self.intervals.pop(k)
|
136
|
+
return
|
137
|
+
# check for lower boundary
|
138
|
+
elsif v==i.start
|
139
|
+
# self.intervals[k] = i.start+1..i.stop-1
|
140
|
+
self.intervals[k] = i.start+1..i.stop
|
141
|
+
return
|
142
|
+
# check for upper boundary
|
143
|
+
elsif v==i.stop-1
|
144
|
+
# self.intervals[k] = i.start..i.stop-1-1
|
145
|
+
self.intervals[k] = i.start..i.stop
|
146
|
+
return
|
147
|
+
# split existing range
|
148
|
+
elsif v<i.stop-1
|
149
|
+
x = i.start..(v-1)
|
150
|
+
i.start = v + 1
|
151
|
+
self.intervals.insert(k, x)
|
152
|
+
return
|
153
|
+
end
|
154
|
+
k = k + 1
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def toString(tokenNames=nil)
|
160
|
+
if self.intervals.nil? or self.intervals.empty? then
|
161
|
+
return "{}"
|
162
|
+
end
|
163
|
+
# "{#{intervals.to_s}}"
|
164
|
+
StringIO.open do |buf|
|
165
|
+
if length > 1 then
|
166
|
+
buf.write("{")
|
167
|
+
end
|
168
|
+
x = intervals.map { |i|
|
169
|
+
i.map { |j|
|
170
|
+
if tokenNames then
|
171
|
+
self.elementName(tokenNames, j).to_s
|
172
|
+
else
|
173
|
+
j.to_s
|
174
|
+
end
|
175
|
+
}.join(', ')
|
176
|
+
}.join(", ")
|
177
|
+
buf.write(x)
|
178
|
+
if length > 1 then
|
179
|
+
buf.write("}")
|
180
|
+
end
|
181
|
+
return buf.string()
|
182
|
+
end
|
183
|
+
end
|
184
|
+
def elementName(tokenNames, a)
|
185
|
+
if a==Token::EOF then
|
186
|
+
return "<EOF>"
|
187
|
+
elsif a==Token::EPSILON
|
188
|
+
return "<EPSILON>"
|
189
|
+
else
|
190
|
+
return tokenNames[a]
|
191
|
+
end
|
192
|
+
end
|
193
|
+
#IntervalSet implements IntSet {
|
194
|
+
# COMPLETE_CHAR_SET = IntervalSet.of(Lexer::MIN_CHAR_VALUE, Lexer::MAX_CHAR_VALUE);
|
195
|
+
# static { COMPLETE_CHAR_SET.setReadonly(true); }
|
196
|
+
# EMPTY_SET = new IntervalSet(); static { EMPTY_SET.setReadonly(true); }
|
197
|
+
#
|
198
|
+
# public IntervalSet addAll(IntSet set) {
|
199
|
+
# if ( set==null ) { return this; }
|
200
|
+
# if (set instanceof IntervalSet) {
|
201
|
+
# IntervalSet other = (IntervalSet)set;
|
202
|
+
# int n = other.intervals.size();
|
203
|
+
# for (int i = 0; i < n; i++) {
|
204
|
+
# Interval I = other.intervals.get(i);
|
205
|
+
# this.add(I.a,I.b);
|
206
|
+
# }
|
207
|
+
# return this;
|
208
|
+
#}
|
209
|
+
def isNil()
|
210
|
+
self.intervals.empty?
|
211
|
+
end
|
212
|
+
#
|
213
|
+
# this.complement(IntervalSet.of(minElement,maxElement));
|
214
|
+
#
|
215
|
+
def complement(vocabulary)
|
216
|
+
if vocabulary.nil? || vocabulary.isNil() then
|
217
|
+
return nil
|
218
|
+
end
|
219
|
+
vocabularyIS = vocabulary
|
220
|
+
vocabularyIS.subtract(self);
|
221
|
+
end
|
222
|
+
|
223
|
+
def subtract(a)
|
224
|
+
if (a.nil? || a.isNil()) then
|
225
|
+
s = IntervalSet.new
|
226
|
+
s.addSet(self)
|
227
|
+
return s
|
228
|
+
end
|
229
|
+
|
230
|
+
return IntervalSet.subtract(self, a);
|
231
|
+
end
|
232
|
+
|
233
|
+
|
234
|
+
# Compute the set difference between two interval sets. The specific
|
235
|
+
# operation is {@code left - right}. If either of the input sets is
|
236
|
+
# {@code null}, it is treated as though it was an empty set.
|
237
|
+
def self.subtract(left,right)
|
238
|
+
if left.nil? or left.isNil() then
|
239
|
+
return IntervalSet.new()
|
240
|
+
end
|
241
|
+
|
242
|
+
result = IntervalSet.copy(left)
|
243
|
+
if right.nil? or right.isNil() then
|
244
|
+
# right set has no elements; just return the copy of the current set
|
245
|
+
return result
|
246
|
+
end
|
247
|
+
|
248
|
+
resultI = 0
|
249
|
+
rightI = 0
|
250
|
+
while (resultI < result.intervals.size() && rightI < right.intervals.size()) do
|
251
|
+
resultInterval = result.intervals[resultI]
|
252
|
+
rightInterval = right.intervals[rightI]
|
253
|
+
|
254
|
+
# operation: (resultInterval - rightInterval) and update indexes
|
255
|
+
if (rightInterval.b < resultInterval.a) then
|
256
|
+
rightI += 1
|
257
|
+
next
|
258
|
+
end
|
259
|
+
if (rightInterval.a > resultInterval.b) then
|
260
|
+
resultI += 1
|
261
|
+
next
|
262
|
+
end
|
263
|
+
|
264
|
+
beforeCurrent = nil
|
265
|
+
afterCurrent = nil
|
266
|
+
if (rightInterval.a > resultInterval.a) then
|
267
|
+
beforeCurrent = (resultInterval.a .. rightInterval.a - 1)
|
268
|
+
end
|
269
|
+
|
270
|
+
if (rightInterval.b < resultInterval.b) then
|
271
|
+
afterCurrent = (rightInterval.b + 1 .. resultInterval.b)
|
272
|
+
end
|
273
|
+
|
274
|
+
if not beforeCurrent.nil? then
|
275
|
+
if not afterCurrent.nil? then
|
276
|
+
# split the current interval into two
|
277
|
+
result.intervals[resultI] = beforeCurrent
|
278
|
+
result.intervals[resultI + 1] = afterCurrent
|
279
|
+
resultI += 1
|
280
|
+
rightI += 1
|
281
|
+
else
|
282
|
+
# replace the current interval
|
283
|
+
result.intervals[resultI]= beforeCurrent
|
284
|
+
resultI += 1
|
285
|
+
end
|
286
|
+
next
|
287
|
+
else
|
288
|
+
if not afterCurrent.nil? then
|
289
|
+
# replace the current interval
|
290
|
+
result.intervals[resultI] = afterCurrent
|
291
|
+
rightI += 1
|
292
|
+
else
|
293
|
+
# remove the current interval (thus no need to increment resultI)
|
294
|
+
result.intervals.delete_at(resultI)
|
295
|
+
end
|
296
|
+
next
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
# If rightI reached right.intervals.size(), no more intervals to subtract from result.
|
301
|
+
# If resultI reached result.intervals.size(), we would be subtracting from an empty set.
|
302
|
+
# Either way, we are done.
|
303
|
+
result
|
304
|
+
end
|
305
|
+
|
306
|
+
end
|
307
|
+
# Returns the maximum value contained in the set.
|
308
|
+
# If the set is empty, this method returns {@link Token#INVALID_TYPE}.
|
309
|
+
# def getMaxElement()
|
310
|
+
# if ( isNil() ) { return Token::INVALID_TYPE; }
|
311
|
+
# Interval last = intervals.get(intervals.size()-1);
|
312
|
+
# return last.b;
|
313
|
+
# end
|
314
|
+
#
|
315
|
+
## Returns the minimum value contained in the set.
|
316
|
+
# def getMinElement()
|
317
|
+
# if ( isNil() ) { return Token::INVALID_TYPE; }
|
318
|
+
# return intervals.get(0).a;
|
319
|
+
# end
|
320
|
+
|
321
|
+
|
322
|
+
# /** Get the ith element of ordered set. Used only by RandomPhrase so
|
323
|
+
# * don't bother to implement if you're not doing that for a new
|
324
|
+
# * ANTLR code gen target.
|
325
|
+
# public int get(int i) {
|
326
|
+
# int n = intervals.size();
|
327
|
+
# int index = 0;
|
328
|
+
# for (int j = 0; j < n; j++) {
|
329
|
+
# Interval I = intervals.get(j);
|
330
|
+
# int a = I.a;
|
331
|
+
# int b = I.b;
|
332
|
+
# for (int v=a; v<=b; v++) {
|
333
|
+
# if ( index==i ) {
|
334
|
+
# return v;
|
335
|
+
# }
|
336
|
+
# index++;
|
337
|
+
# }
|
338
|
+
# }
|
339
|
+
# return -1;
|
340
|
+
# }
|
341
|
+
|