Class: IntervalSet

Inherits:
Object show all
Extended by:
Forwardable
Includes:
Enumerable
Defined in:
lib/antlr4/IntervalSet.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeIntervalSet

Returns a new instance of IntervalSet.



6
7
8
9
10
# File 'lib/antlr4/IntervalSet.rb', line 6

def initialize
    self.intervals = Array.new
    self.readonly = false
    @_internal = Set.new
end

Instance Attribute Details

#_internalObject

Returns the value of attribute _internal.



5
6
7
# File 'lib/antlr4/IntervalSet.rb', line 5

def _internal
  @_internal
end

#intervalsObject

Returns the value of attribute intervals.



4
5
6
# File 'lib/antlr4/IntervalSet.rb', line 4

def intervals
  @intervals
end

#readonlyObject

Returns the value of attribute readonly.



4
5
6
# File 'lib/antlr4/IntervalSet.rb', line 4

def readonly
  @readonly
end

Class Method Details

.copy(other) ⇒ Object



14
15
16
17
18
19
20
# File 'lib/antlr4/IntervalSet.rb', line 14

def self.copy(other)
    s = IntervalSet.new
    s.intervals = other.intervals.clone
    s.readonly = other.readonly
    s._internal = other._internal.clone
    s
end

.of(a, b = nil) ⇒ Object



22
23
24
25
26
27
28
29
# File 'lib/antlr4/IntervalSet.rb', line 22

def self.of(a,b=nil)
   s = IntervalSet.new
   if b.nil? then
      b = a
   end
   s.addRange(a..b)
   s
end

.subtract(left, right) ⇒ Object

Compute the set difference between two interval sets. The specific operation is left - right. If either of the input sets is null, it is treated as though it was an empty set.



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
# File 'lib/antlr4/IntervalSet.rb', line 237

def self.subtract(left,right)
   if left.nil? or left.isNil() then
       return IntervalSet.new()
   end

   result = IntervalSet.copy(left)
  if right.nil? or right.isNil() then
    # right set has no elements; just return the copy of the current set
    return result
  end

  resultI = 0
  rightI = 0
  while (resultI < result.intervals.size() && rightI < right.intervals.size()) do
    resultInterval = result.intervals[resultI]
    rightInterval = right.intervals[rightI]

    # operation: (resultInterval - rightInterval) and update indexes
    if (rightInterval.b < resultInterval.a) then
      rightI += 1
      next
    end
    if (rightInterval.a > resultInterval.b) then
      resultI += 1
      next
    end 

    beforeCurrent = nil
    afterCurrent = nil
    if (rightInterval.a > resultInterval.a) then
      beforeCurrent = (resultInterval.a .. rightInterval.a - 1)
    end

    if (rightInterval.b < resultInterval.b) then
      afterCurrent =  (rightInterval.b + 1  .. resultInterval.b)
    end

    if not beforeCurrent.nil? then
      if not afterCurrent.nil? then
        # split the current interval into two
        result.intervals[resultI] =  beforeCurrent
        result.intervals[resultI + 1] =  afterCurrent
        resultI += 1
        rightI += 1
      else
        # replace the current interval
        result.intervals[resultI]= beforeCurrent
        resultI += 1
      end
      next
    else
      if not afterCurrent.nil?  then
        # replace the current interval
        result.intervals[resultI] =  afterCurrent
        rightI += 1
      else
        # remove the current interval (thus no need to increment resultI)
        result.intervals.delete_at(resultI)
      end
      next
    end
  end

  # If rightI reached right.intervals.size(), no more intervals to subtract from result.
  # If resultI reached result.intervals.size(), we would be subtracting from an empty set.
  # Either way, we are done.
  result
end

Instance Method Details

#addOne(v) ⇒ Object



34
35
36
# File 'lib/antlr4/IntervalSet.rb', line 34

def addOne(v)
    self.addRange(v..v)
end

#addRange(v) ⇒ Object



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
# File 'lib/antlr4/IntervalSet.rb', line 38

def addRange(v)
    type_check(v, Range)
    if self.intervals.empty? then
        self.intervals.push(v)
    else
        # find insert pos
        k = 0
        for i in self.intervals do
            # distinct range -> insert
            if v.stop<i.start then
                self.intervals.insert(k, v)
                return
            # contiguous range -> adjust
            elsif v.stop==i.start
                self.intervals[k] = v.start..i.stop
                return
            # overlapping range -> adjust and reduce
            elsif v.start<=i.stop
                self.intervals[k] = [i.start,v.start].min() ..  ([i.stop,v.stop].max())
                self.reduce(k)
                return
            end
            k = k + 1
        end
        # greater than any existing
        self.intervals.push(v)
    end
