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,23 @@
|
|
1
|
+
class TraceListener < ParseTreeListener
|
2
|
+
|
3
|
+
attr :parser
|
4
|
+
def initialize(parser=nil)
|
5
|
+
super()
|
6
|
+
if parser then
|
7
|
+
@parser = parser
|
8
|
+
end
|
9
|
+
end
|
10
|
+
def enterEveryRule(ctx)
|
11
|
+
puts "enter #{parser.ruleNames[ctx.ruleIndex]}, LT(1)=#{parser.input.LT(1).text.to_s}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def visitTerminal(node)
|
15
|
+
puts "consume #{node.symbol} rule #{parser.ruleNames[parser.ctx.ruleIndex]}"
|
16
|
+
end
|
17
|
+
def visitErrorNode(node)
|
18
|
+
end
|
19
|
+
|
20
|
+
def exitEveryRule(ctx)
|
21
|
+
puts "exit #{parser.ruleNames[ctx.ruleIndex]}, LT(1)=#{parser.input.LT(1).text}"
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
|
2
|
+
class ATN
|
3
|
+
INVALID_ALT_NUMBER = 0
|
4
|
+
def self.INVALID_ALT_NUMBER
|
5
|
+
ATN::INVALID_ALT_NUMBER
|
6
|
+
end
|
7
|
+
# Used for runtime deserialization of ATNs from strings#/
|
8
|
+
attr_accessor :grammarType, :maxTokenType, :states, :decisionToState
|
9
|
+
attr_accessor :ruleToStartState, :ruleToStopState, :modeNameToStartState
|
10
|
+
attr_accessor :ruleToTokenType, :lexerActions, :modeToStartState
|
11
|
+
def initialize(grammarType, maxTokenType)
|
12
|
+
# The type of the ATN.
|
13
|
+
@grammarType = grammarType
|
14
|
+
# The maximum value for any symbol recognized by a transition in the ATN.
|
15
|
+
@maxTokenType = maxTokenType
|
16
|
+
@states = Array.new
|
17
|
+
# Each subrule/rule is a decision point and we must track them so we
|
18
|
+
# can go back later and build DFA predictors for them. This includes
|
19
|
+
# all the rules, subrules, optional blocks, ()+, ()* etc...
|
20
|
+
@decisionToState = Array.new
|
21
|
+
# Maps from rule index to starting state number.
|
22
|
+
@ruleToStartState = Array.new
|
23
|
+
# Maps from rule index to stop state number.
|
24
|
+
@ruleToStopState = nil
|
25
|
+
@modeNameToStartState = Hash.new
|
26
|
+
# For lexer ATNs, this maps the rule index to the resulting token type.
|
27
|
+
# For parser ATNs, this maps the rule index to the generated bypass token
|
28
|
+
# type if the
|
29
|
+
# {@link ATNDeserializationOptions#isGenerateRuleBypassTransitions}
|
30
|
+
# deserialization option was specified; otherwise, this is {@code null}.
|
31
|
+
@ruleToTokenType = nil
|
32
|
+
# For lexer ATNs, this is an array of {@link LexerAction} objects which may
|
33
|
+
# be referenced by action transitions in the ATN.
|
34
|
+
@lexerActions = nil
|
35
|
+
@modeToStartState = Array.new
|
36
|
+
end
|
37
|
+
# Compute the set of valid tokens that can occur starting in state {@code s}.
|
38
|
+
# If {@code ctx} is null, the set of tokens will not include what can follow
|
39
|
+
# the rule surrounding {@code s}. In other words, the set will be
|
40
|
+
# restricted to tokens reachable staying within {@code s}'s rule.
|
41
|
+
def nextTokensInContext(s, ctx)
|
42
|
+
require 'antlr4/LL1Analyzer'
|
43
|
+
anal = LL1Analyzer.new(self)
|
44
|
+
return anal.LOOK(s, ctx=ctx)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Compute the set of valid tokens that can occur starting in {@code s} and
|
48
|
+
# staying in same rule. {@link Token#EPSILON} is in set if we reach end of
|
49
|
+
# rule.
|
50
|
+
def nextTokensNoContext(s)
|
51
|
+
if not s.nextTokenWithinRule.nil?
|
52
|
+
return s.nextTokenWithinRule
|
53
|
+
end
|
54
|
+
s.nextTokenWithinRule = self.nextTokensInContext(s,nil )
|
55
|
+
s.nextTokenWithinRule.readonly = true
|
56
|
+
return s.nextTokenWithinRule
|
57
|
+
end
|
58
|
+
def nextTokens(s, ctx= nil)
|
59
|
+
if ctx.nil?
|
60
|
+
return self.nextTokensNoContext(s)
|
61
|
+
else
|
62
|
+
return self.nextTokensInContext(s, ctx)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
def addState(state)
|
66
|
+
if not state.nil?
|
67
|
+
state.atn = self
|
68
|
+
state.stateNumber = self.states.length()
|
69
|
+
end
|
70
|
+
self.states.push(state)
|
71
|
+
end
|
72
|
+
|
73
|
+
def removeState(state)
|
74
|
+
self.states[state.stateNumber] = nil
|
75
|
+
end
|
76
|
+
def defineDecisionState(s)
|
77
|
+
self.decisionToState.push(s)
|
78
|
+
s.decision = self.decisionToState.length()-1
|
79
|
+
return s.decision
|
80
|
+
end
|
81
|
+
def getDecisionState(decision)
|
82
|
+
if self.decisionToState.length==0
|
83
|
+
return nil
|
84
|
+
else
|
85
|
+
return self.decisionToState[decision]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
# Computes the set of input symbols which could follow ATN state number
|
89
|
+
# {@code stateNumber} in the specified full {@code context}. This method
|
90
|
+
# considers the complete parser context, but does not evaluate semantic
|
91
|
+
# predicates (i.e. all predicates encountered during the calculation are
|
92
|
+
# assumed true). If a path in the ATN exists from the starting state to the
|
93
|
+
# {@link RuleStopState} of the outermost context without matching any
|
94
|
+
# symbols, {@link Token#EOF} is added to the returned set.
|
95
|
+
#
|
96
|
+
# <p>If {@code context} is {@code null}, it is treated as
|
97
|
+
# {@link ParserRuleContext#EMPTY}.</p>
|
98
|
+
#
|
99
|
+
# @param stateNumber the ATN state number
|
100
|
+
# @param context the full parse context
|
101
|
+
# @return The set of potentially valid input symbols which could follow the
|
102
|
+
# specified state in the specified context.
|
103
|
+
# @throws IllegalArgumentException if the ATN does not contain a state with
|
104
|
+
# number {@code stateNumber}
|
105
|
+
#/
|
106
|
+
def getExpectedTokens(stateNumber, ctx)
|
107
|
+
if stateNumber < 0 or stateNumber >= self.states.length
|
108
|
+
raise Exception.new("Invalid state number: #{stateNumber}.")
|
109
|
+
end
|
110
|
+
s = self.states[stateNumber]
|
111
|
+
following = self.nextTokens(s)
|
112
|
+
if not following.member? Token::EPSILON
|
113
|
+
return following
|
114
|
+
end
|
115
|
+
expected = IntervalSet.new()
|
116
|
+
expected.addSet(following)
|
117
|
+
#puts expected.to_s
|
118
|
+
expected.remove(Token::EPSILON)
|
119
|
+
#puts expected.to_s
|
120
|
+
while ( ctx and ctx.invokingState >= 0 and following.member?(Token::EPSILON) ) do
|
121
|
+
invokingState = self.states[ctx.invokingState]
|
122
|
+
rt = invokingState.transitions[0]
|
123
|
+
following = self.nextTokens(rt.followState)
|
124
|
+
expected.addSet(following)
|
125
|
+
expected.remove(Token::EPSILON)
|
126
|
+
ctx = ctx.parentCtx
|
127
|
+
end
|
128
|
+
if following.member?(Token::EPSILON) then
|
129
|
+
expected.addOne(Token::EOF)
|
130
|
+
end
|
131
|
+
return expected
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# A tuple: (ATN state, predicted alt, syntactic, semantic context).
|
2
|
+
# The syntactic context is a graph-structured stack node whose
|
3
|
+
# path(s) to the root is the rule invocation(s)
|
4
|
+
# chain used to arrive at the state. The semantic context is
|
5
|
+
# the tree of semantic predicates encountered before reaching
|
6
|
+
# an ATN state.
|
7
|
+
|
8
|
+
class ATNConfig
|
9
|
+
|
10
|
+
def self.createConfigState(config, state)
|
11
|
+
new(state,nil,nil,nil,config)
|
12
|
+
end
|
13
|
+
attr_accessor :reachesIntoOuterContext
|
14
|
+
attr_reader :state, :alt, :context, :semanticContext
|
15
|
+
attr_reader :hashcode
|
16
|
+
def initialize(state=nil, alt=nil, context=nil, semantic=nil, config=nil)
|
17
|
+
if config then
|
18
|
+
state = config.state if state.nil?
|
19
|
+
alt = config.alt if alt.nil?
|
20
|
+
context = config.context if context.nil?
|
21
|
+
semantic = config.semanticContext if semantic.nil?
|
22
|
+
semantic = SemanticContext.NONE if semantic.nil?
|
23
|
+
@reachesIntoOuterContext = config.reachesIntoOuterContext
|
24
|
+
else
|
25
|
+
# We cannot execute predicates dependent upon local context unless
|
26
|
+
# we know for sure we are in the correct context. Because there is
|
27
|
+
# no way to do this efficiently, we simply cannot evaluate
|
28
|
+
# dependent predicates unless we are in the rule that initially
|
29
|
+
# invokes the ATN simulator.
|
30
|
+
#
|
31
|
+
# closure() tracks the depth of how far we dip into the
|
32
|
+
# outer context: depth > 0. Note that it may not be totally
|
33
|
+
# accurate depth since I don't ever decrement. TODO: make it a boolean then
|
34
|
+
@reachesIntoOuterContext = 0
|
35
|
+
end
|
36
|
+
|
37
|
+
#if not isinstance(state, ATNState):
|
38
|
+
# pass
|
39
|
+
# The ATN state associated with this configuration#/
|
40
|
+
@state = state
|
41
|
+
# What alt (or lexer rule) is predicted by this configuration#/
|
42
|
+
@alt = alt
|
43
|
+
# The stack of invoking states leading to the rule/states associated
|
44
|
+
# with this config. We track only those contexts pushed during
|
45
|
+
# execution of the ATN simulator.
|
46
|
+
@context = context
|
47
|
+
@semanticContext = semantic
|
48
|
+
mk_hashcode
|
49
|
+
end
|
50
|
+
|
51
|
+
# An ATN configuration is equal to another if both have
|
52
|
+
# the same state, they predict the same alternative, and
|
53
|
+
# syntactic/semantic contexts are the same.
|
54
|
+
def eql?(other)
|
55
|
+
self == other
|
56
|
+
end
|
57
|
+
def ==(other)
|
58
|
+
self.equal?(other) or \
|
59
|
+
other.kind_of?(ATNConfig) and \
|
60
|
+
(@state.stateNumber==other.state.stateNumber and
|
61
|
+
@alt==other.alt and (@context==other.context) and
|
62
|
+
@semanticContext==other.semanticContext )
|
63
|
+
end
|
64
|
+
def context=(o)
|
65
|
+
@context = o
|
66
|
+
mk_hashcode
|
67
|
+
end
|
68
|
+
|
69
|
+
def mk_hashcode
|
70
|
+
@hashcode = "#{@state.stateNumber}/#{@alt}/#{@context}/#{@semanticContext}".hash
|
71
|
+
end
|
72
|
+
def hash
|
73
|
+
@hashcode
|
74
|
+
end
|
75
|
+
def toString(recog=nil, showAlt=true)
|
76
|
+
to_s(recog,showAlt)
|
77
|
+
end
|
78
|
+
def to_s(recog=nil, showAlt=true)
|
79
|
+
StringIO.open do |buf|
|
80
|
+
buf.write('(')
|
81
|
+
buf.write(self.state.to_s)
|
82
|
+
if showAlt then
|
83
|
+
buf.write(",")
|
84
|
+
buf.write(self.alt.to_s)
|
85
|
+
end
|
86
|
+
if self.context then
|
87
|
+
buf.write(",[")
|
88
|
+
buf.write(self.context.to_s)
|
89
|
+
buf.write("]")
|
90
|
+
end
|
91
|
+
if self.semanticContext and (! self.semanticContext.equal? SemanticContext.NONE) then
|
92
|
+
buf.write(",")
|
93
|
+
buf.write(self.semanticContext.to_s)
|
94
|
+
end
|
95
|
+
if self.reachesIntoOuterContext>0 then
|
96
|
+
buf.write(",up=")
|
97
|
+
buf.write(self.reachesIntoOuterContext.to_s)
|
98
|
+
end
|
99
|
+
buf.write(')')
|
100
|
+
return buf.string()
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
# need a forward declaration
|
105
|
+
|
106
|
+
class LexerATNConfig < ATNConfig
|
107
|
+
|
108
|
+
attr_accessor :passedThroughNonGreedyDecision, :lexerActionExecutor
|
109
|
+
def initialize(state, alt=nil, context=nil, semantic=SemanticContext.NONE, _lexerActionExecutor=nil, config=nil)
|
110
|
+
super(state, alt, context, semantic, config)
|
111
|
+
if config then
|
112
|
+
_lexerActionExecutor = config.lexerActionExecutor if _lexerActionExecutor.nil?
|
113
|
+
@passedThroughNonGreedyDecision = self.checkNonGreedyDecision(config, state)
|
114
|
+
else
|
115
|
+
@passedThroughNonGreedyDecision = false
|
116
|
+
end
|
117
|
+
# This is the backing field for {@link #getLexerActionExecutor}.
|
118
|
+
@lexerActionExecutor = _lexerActionExecutor
|
119
|
+
end
|
120
|
+
|
121
|
+
def hash
|
122
|
+
b = 0
|
123
|
+
b = 1 if self.passedThroughNonGreedyDecision
|
124
|
+
[self.state.stateNumber, self.alt, self.context,
|
125
|
+
self.semanticContext, b, self.lexerActionExecutor
|
126
|
+
].map(&:to_s).join('').hash
|
127
|
+
end
|
128
|
+
def eql?(other)
|
129
|
+
self == other
|
130
|
+
end
|
131
|
+
def ==(other)
|
132
|
+
return true if self.equal? other
|
133
|
+
return false unless other.kind_of? LexerATNConfig
|
134
|
+
if self.passedThroughNonGreedyDecision != other.passedThroughNonGreedyDecision
|
135
|
+
return false
|
136
|
+
end
|
137
|
+
if self.lexerActionExecutor == other.lexerActionExecutor
|
138
|
+
super(other)
|
139
|
+
else
|
140
|
+
false
|
141
|
+
end
|
142
|
+
end
|
143
|
+
def checkNonGreedyDecision(source, target)
|
144
|
+
source.passedThroughNonGreedyDecision or (target.kind_of?(DecisionState) and target.nonGreedy )
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,215 @@
|
|
1
|
+
# Specialized {@link Set}{@code <}{@link ATNConfig}{@code >} that can track
|
2
|
+
# info about the set, with support for combining similar configurations using a
|
3
|
+
# graph-structured stack.
|
4
|
+
|
5
|
+
class ATNConfigSet
|
6
|
+
# The reason that we need this is because we don't want the hash map to use
|
7
|
+
# the standard hash code and equals. We need all configurations with the same
|
8
|
+
# {@code (s,i,_,semctx)} to be equal. Unfortunately, this key effectively doubles
|
9
|
+
# the number of objects associated with ATNConfigs. The other solution is to
|
10
|
+
# use a hash table that lets us specify the equals/hashcode operation.
|
11
|
+
extend Forwardable
|
12
|
+
|
13
|
+
def_delegators :@configs, :size, :each, :map, :length
|
14
|
+
|
15
|
+
|
16
|
+
attr_accessor :configLookup, :fullCtx, :readonly, :configs, :uniqueAlt
|
17
|
+
attr_accessor :conflictingAlts, :hasSemanticContext, :dipsIntoOuterContext
|
18
|
+
attr_accessor :cachedHashCode
|
19
|
+
|
20
|
+
include PredictionContextFunctions
|
21
|
+
def initialize(_fullCtx=true)
|
22
|
+
# All configs but hashed by (s, i, _, pi) not including context. Wiped out
|
23
|
+
# when we go readonly as this set becomes a DFA state.
|
24
|
+
self.configLookup = Set.new()
|
25
|
+
# Indicates that this configuration set is part of a full context
|
26
|
+
# LL prediction. It will be used to determine how to merge $. With SLL
|
27
|
+
# it's a wildcard whereas it is not for LL context merge.
|
28
|
+
self.fullCtx = _fullCtx
|
29
|
+
# Indicates that the set of configurations is read-only. Do not
|
30
|
+
# allow any code to manipulate the set; DFA states will point at
|
31
|
+
# the sets and they must not change. This does not protect the other
|
32
|
+
# fields; in particular, conflictingAlts is set after
|
33
|
+
# we've made this readonly.
|
34
|
+
self.readonly = false
|
35
|
+
# Track the elements as they are added to the set; supports get(i)#/
|
36
|
+
self.configs = Array.new
|
37
|
+
# TODO: these fields make me pretty uncomfortable but nice to pack up info together, saves recomputation
|
38
|
+
# TODO: can we track conflicts as they are added to save scanning configs later?
|
39
|
+
self.uniqueAlt = 0
|
40
|
+
self.conflictingAlts = nil
|
41
|
+
|
42
|
+
# Used in parser and lexer. In lexer, it indicates we hit a pred
|
43
|
+
# while computing a closure operation. Don't make a DFA state from this.
|
44
|
+
self.hasSemanticContext = false
|
45
|
+
self.dipsIntoOuterContext = false
|
46
|
+
self.cachedHashCode = -1
|
47
|
+
end
|
48
|
+
# Adding a new config means merging contexts with existing configs for
|
49
|
+
# {@code (s, i, pi, _)}, where {@code s} is the
|
50
|
+
# {@link ATNConfig#state}, {@code i} is the {@link ATNConfig#alt}, and
|
51
|
+
# {@code pi} is the {@link ATNConfig#semanticContext}. We use
|
52
|
+
# {@code (s,i,pi)} as key.
|
53
|
+
#
|
54
|
+
# <p>This method updates {@link #dipsIntoOuterContext} and
|
55
|
+
# {@link #hasSemanticContext} when necessary.</p>
|
56
|
+
#/
|
57
|
+
def add(config, mergeCache=nil)
|
58
|
+
raise Exception.new("This set is readonly") if self.readonly
|
59
|
+
if ! config.semanticContext.equal? SemanticContext.NONE
|
60
|
+
self.hasSemanticContext = true
|
61
|
+
end
|
62
|
+
if config.reachesIntoOuterContext > 0
|
63
|
+
self.dipsIntoOuterContext = true
|
64
|
+
end
|
65
|
+
existing = self.getOrAdd(config)
|
66
|
+
if existing.equal? config
|
67
|
+
self.cachedHashCode = -1
|
68
|
+
self.configs.push(config) # track order here
|
69
|
+
return true
|
70
|
+
end
|
71
|
+
# a previous (s,i,pi,_), merge with it and save result
|
72
|
+
rootIsWildcard = self.fullCtx.nil?
|
73
|
+
merged = merge(existing.context, config.context, rootIsWildcard, mergeCache)
|
74
|
+
# no need to check for existing.context, config.context in cache
|
75
|
+
# since only way to create new graphs is "call rule" and here. We
|
76
|
+
# cache at both places.
|
77
|
+
existing.reachesIntoOuterContext = [existing.reachesIntoOuterContext, config.reachesIntoOuterContext].max
|
78
|
+
existing.context = merged # replace context; no need to alt mapping
|
79
|
+
return true
|
80
|
+
end
|
81
|
+
def getOrAdd(config)
|
82
|
+
if self.configLookup.member?(config) then
|
83
|
+
self.configLookup.grep(config).first
|
84
|
+
else
|
85
|
+
self.configLookup.add(config)
|
86
|
+
config
|
87
|
+
end
|
88
|
+
end
|
89
|
+
def getStates
|
90
|
+
states = Set.new()
|
91
|
+
self.configs.each {|c| states.add(c.state) }
|
92
|
+
return states
|
93
|
+
end
|
94
|
+
def getPredicates
|
95
|
+
preds = Array.new
|
96
|
+
self.configs.each{|c|
|
97
|
+
if not c.semanticContext.equal?(SemanticContext.NONE) then
|
98
|
+
preds.push(c.semanticContext)
|
99
|
+
end
|
100
|
+
}
|
101
|
+
return preds
|
102
|
+
end
|
103
|
+
def get(i)
|
104
|
+
return self.configs[i]
|
105
|
+
end
|
106
|
+
|
107
|
+
def optimizeConfigs(interpreter)
|
108
|
+
raise IllegalStateException.new("This set is readonly") if self.readonly
|
109
|
+
|
110
|
+
return if self.configLookup.empty?
|
111
|
+
self.configs.each {|config|
|
112
|
+
config.context = interpreter.getCachedContext(config.context)
|
113
|
+
}
|
114
|
+
end
|
115
|
+
|
116
|
+
def addAll(coll)
|
117
|
+
coll.each {|c| self.add(c) }
|
118
|
+
return false
|
119
|
+
end
|
120
|
+
def eql?(other)
|
121
|
+
self == other
|
122
|
+
end
|
123
|
+
def ==(other)
|
124
|
+
self.equal? other or other.kind_of? ATNConfigSet and \
|
125
|
+
self.configs and \
|
126
|
+
self.configs==other.configs and \
|
127
|
+
self.fullCtx == other.fullCtx and \
|
128
|
+
self.uniqueAlt == other.uniqueAlt and \
|
129
|
+
self.conflictingAlts == other.conflictingAlts and \
|
130
|
+
self.hasSemanticContext == other.hasSemanticContext and \
|
131
|
+
self.dipsIntoOuterContext == other.dipsIntoOuterContext
|
132
|
+
end
|
133
|
+
def hash
|
134
|
+
if self.readonly
|
135
|
+
if self.cachedHashCode == -1
|
136
|
+
self.cachedHashCode = self.hashConfigs()
|
137
|
+
end
|
138
|
+
return self.cachedHashCode
|
139
|
+
end
|
140
|
+
return self.hashConfigs()
|
141
|
+
end
|
142
|
+
def hashConfigs
|
143
|
+
StringIO.open do |buf|
|
144
|
+
self.configs.each { |cfg|
|
145
|
+
buf.write(cfg.to_s)
|
146
|
+
}
|
147
|
+
return buf.string().hash
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# def length
|
152
|
+
# return self.configs.length
|
153
|
+
# end
|
154
|
+
|
155
|
+
def empty?
|
156
|
+
self.configs.empty?
|
157
|
+
end
|
158
|
+
def isEmpty
|
159
|
+
return self.configs.empty?
|
160
|
+
end
|
161
|
+
|
162
|
+
# def __contains__(self, item)
|
163
|
+
# if self.configLookup is None
|
164
|
+
# raise UnsupportedOperationException("This method is not implemented for readonly sets.")
|
165
|
+
# return item in self.configLookup
|
166
|
+
# end
|
167
|
+
def containsFast( obj)
|
168
|
+
if self.configLookup.nil?
|
169
|
+
raise UnsupportedOperationException.new("This method is not implemented for readonly sets.")
|
170
|
+
end
|
171
|
+
return self.configLookup.containsFast(obj)
|
172
|
+
end
|
173
|
+
|
174
|
+
def clear
|
175
|
+
raise IllegalStateException.new("This set is readonly") if self.readonly
|
176
|
+
self.configs.clear()
|
177
|
+
self.cachedHashCode = -1
|
178
|
+
self.configLookup.clear()
|
179
|
+
end
|
180
|
+
def setReadonly(readonly)
|
181
|
+
self.readonly = readonly
|
182
|
+
self.configLookup = nil # can't mod, no need for lookup cache
|
183
|
+
end
|
184
|
+
def to_s
|
185
|
+
StringIO.open do |buf|
|
186
|
+
buf.write("[")
|
187
|
+
buf.write( @configs.map {|x| x.to_s}.join(', ') )
|
188
|
+
buf.write(']') # @#{@configs.length}")
|
189
|
+
if self.hasSemanticContext
|
190
|
+
buf.write(",hasSemanticContext=")
|
191
|
+
buf.write(self.hasSemanticContext.to_s)
|
192
|
+
end
|
193
|
+
if self.uniqueAlt!=ATN::INVALID_ALT_NUMBER
|
194
|
+
buf.write(",uniqueAlt=")
|
195
|
+
buf.write(self.uniqueAlt.to_s())
|
196
|
+
end
|
197
|
+
if self.conflictingAlts then
|
198
|
+
buf.write(",conflictingAlts=")
|
199
|
+
buf.write(self.conflictingAlts.to_s)
|
200
|
+
end
|
201
|
+
if self.dipsIntoOuterContext
|
202
|
+
buf.write(",dipsIntoOuterContext")
|
203
|
+
end
|
204
|
+
return buf.string()
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
class OrderedATNConfigSet < ATNConfigSet
|
210
|
+
|
211
|
+
def initialize()
|
212
|
+
super()
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|