Class: ATNConfigSet

Inherits:
Object show all
Extended by:
Forwardable
Includes:
PredictionContextFunctions
Defined in:
lib/antlr4/atn/ATNConfigSet.rb

Overview

Specialized Set<ATNConfig> that can track info about the set, with support for combining similar configurations using a graph-structured stack.

Direct Known Subclasses

OrderedATNConfigSet

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from PredictionContextFunctions

included

Constructor Details

#initialize(_fullCtx = true) ⇒ ATNConfigSet



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
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 21

def initialize(_fullCtx=true)
    # All configs but hashed by (s, i, _, pi) not including context. Wiped out
    # when we go readonly as this set becomes a DFA state.
    self.configLookup = Set.new()
    # Indicates that this configuration set is part of a full context
    #  LL prediction. It will be used to determine how to merge $. With SLL
    #  it's a wildcard whereas it is not for LL context merge.
    self.fullCtx = _fullCtx
    # Indicates that the set of configurations is read-only. Do not
    #  allow any code to manipulate the set; DFA states will point at
    #  the sets and they must not change. This does not protect the other
    #  fields; in particular, conflictingAlts is set after
    #  we've made this readonly.
    self.readonly = false
    # Track the elements as they are added to the set; supports get(i)#/
    self.configs = Array.new
    # TODO: these fields make me pretty uncomfortable but nice to pack up info together, saves recomputation
    # TODO: can we track conflicts as they are added to save scanning configs later?
    self.uniqueAlt = 0
    self.conflictingAlts = nil

    # Used in parser and lexer. In lexer, it indicates we hit a pred
    # while computing a closure operation.  Don't make a DFA state from this.
    self.hasSemanticContext = false
    self.dipsIntoOuterContext = false
    self.cachedHashCode = -1
end

Instance Attribute Details

#cachedHashCodeObject

Returns the value of attribute cachedHashCode.



18
19
20
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 18

def cachedHashCode
  @cachedHashCode
end

#configLookupObject

Returns the value of attribute configLookup.



16
17
18
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 16

def configLookup
  @configLookup
end

#configsObject

Returns the value of attribute configs.



16
17
18
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 16

def configs
  @configs
end

#conflictingAltsObject

Returns the value of attribute conflictingAlts.



17
18
19
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 17

def conflictingAlts
  @conflictingAlts
end

#dipsIntoOuterContextObject

Returns the value of attribute dipsIntoOuterContext.



17
18
19
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 17

def dipsIntoOuterContext
  @dipsIntoOuterContext
end

#fullCtxObject

Returns the value of attribute fullCtx.



16
17
18
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 16

def fullCtx
  @fullCtx
end

#hasSemanticContextObject

Returns the value of attribute hasSemanticContext.



17
18
19
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 17

def hasSemanticContext
  @hasSemanticContext
end

#readonlyObject

Returns the value of attribute readonly.



16
17
18
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 16

def readonly
  @readonly
end

#uniqueAltObject

Returns the value of attribute uniqueAlt.



16
17
18
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 16

def uniqueAlt
  @uniqueAlt
end

Instance Method Details

#==(other) ⇒ Object



123
124
125
126
127
128
129
130
131
132
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 123

def ==(other)
    self.equal? other or other.kind_of? ATNConfigSet and \
        self.configs and \
        self.configs==other.configs and \
        self.fullCtx == other.fullCtx and \
        self.uniqueAlt == other.uniqueAlt and \
        self.conflictingAlts == other.conflictingAlts and \
        self.hasSemanticContext == other.hasSemanticContext and \
        self.dipsIntoOuterContext == other.dipsIntoOuterContext
end

#add(config, mergeCache = nil) ⇒ Object

Adding a new config means merging contexts with existing configs for (s, i, pi, _), where s is the ATNConfig#state, i is the ATNConfig#alt, and pi is the ATNConfig#semanticContext. We use (s,i,pi) as key.

<p>This method updates #dipsIntoOuterContext and #hasSemanticContext when necessary.</p> /

Raises:

  • (Exception)


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 57

