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

Returns a new instance of 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

Returns:

  • (Boolean)


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

def empty?
    self.configs.empty?
end

#eql?(other) ⇒ Boolean

Returns:

  • (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