end

#addSet(other) ⇒ Object

IntervalSet):



67
68
69
70
71
72
73
74
75
76
# File 'lib/antlr4/IntervalSet.rb', line 67

def addSet(other) # IntervalSet):
    if other.kind_of?(IntervalSet) then
      if other.intervals and not other.isNil then
        other.intervals.each {|i| self.addRange(i) }
      end
    else
        raise Exception.new("can't add a non-IntervalSet #{other.class}")
    end
    return self
end

#complement(vocabulary) ⇒ Object

this.complement(IntervalSet.of(minElement,maxElement));



215
216
217
218
219
220
221
# File 'lib/antlr4/IntervalSet.rb', line 215

def complement(vocabulary)
  if vocabulary.nil? || vocabulary.isNil() then
    return nil
  end
  vocabularyIS = vocabulary
  vocabularyIS.subtract(self);
end

#elementName(tokenNames, a) ⇒ Object



184
185
186
187
188
189
190
191
192
# File 'lib/antlr4/IntervalSet.rb', line 184

def elementName(tokenNames, a)
    if a==Token::EOF then
        return "<EOF>"
    elsif a==Token::EPSILON
        return "<EPSILON>"
    else
        return tokenNames[a]
    end
end

#getMinElementObject



31
32
33
# File 'lib/antlr4/IntervalSet.rb', line 31

def getMinElement
    intervals.first
end

#isNilObject

}



209
210
211
# File 'lib/antlr4/IntervalSet.rb', line 209

def isNil()
   self.intervals.empty?
end

#lengthObject



103
104
105
106
107
108
109
# File 'lib/antlr4/IntervalSet.rb', line 103

def length
    xlen = 0
    self.intervals.each do |i|
      xlen = xlen + i.length
    end
    return xlen
end

#member?(item) ⇒ Boolean

Returns:

  • (Boolean)


93
94
95
96
97
98
99
100
101
# File 'lib/antlr4/IntervalSet.rb', line 93

def member?(item)
    return false if self.intervals.empty?
    self.intervals.each  do |i|
        if i.member? item  then
           return true
        end
    end
    false
end

#reduce(k) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/antlr4/IntervalSet.rb', line 78

def reduce(k)
    # only need to reduce if k is not the last
    if k<self.intervals.length()-1 then
        l = self.intervals[k]
        r = self.intervals[k+1]
        # if r contained in l
        if l.stop >= r.stop
            self.intervals.pop(k+1)
            self.reduce(k)
        elsif l.stop >= r.start
            self.intervals[k] = l.start..r.stop
            self.intervals.pop(k+1)
        end
    end
end

#remove(v) ⇒ Object



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
# File 'lib/antlr4/IntervalSet.rb', line 125

def remove(v)
    if not self.intervals.empty? then
        k = 0
        for i in self.intervals do
            # intervals is ordered
            if v<i.start then
                return
            # check for single value range
#                elsif v==i.start and v==i.stop-1
            elsif v==i.start and v==i.stop
                self.intervals.pop(k)
                return
            # check for lower boundary
            elsif v==i.start
#                    self.intervals[k] = i.start+1..i.stop-1
                self.intervals[k] = i.start+1..i.stop
                return
            # check for upper boundary
            elsif v==i.stop-1
#                    self.intervals[k] = i.start..i.stop-1-1
                self.intervals[k] = i.start..i.stop
                return
            # split existing range
            elsif v<i.stop-1
                x = i.start..(v-1)
                i.start = v + 1
                self.intervals.insert(k, x)
                return
            end
            k = k + 1
        end
    end                  
end

#subtract(a) ⇒ Object



223
224
225
226
227
228
229
230
231
# File 'lib/antlr4/IntervalSet.rb', line 223

def subtract(a) 
if (a.nil? || a.isNil()) then
 s = IntervalSet.new 
    s.addSet(self) 
    return s 
end

      return IntervalSet.subtract(self, a);
end

#toString(tokenNames = nil) ⇒ Object



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
# File 'lib/antlr4/IntervalSet.rb', line 159

def toString(tokenNames=nil)
    if self.intervals.nil? or self.intervals.empty? then
        return "{}"
    end
#        "{#{intervals.to_s}}"
   StringIO.open  do |buf|
        if length > 1 then
            buf.write("{")
        end
        x = intervals.map { |i|
            i.map { |j| 
                if tokenNames then
                    self.elementName(tokenNames, j).to_s
                else
                    j.to_s
                end
            }.join(', ')
        }.join(", ")
        buf.write(x) 
        if length > 1 then 
            buf.write("}")
        end
        return buf.string() 
   end
end