def add(config, mergeCache=nil)
    raise Exception.new("This set is readonly") if self.readonly
    if ! config.semanticContext.equal? SemanticContext.NONE
        self.hasSemanticContext = true
    end
    if config.reachesIntoOuterContext > 0
        self.dipsIntoOuterContext = true
    end
    existing = self.getOrAdd(config)
    if existing.equal? config
        self.cachedHashCode = -1
        self.configs.push(config)  # track order here
        return true
    end
    # a previous (s,i,pi,_), merge with it and save result
    rootIsWildcard =  self.fullCtx.nil?
    merged = merge(existing.context, config.context, rootIsWildcard, mergeCache)
    # no need to check for existing.context, config.context in cache
    # since only way to create new graphs is "call rule" and here. We
    # cache at both places.
    existing.reachesIntoOuterContext = [existing.reachesIntoOuterContext, config.reachesIntoOuterContext].max
    existing.context = merged # replace context; no need to alt mapping
    return true
end

#addAll(coll) ⇒ Object



116
117
118
119
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 116

def addAll(coll)
    coll.each {|c| self.add(c) }
    return false
end

#clearObject



174
175
176
177
178
179
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 174

def clear
    raise IllegalStateException.new("This set is readonly") if self.readonly
    self.configs.clear()
    self.cachedHashCode = -1
    self.configLookup.clear()
end

#containsFast(obj) ⇒ Object

def __contains__(self, item)

    if self.configLookup is None
        raise UnsupportedOperationException("This method is not implemented for readonly sets.")
    return item in self.configLookup
end


167
168
169
170
171
172
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 167

def containsFast( obj)
    if self.configLookup.nil? 
        raise UnsupportedOperationException.new("This method is not implemented for readonly sets.")
    end
    return self.configLookup.containsFast(obj)
end

#empty?Boolean

def length

    return self.configs.length
end


155
156
157
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 155

def empty?
    self.configs.empty?
end

#eql?(other) ⇒ Boolean



120
121
122
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 120

def eql?(other)
  self == other
end

#get(i) ⇒ Object



103
104
105
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 103

def get(i)
    return self.configs[i]
end

#getOrAdd(config) ⇒ Object



81
82
83
84
85
86
87
88
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 81

def getOrAdd(config)
    if self.configLookup.member?(config) then
        self.configLookup.grep(config).first
    else
        self.configLookup.add(config)
        config
    end
end

#getPredicatesObject



94
95
96
97
98
99
100
101
102
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 94

def getPredicates
    preds = Array.new
    self.configs.each{|c|
        if not c.semanticContext.equal?(SemanticContext.NONE) then
            preds.push(c.semanticContext)
        end
    }
    return preds
end

#getStatesObject



89
90
91
92
93
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 89

def getStates
    states = Set.new()
    self.configs.each {|c| states.add(c.state) }
    return states
end

#hashObject



133
134
135
136
137
138
139
140
141
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 133

def hash
    if self.readonly
        if self.cachedHashCode == -1
            self.cachedHashCode = self.hashConfigs()
        end
        return self.cachedHashCode
    end
    return self.hashConfigs()
end

#hashConfigsObject



142
143
144
145
146
147
148
149
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 142

def hashConfigs
    StringIO.open  do |buf|
      self.configs.each { |cfg| 
          buf.write(cfg.to_s)
      }
      return buf.string().hash
    end
end

#isEmptyObject



158
159
160
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 158

def isEmpty
    return self.configs.empty?
end

#optimizeConfigs(interpreter) ⇒ Object



107
108
109
110
111
112
113
114
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 107

def optimizeConfigs(interpreter)
    raise IllegalStateException.new("This set is readonly") if self.readonly
  
    return if self.configLookup.empty?
    self.configs.each {|config|
        config.context = interpreter.getCachedContext(config.context)
    }
end

#setReadonly(readonly) ⇒ Object



180
181
182
183
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 180

def setReadonly(readonly)
    self.readonly = readonly
    self.configLookup = nil # can't mod, no need for lookup cache
end

#to_sObject



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/antlr4/atn/ATNConfigSet.rb', line 184

def to_s
    StringIO.open  do |buf|
        buf.write("[")
        buf.write( @configs.map {|x| x.to_s}.join(', ') )
        buf.write(']')  # @#{@configs.length}")
        if self.hasSemanticContext
            buf.write(",hasSemanticContext=")
            buf.write(self.hasSemanticContext.to_s)
        end
        if self.uniqueAlt!=ATN::INVALID_ALT_NUMBER
            buf.write(",uniqueAlt=")
            buf.write(self.uniqueAlt.to_s())
        end
        if self.conflictingAlts then
            buf.write(",conflictingAlts=")
            buf.write(self.conflictingAlts.to_s)
        end
        if self.dipsIntoOuterContext
            buf.write(",dipsIntoOuterContext")
        end
        return buf.string()
    end
end