antlr4-runtime 0.1.0
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/.gitignore +15 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +35 -0
- data/LICENSE.txt +21 -0
- data/README.md +65 -0
- data/Rakefile +6 -0
- data/antlr4-runtime.gemspec +30 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ext/rumourhash/Makefile +264 -0
- data/ext/rumourhash/extconf.rb +3 -0
- data/ext/rumourhash/rumourhash.c +59 -0
- data/lib/antlr4/runtime.rb +37 -0
- data/lib/antlr4/runtime/abstract_parse_tree_visitor.rb +43 -0
- data/lib/antlr4/runtime/abstract_predicate_transition.rb +11 -0
- data/lib/antlr4/runtime/action_transition.rb +29 -0
- data/lib/antlr4/runtime/ambiguity_info.rb +10 -0
- data/lib/antlr4/runtime/antlr_error_listener.rb +15 -0
- data/lib/antlr4/runtime/antlr_error_strategy.rb +24 -0
- data/lib/antlr4/runtime/antlr_file_stream.rb +17 -0
- data/lib/antlr4/runtime/antlr_input_stream.rb +6 -0
- data/lib/antlr4/runtime/array_2d_hash_set.rb +471 -0
- data/lib/antlr4/runtime/array_prediction_context.rb +76 -0
- data/lib/antlr4/runtime/atn.rb +100 -0
- data/lib/antlr4/runtime/atn_config.rb +140 -0
- data/lib/antlr4/runtime/atn_config_set.rb +150 -0
- data/lib/antlr4/runtime/atn_deserialization_options.rb +48 -0
- data/lib/antlr4/runtime/atn_deserializer.rb +737 -0
- data/lib/antlr4/runtime/atn_simulator.rb +69 -0
- data/lib/antlr4/runtime/atn_state.rb +118 -0
- data/lib/antlr4/runtime/atn_type.rb +8 -0
- data/lib/antlr4/runtime/atom_transition.rb +27 -0
- data/lib/antlr4/runtime/bail_error_strategy.rb +31 -0
- data/lib/antlr4/runtime/base_error_listener.rb +18 -0
- data/lib/antlr4/runtime/basic_block_start_state.rb +12 -0
- data/lib/antlr4/runtime/basic_state.rb +11 -0
- data/lib/antlr4/runtime/bit_set.rb +54 -0
- data/lib/antlr4/runtime/block_end_state.rb +15 -0
- data/lib/antlr4/runtime/block_start_state.rb +12 -0
- data/lib/antlr4/runtime/buffered_token_stream.rb +335 -0
- data/lib/antlr4/runtime/char_stream.rb +6 -0
- data/lib/antlr4/runtime/char_streams.rb +12 -0
- data/lib/antlr4/runtime/chunk.rb +4 -0
- data/lib/antlr4/runtime/code_point_char_stream.rb +83 -0
- data/lib/antlr4/runtime/common_token.rb +125 -0
- data/lib/antlr4/runtime/common_token_factory.rb +30 -0
- data/lib/antlr4/runtime/common_token_stream.rb +63 -0
- data/lib/antlr4/runtime/console_error_listener.rb +12 -0
- data/lib/antlr4/runtime/context_sensitivity_info.rb +7 -0
- data/lib/antlr4/runtime/decision_event_info.rb +19 -0
- data/lib/antlr4/runtime/decision_info.rb +36 -0
- data/lib/antlr4/runtime/decision_state.rb +15 -0
- data/lib/antlr4/runtime/default_error_strategy.rb +314 -0
- data/lib/antlr4/runtime/dfa.rb +97 -0
- data/lib/antlr4/runtime/dfa_serializer.rb +62 -0
- data/lib/antlr4/runtime/dfa_state.rb +109 -0
- data/lib/antlr4/runtime/diagnostic_error_listener.rb +58 -0
- data/lib/antlr4/runtime/double_key_map.rb +49 -0
- data/lib/antlr4/runtime/empty_prediction_context.rb +35 -0
- data/lib/antlr4/runtime/epsilon_transition.rb +27 -0
- data/lib/antlr4/runtime/equality_comparator.rb +4 -0
- data/lib/antlr4/runtime/error_info.rb +7 -0
- data/lib/antlr4/runtime/error_node.rb +5 -0
- data/lib/antlr4/runtime/error_node_impl.rb +12 -0
- data/lib/antlr4/runtime/failed_predicate_exception.rb +33 -0
- data/lib/antlr4/runtime/flexible_hash_map.rb +232 -0
- data/lib/antlr4/runtime/input_mismatch_exception.rb +20 -0
- data/lib/antlr4/runtime/int_stream.rb +31 -0
- data/lib/antlr4/runtime/integer.rb +14 -0
- data/lib/antlr4/runtime/interval.rb +111 -0
- data/lib/antlr4/runtime/interval_set.rb +540 -0
- data/lib/antlr4/runtime/lexer.rb +257 -0
- data/lib/antlr4/runtime/lexer_action.rb +12 -0
- data/lib/antlr4/runtime/lexer_action_executor.rb +75 -0
- data/lib/antlr4/runtime/lexer_action_type.rb +12 -0
- data/lib/antlr4/runtime/lexer_atn_config.rb +50 -0
- data/lib/antlr4/runtime/lexer_atn_simulator.rb +522 -0
- data/lib/antlr4/runtime/lexer_channel_action.rb +51 -0
- data/lib/antlr4/runtime/lexer_custom_action.rb +49 -0
- data/lib/antlr4/runtime/lexer_dfa_serializer.rb +12 -0
- data/lib/antlr4/runtime/lexer_indexed_custom_action.rb +49 -0
- data/lib/antlr4/runtime/lexer_mode_action.rb +51 -0
- data/lib/antlr4/runtime/lexer_more_action.rb +41 -0
- data/lib/antlr4/runtime/lexer_no_viable_alt_exception.rb +4 -0
- data/lib/antlr4/runtime/lexer_pop_mode_action.rb +41 -0
- data/lib/antlr4/runtime/lexer_push_mode_action.rb +51 -0
- data/lib/antlr4/runtime/lexer_skip_action.rb +43 -0
- data/lib/antlr4/runtime/lexer_type_action.rb +51 -0
- data/lib/antlr4/runtime/ll1_analyzer.rb +133 -0
- data/lib/antlr4/runtime/lookahead_event_info.rb +10 -0
- data/lib/antlr4/runtime/loop_end_state.rb +15 -0
- data/lib/antlr4/runtime/murmur_hash.rb +99 -0
- data/lib/antlr4/runtime/no_viable_alt_exception.rb +7 -0
- data/lib/antlr4/runtime/not_set_transition.rb +20 -0
- data/lib/antlr4/runtime/object_equality_comparator.rb +18 -0
- data/lib/antlr4/runtime/ordered_atn_config_set.rb +15 -0
- data/lib/antlr4/runtime/parse_cancellation_exception.rb +5 -0
- data/lib/antlr4/runtime/parse_tree.rb +7 -0
- data/lib/antlr4/runtime/parse_tree_listener.rb +4 -0
- data/lib/antlr4/runtime/parse_tree_visitor.rb +4 -0
- data/lib/antlr4/runtime/parser.rb +522 -0
- data/lib/antlr4/runtime/parser_atn_simulator.rb +1171 -0
- data/lib/antlr4/runtime/parser_rule_context.rb +186 -0
- data/lib/antlr4/runtime/plus_block_start_state.rb +11 -0
- data/lib/antlr4/runtime/plus_loopback_state.rb +12 -0
- data/lib/antlr4/runtime/precedence_predicate_transition.rb +31 -0
- data/lib/antlr4/runtime/predicate.rb +6 -0
- data/lib/antlr4/runtime/predicate_eval_info.rb +16 -0
- data/lib/antlr4/runtime/predicate_transition.rb +35 -0
- data/lib/antlr4/runtime/prediction_context.rb +103 -0
- data/lib/antlr4/runtime/prediction_context_cache.rb +28 -0
- data/lib/antlr4/runtime/prediction_context_utils.rb +407 -0
- data/lib/antlr4/runtime/prediction_mode.rb +213 -0
- data/lib/antlr4/runtime/profiling_atn_simulator.rb +149 -0
- data/lib/antlr4/runtime/proxy_error_listener.rb +33 -0
- data/lib/antlr4/runtime/range_transition.rb +29 -0
- data/lib/antlr4/runtime/recognition_exception.rb +17 -0
- data/lib/antlr4/runtime/recognizer.rb +136 -0
- data/lib/antlr4/runtime/rule_context.rb +131 -0
- data/lib/antlr4/runtime/rule_context_with_alt_num.rb +11 -0
- data/lib/antlr4/runtime/rule_node.rb +8 -0
- data/lib/antlr4/runtime/rule_start_state.rb +17 -0
- data/lib/antlr4/runtime/rule_stop_state.rb +12 -0
- data/lib/antlr4/runtime/rule_tag_token.rb +64 -0
- data/lib/antlr4/runtime/rule_transition.rb +29 -0
- data/lib/antlr4/runtime/semantic_context.rb +313 -0
- data/lib/antlr4/runtime/set_transition.rb +29 -0
- data/lib/antlr4/runtime/singleton_prediction_context.rb +56 -0
- data/lib/antlr4/runtime/star_block_start_state.rb +12 -0
- data/lib/antlr4/runtime/star_loop_entry_state.rb +17 -0
- data/lib/antlr4/runtime/star_loopback_state.rb +16 -0
- data/lib/antlr4/runtime/syntax_tree.rb +6 -0
- data/lib/antlr4/runtime/tag_chunk.rb +22 -0
- data/lib/antlr4/runtime/terminal_node.rb +5 -0
- data/lib/antlr4/runtime/terminal_node_impl.rb +50 -0
- data/lib/antlr4/runtime/text_chunk.rb +16 -0
- data/lib/antlr4/runtime/token.rb +13 -0
- data/lib/antlr4/runtime/token_stream.rb +13 -0
- data/lib/antlr4/runtime/token_tag_token.rb +22 -0
- data/lib/antlr4/runtime/tokens_start_state.rb +14 -0
- data/lib/antlr4/runtime/transition.rb +51 -0
- data/lib/antlr4/runtime/tree.rb +4 -0
- data/lib/antlr4/runtime/trees.rb +195 -0
- data/lib/antlr4/runtime/triple.rb +40 -0
- data/lib/antlr4/runtime/utils.rb +117 -0
- data/lib/antlr4/runtime/uuid.rb +46 -0
- data/lib/antlr4/runtime/version.rb +5 -0
- data/lib/antlr4/runtime/vocabulary.rb +12 -0
- data/lib/antlr4/runtime/vocabulary_impl.rb +82 -0
- data/lib/antlr4/runtime/wildcard_transition.rb +20 -0
- data/lib/antlr4/runtime/writable_token.rb +7 -0
- metadata +243 -0
|
@@ -0,0 +1,1171 @@
|
|
|
1
|
+
require 'antlr4/runtime/atn_simulator'
|
|
2
|
+
require 'antlr4/runtime/prediction_mode'
|
|
3
|
+
require 'antlr4/runtime/double_key_map'
|
|
4
|
+
|
|
5
|
+
module Antlr4::Runtime
|
|
6
|
+
|
|
7
|
+
class ParserATNSimulator < ATNSimulator
|
|
8
|
+
attr_accessor :debug
|
|
9
|
+
attr_accessor :debug_list_atn_decisions
|
|
10
|
+
attr_accessor :dfa_debug
|
|
11
|
+
attr_accessor :retry_debug
|
|
12
|
+
|
|
13
|
+
def self.get_safe_env(env_name)
|
|
14
|
+
ENV[env_name]
|
|
15
|
+
rescue StandardError
|
|
16
|
+
nil
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
TURN_OFF_LR_LOOP_ENTRY_BRANCH_OPT = get_safe_env('TURN_OFF_LR_LOOP_ENTRY_BRANCH_OPT')
|
|
20
|
+
|
|
21
|
+
def initialize(parser, atn, decision_to_dfa, shared_context_cache)
|
|
22
|
+
super(atn, shared_context_cache)
|
|
23
|
+
@parser = parser
|
|
24
|
+
@decision_to_dfa = decision_to_dfa
|
|
25
|
+
@mode = PredictionMode::LL
|
|
26
|
+
@merge_cache = nil
|
|
27
|
+
@_input = nil
|
|
28
|
+
@_start_index = nil
|
|
29
|
+
@_outer_context = nil
|
|
30
|
+
@_dfa = nil
|
|
31
|
+
|
|
32
|
+
@debug = false
|
|
33
|
+
@debug_list_atn_decisions = false
|
|
34
|
+
@dfa_debug = false
|
|
35
|
+
@retry_debug = false
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def clear_dfa
|
|
39
|
+
d = 0
|
|
40
|
+
while d < @decision_to_dfa.length
|
|
41
|
+
@decision_to_dfa[d] = DFA.new(atn.decision_state(d), d)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def adaptive_predict(input, decision, outer_ctx)
|
|
46
|
+
if @debug || @debug_list_atn_decisions
|
|
47
|
+
puts('adaptivePredict decision ' << decision.to_s << ' exec la(1)==' << lookahead_name(input) << ' line ' << input.lt(1).line.to_s << ':' << input.lt(1).char_position_in_line.to_s)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
@_input = input
|
|
51
|
+
@_start_index = input.index
|
|
52
|
+
@_outer_context = outer_ctx
|
|
53
|
+
dfa = @decision_to_dfa[decision]
|
|
54
|
+
@_dfa = dfa
|
|
55
|
+
|
|
56
|
+
m = input.mark
|
|
57
|
+
index = @_start_index
|
|
58
|
+
|
|
59
|
+
# Now we are certain to have a specific decision's DFA
|
|
60
|
+
# But, do we still need an initial state?
|
|
61
|
+
begin
|
|
62
|
+
dfa.precedence_dfa? ? s0 = dfa.precedence_start_state(parser.precedence) : s0 = dfa.s0
|
|
63
|
+
|
|
64
|
+
if s0.nil?
|
|
65
|
+
outer_ctx = ParserRuleContext::EMPTY if outer_ctx.nil?
|
|
66
|
+
if @debug || @debug_list_atn_decisions
|
|
67
|
+
puts('predictATN decision ' << dfa.decision.to_s << ' exec la(1)==' << lookahead_name(input) << ', outer_ctx=' << outer_ctx.to_s_recog(@parser))
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
full_ctx = false
|
|
71
|
+
s0_closure = compute_start_state(dfa.atn_start_state, ParserRuleContext::EMPTY, full_ctx)
|
|
72
|
+
|
|
73
|
+
if dfa.precedence_dfa?
|
|
74
|
+
dfa.s0.configs = s0_closure # not used for prediction but useful to know start configs anyway
|
|
75
|
+
s0_closure = apply_precedence_filter(s0_closure)
|
|
76
|
+
s0 = add_dfa_state(dfa, DFAState.new(s0_closure))
|
|
77
|
+
dfa.precedence_start_state(@parser.precedence, s0)
|
|
78
|
+
else
|
|
79
|
+
s0 = add_dfa_state(dfa, DFAState.new(s0_closure))
|
|
80
|
+
dfa.s0 = s0
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
alt = exec_atn(dfa, s0, input, index, outer_ctx)
|
|
85
|
+
if @debug
|
|
86
|
+
puts('DFA after predictATN: ' << dfa.to_s2(@parser.get_vocabulary))
|
|
87
|
+
end
|
|
88
|
+
return alt
|
|
89
|
+
ensure
|
|
90
|
+
@merge_cache = nil # wack cache after each prediction
|
|
91
|
+
@_dfa = nil
|
|
92
|
+
input.seek(index)
|
|
93
|
+
input.release(m)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def exec_atn(dfa, s0, input, start_index, outer_ctx)
|
|
98
|
+
if @debug || @debug_list_atn_decisions
|
|
99
|
+
puts('execATN decision ' << dfa.decision.to_s << ' exec la(1)==' << lookahead_name(input) << ' line ' << input.lt(1).line.to_s << ':' << input.lt(1).char_position_in_line.to_s)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
previous_d = s0
|
|
103
|
+
|
|
104
|
+
puts('s0 = ' << s0.to_s) if @debug
|
|
105
|
+
|
|
106
|
+
t = input.la(1)
|
|
107
|
+
|
|
108
|
+
loop do # while more work
|
|
109
|
+
d = existing_target_state(previous_d, t)
|
|
110
|
+
d = compute_target_state(dfa, previous_d, t) if d.nil?
|
|
111
|
+
|
|
112
|
+
if d == @@error
|
|
113
|
+
# if any configs in previous dipped into outer context, that
|
|
114
|
+
# means that input up to t actually finished entry rule
|
|
115
|
+
# at least for SLL decision. Full LL doesn' t dip into outer
|
|
116
|
+
# so don't need special case.
|
|
117
|
+
# We will get an error no matter what so delay until after
|
|
118
|
+
# decision better error message. Also, no reachable target
|
|
119
|
+
# ATN states in SLL implies LL will also get nowhere.
|
|
120
|
+
# If conflict in states that dip out, choose min since we
|
|
121
|
+
# will get error no matter what.
|
|
122
|
+
input.seek(start_index)
|
|
123
|
+
alt = syn_valid_or_sem_invalid_alt_that_finished_decision_entry_rule(previous_d.configs, outer_ctx)
|
|
124
|
+
return alt if alt != ATN::INVALID_ALT_NUMBER
|
|
125
|
+
|
|
126
|
+
exc = NoViableAltException.new
|
|
127
|
+
exc.recognizer = @parser
|
|
128
|
+
exc.input = input
|
|
129
|
+
exc.context = outer_ctx
|
|
130
|
+
exc.start_token = input.get(start_index)
|
|
131
|
+
exc.offending_token = input.lt(1)
|
|
132
|
+
exc.dead_end_configs = previous_d.configs
|
|
133
|
+
raise exc
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
if d.requires_full_context && @mode != PredictionMode::SLL
|
|
137
|
+
# IF PREDS, MIGHT RESOLVE TO SINGLE ALT => SLL (or syntax error)
|
|
138
|
+
conflicting_alts = d.configs.conflictingAlts
|
|
139
|
+
unless d.predicates.nil?
|
|
140
|
+
puts('DFA state has preds in DFA sim LL failover') if @debug
|
|
141
|
+
conflict_index = input.index
|
|
142
|
+
input.seek(start_index) if conflict_index != start_index
|
|
143
|
+
|
|
144
|
+
conflicting_alts = eval_semantic_context(d.predicates, outer_ctx, true)
|
|
145
|
+
if conflicting_alts.cardinality == 1
|
|
146
|
+
puts('Full LL avoided') if debug
|
|
147
|
+
return conflicting_alts.next_set_bit(0)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
if conflict_index != start_index
|
|
151
|
+
# restore the index so reporting the fallback to full
|
|
152
|
+
# context occurs with the index at the correct spot
|
|
153
|
+
input.seek(conflict_index)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
if @dfa_debug
|
|
158
|
+
puts('ctx sensitive state ' << outer_ctx.to_s << ' in ' << d.to_s)
|
|
159
|
+
end
|
|
160
|
+
full_ctx = true
|
|
161
|
+
s0_closure = compute_start_state(dfa.atn_start_state, outer_ctx, full_ctx)
|
|
162
|
+
report_attempting_full_context(dfa, conflicting_alts, d.configs, start_index, input.index)
|
|
163
|
+
alt = exec_atn_with_full_context(dfa, d, s0_closure, input, start_index, outer_ctx)
|
|
164
|
+
return alt
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
if d.is_accept_state
|
|
168
|
+
return d.prediction if d.predicates.nil?
|
|
169
|
+
|
|
170
|
+
stop_index = input.index
|
|
171
|
+
input.seek(start_index)
|
|
172
|
+
alts = eval_semantic_context(d.predicates, outer_ctx, true)
|
|
173
|
+
case alts.cardinality
|
|
174
|
+
when 0
|
|
175
|
+
exc = NoViableAltException.new
|
|
176
|
+
exc.recognizer = @parser
|
|
177
|
+
exc.input = input
|
|
178
|
+
exc.context = outer_ctx
|
|
179
|
+
exc.start_token = input.get(start_index)
|
|
180
|
+
exc.offending_token = input.lt(1)
|
|
181
|
+
exc.dead_end_configs = d.configs
|
|
182
|
+
raise exc
|
|
183
|
+
|
|
184
|
+
when 1
|
|
185
|
+
return alts.next_set_bit(0)
|
|
186
|
+
|
|
187
|
+
else # report ambiguity after predicate evaluation to make sure the correct
|
|
188
|
+
# set of ambig alts is reported.
|
|
189
|
+
report_ambiguity(dfa, d, start_index, stop_index, false, alts, d.configs)
|
|
190
|
+
return alts.next_set_bit(0)
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
previous_d = d
|
|
195
|
+
|
|
196
|
+
if t != IntStream::EOF
|
|
197
|
+
input.consume
|
|
198
|
+
t = input.la(1)
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def existing_target_state(prev_d, t)
|
|
204
|
+
edges = prev_d.edges
|
|
205
|
+
return nil if edges.nil? || (t + 1) < 0 || (t + 1) >= edges.length
|
|
206
|
+
|
|
207
|
+
edges[t + 1]
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def compute_target_state(dfa, prev_d, t)
|
|
211
|
+
reach = compute_reach_set(prev_d.configs, t, false)
|
|
212
|
+
if reach.nil?
|
|
213
|
+
add_dfa_edge(dfa, prev_d, t, @@error)
|
|
214
|
+
return @@error
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# create new target state we'll add to DFA after it's complete
|
|
218
|
+
d = DFAState.new(reach)
|
|
219
|
+
|
|
220
|
+
predicted_alt = unique_alt(reach)
|
|
221
|
+
|
|
222
|
+
if @debug
|
|
223
|
+
alt_sub_sets = PredictionMode.conflicting_alt_subsets(reach)
|
|
224
|
+
alt_sub_sets_str = '['
|
|
225
|
+
alt_sub_sets.each do |x|
|
|
226
|
+
alt_sub_sets_str << x.to_s
|
|
227
|
+
end
|
|
228
|
+
alt_sub_sets_str << ']'
|
|
229
|
+
puts('SLL alt_sub_sets=' << alt_sub_sets_str << ', configs=' << reach.to_s << ', predict=' << predicted_alt.to_s << ', allSubsetsConflict=' << PredictionMode.all_subsets_conflict?(alt_sub_sets).to_s << ', conflicting_alts=' << conflicting_alts(reach).to_s)
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
if predicted_alt != ATN::INVALID_ALT_NUMBER
|
|
233
|
+
# NO CONFLICT, UNIQUELY PREDICTED ALT
|
|
234
|
+
d.is_accept_state = true
|
|
235
|
+
d.configs.unique_alt = predicted_alt
|
|
236
|
+
d.prediction = predicted_alt
|
|
237
|
+
elsif PredictionMode.has_sll_conflict_terminating_prediction(@mode, reach)
|
|
238
|
+
# MORE THAN ONE VIABLE ALTERNATIVE
|
|
239
|
+
d.configs.conflictingAlts = conflicting_alts(reach)
|
|
240
|
+
d.requires_full_context = true
|
|
241
|
+
# in SLL-only mode, we will stop at this state and return the minimum alt
|
|
242
|
+
d.is_accept_state = true
|
|
243
|
+
d.prediction = d.configs.conflictingAlts.next_set_bit(0)
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
if d.is_accept_state && d.configs.has_semantic_context
|
|
247
|
+
predicate_dfa_state(d, atn.decision_state(dfa.decision))
|
|
248
|
+
d.prediction = ATN::INVALID_ALT_NUMBER unless d.predicates.nil?
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# all adds to dfa are done after we've created full D state
|
|
252
|
+
d = add_dfa_edge(dfa, prev_d, t, d)
|
|
253
|
+
d
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def predicate_dfa_state(dfa_state, decision_state) # We need to test all predicates, even in DFA states that
|
|
257
|
+
# uniquely predict alternative.
|
|
258
|
+
nalts = decision_state.number_of_transitions
|
|
259
|
+
# Update DFA so reach becomes accept state with (predicate,alt)
|
|
260
|
+
# pairs if preds found for conflicting alts
|
|
261
|
+
alts_to_collect_preds_from = conflicting_alts_or_unique_alt(dfa_state.configs)
|
|
262
|
+
alt_to_pred = preds_for_ambig_alts(alts_to_collect_preds_from, dfa_state.configs, nalts)
|
|
263
|
+
if !alt_to_pred.nil?
|
|
264
|
+
dfa_state.predicates = predicate_predictions(alts_to_collect_preds_from, alt_to_pred)
|
|
265
|
+
dfa_state.prediction = ATN::INVALID_ALT_NUMBER # make sure we use preds
|
|
266
|
+
else # There are preds in configs but they might go away
|
|
267
|
+
# when OR'd together like pend? || NONE == NONE. If neither
|
|
268
|
+
# alt has preds, resolve to min alt
|
|
269
|
+
dfa_state.prediction = alts_to_collect_preds_from.next_set_bit(0)
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
# comes back with reach.uniqueAlt set to a valid alt
|
|
274
|
+
def exec_atn_with_full_context(dfa, d, s0, input, start_index, outer_ctx)
|
|
275
|
+
if @debug || @debug_list_atn_decisions
|
|
276
|
+
puts('execATNWithFullContext ' << s0.to_s)
|
|
277
|
+
end
|
|
278
|
+
full_ctx = true
|
|
279
|
+
found_exact_ambig = false
|
|
280
|
+
reach = nil
|
|
281
|
+
previous = s0
|
|
282
|
+
input.seek(start_index)
|
|
283
|
+
t = input.la(1)
|
|
284
|
+
predicted_alt = 0
|
|
285
|
+
loop do # while more work
|
|
286
|
+
reach = compute_reach_set(previous, t, full_ctx)
|
|
287
|
+
if reach.nil?
|
|
288
|
+
# if any configs in previous dipped into outer context, that
|
|
289
|
+
# means that input up to t actually finished entry rule
|
|
290
|
+
# at least for LL decision. Full LL doesn't dip into outer
|
|
291
|
+
# so don't need special case.
|
|
292
|
+
# We will get an error no matter what so delay until after
|
|
293
|
+
# decision better error message. Also, no reachable target
|
|
294
|
+
# ATN states in SLL implies LL will also get nowhere.
|
|
295
|
+
# If conflict in states that dip out, choose min since we
|
|
296
|
+
# will get error no matter what.
|
|
297
|
+
|
|
298
|
+
input.seek(start_index)
|
|
299
|
+
alt = syn_valid_or_sem_invalid_alt_that_finished_decision_entry_rule(previous, outer_ctx)
|
|
300
|
+
return alt if alt != ATN::INVALID_ALT_NUMBER
|
|
301
|
+
|
|
302
|
+
exc = NoViableAltException.new
|
|
303
|
+
exc.recognizer = @parser
|
|
304
|
+
exc.input = input
|
|
305
|
+
exc.context = outer_ctx
|
|
306
|
+
exc.start_token = input.get(start_index)
|
|
307
|
+
exc.offending_token = input.lt(1)
|
|
308
|
+
exc.dead_end_configs = previous.configs
|
|
309
|
+
raise exc
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
alt_sub_sets = PredictionMode.conflicting_alt_subsets(reach)
|
|
313
|
+
if @debug
|
|
314
|
+
tmp = ''
|
|
315
|
+
alt_sub_sets.each do |as|
|
|
316
|
+
tmp << as.to_s
|
|
317
|
+
tmp << ' '
|
|
318
|
+
end
|
|
319
|
+
puts('LL alt_sub_sets=' << tmp << ', predict=' << PredictionMode.unique_alt(alt_sub_sets).to_s << ', resolvesToJustOneViableAlt=' << PredictionMode.resolves_to_just_one_viable_alt?(alt_sub_sets).to_s)
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
# puts("alt_sub_sets: "+alt_sub_sets)
|
|
323
|
+
# System.err.println("reach="+reach+", "+reach.conflicting_alts)
|
|
324
|
+
reach.unique_alt = unique_alt(reach)
|
|
325
|
+
# unique prediction?
|
|
326
|
+
if reach.unique_alt != ATN::INVALID_ALT_NUMBER
|
|
327
|
+
predicted_alt = reach.unique_alt
|
|
328
|
+
break
|
|
329
|
+
end
|
|
330
|
+
if @mode != PredictionMode::LL_EXACT_AMBIG_DETECTION
|
|
331
|
+
predicted_alt = PredictionMode.resolves_to_just_one_viable_alt?(alt_sub_sets)
|
|
332
|
+
break if predicted_alt != ATN::INVALID_ALT_NUMBER
|
|
333
|
+
else # In exact ambiguity mode, we never try to terminate early.
|
|
334
|
+
# Just keeps scarfing until we know what the conflict is
|
|
335
|
+
if PredictionMode.all_subsets_conflict?(alt_sub_sets) && PredictionMode.all_subsets_equal?(alt_sub_sets)
|
|
336
|
+
|
|
337
|
+
found_exact_ambig = true
|
|
338
|
+
predicted_alt = PredictionMode.single_viable_alt(alt_sub_sets)
|
|
339
|
+
break
|
|
340
|
+
end
|
|
341
|
+
# else there are multiple non-conflicting subsets or
|
|
342
|
+
# we're not sure what the ambiguity is yet.
|
|
343
|
+
# So, keep going.
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
previous = reach
|
|
347
|
+
if t != IntStream::EOF
|
|
348
|
+
input.consume
|
|
349
|
+
t = input.la(1)
|
|
350
|
+
end
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
# If the configuration set uniquely predicts an alternative,
|
|
354
|
+
# without conflict, then we know that it's a full LL decision
|
|
355
|
+
# not SLL.
|
|
356
|
+
if reach.unique_alt != ATN::INVALID_ALT_NUMBER
|
|
357
|
+
report_context_sensitivity(dfa, predicted_alt, reach, start_index, input.index)
|
|
358
|
+
return predicted_alt
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
report_ambiguity(dfa, d, start_index, input.index, found_exact_ambig, reach.alts, reach)
|
|
362
|
+
|
|
363
|
+
predicted_alt
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
def compute_reach_set(closure, t, full_ctx)
|
|
367
|
+
puts('in computeReachSet, starting closure: ' << closure.to_s) if @debug
|
|
368
|
+
|
|
369
|
+
@merge_cache = DoubleKeyMap.new if @merge_cache.nil?
|
|
370
|
+
|
|
371
|
+
intermediate = ATNConfigSet.new(full_ctx)
|
|
372
|
+
|
|
373
|
+
skipped_stop_states = nil
|
|
374
|
+
|
|
375
|
+
# First figure out where we can reach on input t
|
|
376
|
+
i = 0
|
|
377
|
+
while i < closure.configs.length
|
|
378
|
+
c = closure.configs[i]
|
|
379
|
+
puts('testing ' << token_name(t) << ' at ' << c.to_s) if @debug
|
|
380
|
+
|
|
381
|
+
if c.state.is_a? RuleStopState
|
|
382
|
+
if full_ctx || t == IntStream::EOF
|
|
383
|
+
skipped_stop_states = [] if skipped_stop_states.nil?
|
|
384
|
+
|
|
385
|
+
skipped_stop_states.push(c)
|
|
386
|
+
end
|
|
387
|
+
i += 1
|
|
388
|
+
next
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
n = c.state.number_of_transitions
|
|
392
|
+
ti = 0
|
|
393
|
+
while ti < n
|
|
394
|
+
trans = c.state.transition(ti)
|
|
395
|
+
target = reachable_target(trans, t)
|
|
396
|
+
unless target.nil?
|
|
397
|
+
atncfg = ATNConfig.new
|
|
398
|
+
atncfg.atn_config3(c, target)
|
|
399
|
+
intermediate.add(atncfg, @merge_cache)
|
|
400
|
+
end
|
|
401
|
+
ti += 1
|
|
402
|
+
end
|
|
403
|
+
i += 1
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
# Now figure out where the reach operation can take us...
|
|
407
|
+
|
|
408
|
+
reach = nil
|
|
409
|
+
|
|
410
|
+
if skipped_stop_states.nil? && t != Token::EOF
|
|
411
|
+
if intermediate.configs.size == 1
|
|
412
|
+
# Don' t pursue the closure if there is just one state.
|
|
413
|
+
# It can only have one alternative just add to result
|
|
414
|
+
# Also don't pursue the closure if there is unique alternative
|
|
415
|
+
# among the configurations.
|
|
416
|
+
reach = intermediate
|
|
417
|
+
elsif unique_alt(intermediate) != ATN::INVALID_ALT_NUMBER
|
|
418
|
+
# Also don't pursue the closure if there is unique alternative
|
|
419
|
+
# among the configurations.
|
|
420
|
+
reach = intermediate
|
|
421
|
+
end
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
if reach.nil?
|
|
425
|
+
reach = ATNConfigSet.new(full_ctx)
|
|
426
|
+
closure_busy = Set.new
|
|
427
|
+
treat_eof_as_epsilon = t == Token::EOF
|
|
428
|
+
i = 0
|
|
429
|
+
while i < intermediate.configs.length
|
|
430
|
+
c = intermediate.configs[i]
|
|
431
|
+
closure(c, reach, closure_busy, false, full_ctx, treat_eof_as_epsilon)
|
|
432
|
+
i += 1
|
|
433
|
+
end
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
if t == IntStream::EOF
|
|
437
|
+
reach = remove_all_configs_not_in_rule_stop_state(reach, reach == intermediate)
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
if !skipped_stop_states.nil? && (!full_ctx || !PredictionMode.has_config_in_rule_stop_state?(reach))
|
|
441
|
+
i = 0
|
|
442
|
+
while i < skipped_stop_states.length
|
|
443
|
+
c = skipped_stop_states[i]
|
|
444
|
+
reach.add(c, @merge_cache)
|
|
445
|
+
i += 1
|
|
446
|
+
end
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
return nil if reach.empty?
|
|
450
|
+
reach
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
def remove_all_configs_not_in_rule_stop_state(configs, look_to_end_of_rule)
|
|
454
|
+
return configs if PredictionMode.all_configs_in_rule_stop_states?(configs)
|
|
455
|
+
|
|
456
|
+
result = ATNConfigSet.new(configs.full_ctx)
|
|
457
|
+
i = 0
|
|
458
|
+
while i < configs.length
|
|
459
|
+
config = configs[i]
|
|
460
|
+
if config.state.is_a? RuleStopState
|
|
461
|
+
result.add(config, @merge_cache)
|
|
462
|
+
i += 1
|
|
463
|
+
next
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
if look_to_end_of_rule && config.state.only_has_epsilon_transitions
|
|
467
|
+
next_tokens = atn.next_tokens(config.state)
|
|
468
|
+
if next_tokens.include?(Token::EPSILON)
|
|
469
|
+
end_of_rule_state = atn.rule_to_stop_state[config.state.rule_index]
|
|
470
|
+
atncfg = ATNConfig.new
|
|
471
|
+
atncfg.atn_config3(config, end_of_rule_state)
|
|
472
|
+
result.add(atncfg, @merge_cache)
|
|
473
|
+
end
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
i += 1
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
result
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
def compute_start_state(p, ctx, full_ctx)
|
|
483
|
+
# always at least the implicit call to start rule
|
|
484
|
+
initial_context = PredictionContextUtils.from_rule_context(@atn, ctx)
|
|
485
|
+
configs = ATNConfigSet.new(full_ctx)
|
|
486
|
+
|
|
487
|
+
i = 0
|
|
488
|
+
while i < p.number_of_transitions
|
|
489
|
+
target = p.transition(i).target
|
|
490
|
+
c = ATNConfig.new
|
|
491
|
+
c.atn_config1(target, i + 1, initial_context)
|
|
492
|
+
closure_busy = Set.new
|
|
493
|
+
closure(c, configs, closure_busy, true, full_ctx, false)
|
|
494
|
+
i += 1
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
configs
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
def apply_precedence_filter(configs)
|
|
501
|
+
states_from_alt1 = Map.new
|
|
502
|
+
config_set = ATNConfigSet.new(configs.full_ctx)
|
|
503
|
+
i = 0
|
|
504
|
+
while i < configs.length
|
|
505
|
+
config = configs[i]
|
|
506
|
+
if config.alt != 1
|
|
507
|
+
i += 1
|
|
508
|
+
next
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
updated_context = config.semantic_context.eval_precedence(@parser, @_outer_context)
|
|
512
|
+
if updated_context.nil?
|
|
513
|
+
# the configuration was eliminated
|
|
514
|
+
i += 1
|
|
515
|
+
next
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
states_from_alt1.put(config.state.state_number, config.context)
|
|
519
|
+
if updated_context != config.semantic_context
|
|
520
|
+
atncfg = ATNConfig.new
|
|
521
|
+
atncfg.atn_config3(config, updated_context)
|
|
522
|
+
config_set.add(atncfg, @merge_cache)
|
|
523
|
+
else
|
|
524
|
+
config_set.add(config, @merge_cache)
|
|
525
|
+
end
|
|
526
|
+
i += 1
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
i = 0
|
|
530
|
+
while i < configs.length
|
|
531
|
+
config = configs[i]
|
|
532
|
+
if config.alt == 1
|
|
533
|
+
# already handled
|
|
534
|
+
i += 1
|
|
535
|
+
next
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
unless config.precedence_filter_suppressed?
|
|
539
|
+
|
|
540
|
+
context = states_from_alt1.get(config.state.state_number)
|
|
541
|
+
if !context.nil? && context.eql?(config.context)
|
|
542
|
+
# eliminated
|
|
543
|
+
i += 1
|
|
544
|
+
next
|
|
545
|
+
end
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
config_set.add(config, @merge_cache)
|
|
549
|
+
i += 1
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
config_set
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
def reachable_target(trans, ttype)
|
|
556
|
+
return trans.target if trans.matches(ttype, 0, atn.max_token_type)
|
|
557
|
+
|
|
558
|
+
nil
|
|
559
|
+
end
|
|
560
|
+
|
|
561
|
+
def preds_for_ambig_alts(ambig_alts, configs, n_alts)
|
|
562
|
+
alt_to_pred = []
|
|
563
|
+
i = 0
|
|
564
|
+
while i < configs.length
|
|
565
|
+
c = configs[i]
|
|
566
|
+
if ambig_alts.get(c.alt)
|
|
567
|
+
alt_to_pred[c.alt] = SemanticContext.or(alt_to_pred[c.alt], c.semantic_context)
|
|
568
|
+
end
|
|
569
|
+
i += 1
|
|
570
|
+
end
|
|
571
|
+
|
|
572
|
+
n_pred_alts = 0
|
|
573
|
+
i = 1
|
|
574
|
+
while i <= n_alts
|
|
575
|
+
if alt_to_pred[i].nil?
|
|
576
|
+
alt_to_pred[i] = SemanticContext::NONE
|
|
577
|
+
elsif alt_to_pred[i] != SemanticContext::NONE
|
|
578
|
+
n_pred_alts += 1
|
|
579
|
+
end
|
|
580
|
+
i += 1
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
# nonambig alts are nil in alt_to_pred
|
|
584
|
+
alt_to_pred = nil if n_pred_alts == 0
|
|
585
|
+
puts('getPredsForAmbigAlts result ' << alt_to_pred.to_s) if @debug
|
|
586
|
+
alt_to_pred
|
|
587
|
+
end
|
|
588
|
+
|
|
589
|
+
def predicate_predictions(ambig_alts, alt_to_pred)
|
|
590
|
+
pairs = []
|
|
591
|
+
contains_predicate = false
|
|
592
|
+
i = 1
|
|
593
|
+
while i < alt_to_pred.length
|
|
594
|
+
pred = alt_to_pred[i]
|
|
595
|
+
|
|
596
|
+
if !ambig_alts.nil? && ambig_alts.get(i)
|
|
597
|
+
pairs.add(DFAState.PredPrediction.new(pred, i))
|
|
598
|
+
end
|
|
599
|
+
contains_predicate = true if pred != SemanticContext::NONE
|
|
600
|
+
i += 1
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
return nil unless contains_predicate
|
|
604
|
+
|
|
605
|
+
# puts(Arrays.to_s(alt_to_pred)+"->"+pairs)
|
|
606
|
+
pairs.to_a
|
|
607
|
+
end
|
|
608
|
+
|
|
609
|
+
def syn_valid_or_sem_invalid_alt_that_finished_decision_entry_rule(configs, outer_ctx)
|
|
610
|
+
sets = split_according_to_semantic_validity(configs, outer_ctx)
|
|
611
|
+
sem_valid_configs = sets.a
|
|
612
|
+
sem_invalid_configs = sets.b
|
|
613
|
+
alt = alt_that_finished_decision_entry_rule(sem_valid_configs)
|
|
614
|
+
return alt if alt != ATN::INVALID_ALT_NUMBER # semantically/syntactically viable path exists
|
|
615
|
+
|
|
616
|
+
# Is there a syntactically valid path with a failed pred?
|
|
617
|
+
unless sem_invalid_configs.empty?
|
|
618
|
+
alt = alt_that_finished_decision_entry_rule(sem_invalid_configs)
|
|
619
|
+
return alt if alt != ATN::INVALID_ALT_NUMBER # syntactically viable path exists
|
|
620
|
+
end
|
|
621
|
+
ATN::INVALID_ALT_NUMBER
|
|
622
|
+
end
|
|
623
|
+
|
|
624
|
+
def alt_that_finished_decision_entry_rule(configs)
|
|
625
|
+
alts = IntervalSet.new
|
|
626
|
+
i = 0
|
|
627
|
+
while i < configs.configs.length
|
|
628
|
+
c = configs.configs[i]
|
|
629
|
+
depth = c.outer_context_depth
|
|
630
|
+
if depth > 0 || (c.state.is_a?(Antlr4::Runtime::RuleStopState) && c.context.empty_path?)
|
|
631
|
+
alts.add(c.alt)
|
|
632
|
+
end
|
|
633
|
+
i += 1
|
|
634
|
+
end
|
|
635
|
+
return ATN::INVALID_ALT_NUMBER if alts.intervals.empty?
|
|
636
|
+
|
|
637
|
+
alts.min_element
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
def split_according_to_semantic_validity(configs, outer_ctx)
|
|
641
|
+
succeeded = ATNConfigSet.new(configs.full_ctx)
|
|
642
|
+
failed = ATNConfigSet.new(configs.full_ctx)
|
|
643
|
+
i = 0
|
|
644
|
+
while i < configs.configs.length
|
|
645
|
+
c = configs.configs[i]
|
|
646
|
+
if c.semantic_context != SemanticContext::NONE
|
|
647
|
+
predicate_evaluation_result = eval_semantic_context(c.semantic_context, outer_ctx, c.alt, configs.full_ctx)
|
|
648
|
+
if predicate_evaluation_result
|
|
649
|
+
succeeded.add(c)
|
|
650
|
+
else
|
|
651
|
+
failed.add(c)
|
|
652
|
+
end
|
|
653
|
+
else
|
|
654
|
+
succeeded.add(c)
|
|
655
|
+
end
|
|
656
|
+
i += 1
|
|
657
|
+
end
|
|
658
|
+
|
|
659
|
+
pair = OpenStruct.new
|
|
660
|
+
pair.a = succeeded
|
|
661
|
+
pair.b = failed
|
|
662
|
+
pair
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
def eval_semantic_context1(pred_predictions, outer_ctx, complete)
|
|
666
|
+
predictions = BitSet.new
|
|
667
|
+
i = 0
|
|
668
|
+
while i < pred_predictions.length
|
|
669
|
+
pair = pred_predictions[i]
|
|
670
|
+
if pair.pred == SemanticContext::NONE
|
|
671
|
+
predictions.set(pair.alt)
|
|
672
|
+
break unless complete
|
|
673
|
+
i += 1
|
|
674
|
+
next
|
|
675
|
+
end
|
|
676
|
+
|
|
677
|
+
full_ctx = false # in dfa
|
|
678
|
+
predicate_evaluation_result = eval_semantic_context(pair.pred, outer_ctx, pair.alt, full_ctx)
|
|
679
|
+
if @debug || @dfa_debug
|
|
680
|
+
puts('eval pred ' << pair << '=' << predicate_evaluation_result)
|
|
681
|
+
end
|
|
682
|
+
|
|
683
|
+
unless predicate_evaluation_result
|
|
684
|
+
i += 1
|
|
685
|
+
next
|
|
686
|
+
end
|
|
687
|
+
|
|
688
|
+
puts('PREDICT ' << pair.alt) if @debug || @dfa_debug
|
|
689
|
+
predictions.set(pair.alt)
|
|
690
|
+
break unless complete
|
|
691
|
+
i += 1
|
|
692
|
+
end
|
|
693
|
+
|
|
694
|
+
predictions
|
|
695
|
+
end
|
|
696
|
+
|
|
697
|
+
def eval_semantic_context2(pred, parser_call_stack, _alt, _full_ctx)
|
|
698
|
+
pred.eval(parser, parser_call_stack)
|
|
699
|
+
end
|
|
700
|
+
|
|
701
|
+
def closure(config, configs, closure_busy, collect_predicates, full_ctx, treat_eof_as_epsilon)
|
|
702
|
+
initial_depth = 0
|
|
703
|
+
closure_checking_stop_state(config, configs, closure_busy, collect_predicates, full_ctx, initial_depth, treat_eof_as_epsilon)
|
|
704
|
+
end
|
|
705
|
+
|
|
706
|
+
def closure_checking_stop_state(config, configs, closure_busy, collect_predicates, full_ctx, depth, treat_eof_as_epsilon)
|
|
707
|
+
puts('closure(' << config.to_s2(@parser, true) << ')') if @debug
|
|
708
|
+
|
|
709
|
+
if config.state.is_a? RuleStopState
|
|
710
|
+
# We hit rule end. If we have context info, use it
|
|
711
|
+
# run thru all possible stack tops in ctx
|
|
712
|
+
if !config.context.empty?
|
|
713
|
+
i = 0
|
|
714
|
+
while i < config.context.size
|
|
715
|
+
if config.context.get_return_state(i) == PredictionContext::EMPTY_RETURN_STATE
|
|
716
|
+
if full_ctx
|
|
717
|
+
atncfg = ATNConfig.new
|
|
718
|
+
atncfg.atn_config6(config, config.state, EmptyPredictionContext::EMPTY)
|
|
719
|
+
configs.add(atncfg, @merge_cache)
|
|
720
|
+
i += 1
|
|
721
|
+
next
|
|
722
|
+
else # we have no context info, just chase follow links (if greedy)
|
|
723
|
+
if @debug
|
|
724
|
+
puts('FALLING off rule ' << rule_name(config.state.rule_index))
|
|
725
|
+
end
|
|
726
|
+
closure_(config, configs, closure_busy, collect_predicates, full_ctx, depth, treat_eof_as_epsilon)
|
|
727
|
+
end
|
|
728
|
+
i += 1
|
|
729
|
+
next
|
|
730
|
+
end
|
|
731
|
+
return_state = atn.states[config.context.get_return_state(i)]
|
|
732
|
+
new_context = config.context.get_parent(i) # "pop" return state
|
|
733
|
+
c = ATNConfig.new
|
|
734
|
+
c.atn_config2(return_state, config.alt, new_context, config.semantic_context)
|
|
735
|
+
# While we have context to pop back from, we may have
|
|
736
|
+
# gotten that context AFTER having falling off a rule.
|
|
737
|
+
# Make sure we track that we are now out of context.
|
|
738
|
+
#
|
|
739
|
+
# This assignment also propagates the
|
|
740
|
+
# isPrecedenceFilterSuppressed() value to the new
|
|
741
|
+
# configuration.
|
|
742
|
+
c.reaches_into_outer_context = config.reaches_into_outer_context
|
|
743
|
+
closure_checking_stop_state(c, configs, closure_busy, collect_predicates, full_ctx, depth - 1, treat_eof_as_epsilon)
|
|
744
|
+
i += 1
|
|
745
|
+
end
|
|
746
|
+
return
|
|
747
|
+
elsif full_ctx
|
|
748
|
+
# reached end of start rule
|
|
749
|
+
configs.add(config, @merge_cache)
|
|
750
|
+
return
|
|
751
|
+
else # else if we have no context info, just chase follow links (if greedy)
|
|
752
|
+
if @debug
|
|
753
|
+
puts('FALLING off rule ' << rule_name(config.state.rule_index))
|
|
754
|
+
end
|
|
755
|
+
end
|
|
756
|
+
end
|
|
757
|
+
|
|
758
|
+
closure_(config, configs, closure_busy, collect_predicates, full_ctx, depth, treat_eof_as_epsilon)
|
|
759
|
+
end
|
|
760
|
+
|
|
761
|
+
def closure_(config, configs, closure_busy, collect_predicates, full_ctx, depth, treat_eof_as_epsilon)
|
|
762
|
+
p = config.state
|
|
763
|
+
# optimization
|
|
764
|
+
unless p.only_has_epsilon_transitions
|
|
765
|
+
configs.add(config, @merge_cache)
|
|
766
|
+
# make sure to not return here, because EOF transitions can act as
|
|
767
|
+
# both epsilon transitions and non-epsilon transitions.
|
|
768
|
+
# if ( debug ) puts("added config "+configs)
|
|
769
|
+
end
|
|
770
|
+
|
|
771
|
+
i = 0
|
|
772
|
+
while i < p.number_of_transitions
|
|
773
|
+
if i == 0 && can_drop_loop_entry_edge_in_left_recursive_rule?(config)
|
|
774
|
+
i += 1
|
|
775
|
+
next
|
|
776
|
+
end
|
|
777
|
+
|
|
778
|
+
t = p.transition(i)
|
|
779
|
+
continue_collecting = !(t.is_a? ActionTransition) && collect_predicates
|
|
780
|
+
c = epsilon_target(config, t, continue_collecting, depth == 0, full_ctx, treat_eof_as_epsilon)
|
|
781
|
+
unless c.nil?
|
|
782
|
+
new_depth = depth
|
|
783
|
+
if config.state.is_a? RuleStopState
|
|
784
|
+
# target fell off end of rule mark resulting c as having dipped into outer context
|
|
785
|
+
# We can't get here if incoming config was rule stop and we had context
|
|
786
|
+
# track how far we dip into outer context. Might
|
|
787
|
+
# come in handy and we avoid evaluating context dependent
|
|
788
|
+
# preds if this is > 0.
|
|
789
|
+
|
|
790
|
+
if !@_dfa.nil? && @_dfa.precedence_dfa?
|
|
791
|
+
outermost_precedence_return = t.outermost_precedence_return
|
|
792
|
+
if outermost_precedence_return == @_dfa.atn_start_state.rule_index
|
|
793
|
+
c.precedence_filter_suppressed(true)
|
|
794
|
+
end
|
|
795
|
+
end
|
|
796
|
+
|
|
797
|
+
c.reaches_into_outer_context += 1
|
|
798
|
+
|
|
799
|
+
added = closure_busy.add?(c)
|
|
800
|
+
unless added
|
|
801
|
+
i += 1
|
|
802
|
+
next
|
|
803
|
+
end
|
|
804
|
+
|
|
805
|
+
configs.dips_into_outer_context = true # TODO: can remove? only care when we add to set per middle of this method
|
|
806
|
+
new_depth -= 1
|
|
807
|
+
puts('dips into outer ctx: ' << c.to_s) if @debug
|
|
808
|
+
else
|
|
809
|
+
added = closure_busy.add?(c)
|
|
810
|
+
if !t.epsilon? && !added
|
|
811
|
+
i += 1
|
|
812
|
+
next
|
|
813
|
+
end
|
|
814
|
+
|
|
815
|
+
if t.is_a? RuleTransition
|
|
816
|
+
# latch when new_depth goes negative - once we step out of the entry context we can't return
|
|
817
|
+
new_depth += 1 if new_depth >= 0
|
|
818
|
+
end
|
|
819
|
+
end
|
|
820
|
+
|
|
821
|
+
closure_checking_stop_state(c, configs, closure_busy, continue_collecting, full_ctx, new_depth, treat_eof_as_epsilon)
|
|
822
|
+
end
|
|
823
|
+
i += 1
|
|
824
|
+
end
|
|
825
|
+
end
|
|
826
|
+
|
|
827
|
+
def can_drop_loop_entry_edge_in_left_recursive_rule?(config)
|
|
828
|
+
return false if TURN_OFF_LR_LOOP_ENTRY_BRANCH_OPT
|
|
829
|
+
|
|
830
|
+
p = config.state
|
|
831
|
+
# First check to see if we are in StarLoopEntryState generated during
|
|
832
|
+
# left-recursion elimination. For efficiency, also check if
|
|
833
|
+
# the context has an empty stack case. If so, it would mean
|
|
834
|
+
# global FOLLOW so we can't perform optimization
|
|
835
|
+
if p.state_type != ATNState::STAR_LOOP_ENTRY || !p.is_precedence_pecision || # Are we the special loop entry/exit state?
|
|
836
|
+
config.context.empty? || # If SLL wildcard
|
|
837
|
+
config.context.empty_path?
|
|
838
|
+
|
|
839
|
+
return false
|
|
840
|
+
end
|
|
841
|
+
|
|
842
|
+
# Require all return states to return back to the same rule
|
|
843
|
+
# that p is in.
|
|
844
|
+
num_ctxs = config.context.size
|
|
845
|
+
i = 0
|
|
846
|
+
while i < num_ctxs
|
|
847
|
+
return_state = atn.states.get(config.context.get_return_state(i))
|
|
848
|
+
return false if return_state.rule_index != p.rule_index
|
|
849
|
+
|
|
850
|
+
i += 1
|
|
851
|
+
end
|
|
852
|
+
|
|
853
|
+
decision_start_state = p.transition(0).target
|
|
854
|
+
block_end_state_num = decision_start_state.end_state.state_number
|
|
855
|
+
block_end_state = atn.states.get(block_end_state_num)
|
|
856
|
+
|
|
857
|
+
# Verify that the top of each stack context leads to loop entry/exit
|
|
858
|
+
# state through epsilon edges and w/o leaving rule.
|
|
859
|
+
i = 0
|
|
860
|
+
while i < num_ctxs
|
|
861
|
+
return_state_number = config.context.get_return_state(i)
|
|
862
|
+
return_state = atn.states.get(return_state_number)
|
|
863
|
+
# all states must have single outgoing epsilon edge
|
|
864
|
+
if return_state.number_of_transitions != 1 || !return_state.transition(0).epsilon?
|
|
865
|
+
|
|
866
|
+
return false
|
|
867
|
+
end
|
|
868
|
+
|
|
869
|
+
# Look for prefix op case like 'not expr', (' type ')' expr
|
|
870
|
+
return_state_target = return_state.transition(0).target
|
|
871
|
+
if return_state.state_type == BLOCK_END && return_state_target == p
|
|
872
|
+
i += 1
|
|
873
|
+
next
|
|
874
|
+
end
|
|
875
|
+
# Look for 'expr op expr' or case where expr's return state is block end
|
|
876
|
+
# of (...)* internal block the block end points to loop back
|
|
877
|
+
# which points to p but we don't need to check that
|
|
878
|
+
if return_state == block_end_state
|
|
879
|
+
i += 1
|
|
880
|
+
next
|
|
881
|
+
end
|
|
882
|
+
# Look for ternary expr ? expr : expr. The return state points at block end,
|
|
883
|
+
# which points at loop entry state
|
|
884
|
+
if return_state_target == block_end_state
|
|
885
|
+
i += 1
|
|
886
|
+
next
|
|
887
|
+
end
|
|
888
|
+
# Look for complex prefix 'between expr and expr' case where 2nd expr's
|
|
889
|
+
# return state points at block end state of (...)* internal block
|
|
890
|
+
if return_state_target.state_type == BLOCK_END && return_state_target.number_of_transitions == 1 && return_state_target.transition(0).epsilon? && return_state_target.transition(0).target == p
|
|
891
|
+
|
|
892
|
+
i += 1
|
|
893
|
+
next
|
|
894
|
+
end
|
|
895
|
+
|
|
896
|
+
# anything else ain't conforming
|
|
897
|
+
return false
|
|
898
|
+
end
|
|
899
|
+
|
|
900
|
+
true
|
|
901
|
+
end
|
|
902
|
+
|
|
903
|
+
def rule_name(index)
|
|
904
|
+
return @parser.rule_names[index] if !@parser.nil? && index >= 0
|
|
905
|
+
|
|
906
|
+
'<rule ' << index << '>'
|
|
907
|
+
end
|
|
908
|
+
|
|
909
|
+
def epsilon_target(config, t, collect_predicates, in_context, full_ctx, treat_eof_as_epsilon)
|
|
910
|
+
case t.serialization_type
|
|
911
|
+
when Transition::RULE
|
|
912
|
+
rule_transition(config, t)
|
|
913
|
+
|
|
914
|
+
when Transition::PRECEDENCE
|
|
915
|
+
precedence_transition(config, t, collect_predicates, in_context, full_ctx)
|
|
916
|
+
|
|
917
|
+
when Transition::PREDICATE
|
|
918
|
+
pred_transition(config, t, collect_predicates, in_context, full_ctx)
|
|
919
|
+
|
|
920
|
+
when Transition::ACTION
|
|
921
|
+
action_transition(config, t)
|
|
922
|
+
|
|
923
|
+
when Transition::EPSILON
|
|
924
|
+
c = ATNConfig.new
|
|
925
|
+
c.atn_config3(config, t.target)
|
|
926
|
+
c
|
|
927
|
+
|
|
928
|
+
when Transition::ATOM, Transition::RANGE, Transition::SET
|
|
929
|
+
# EOF transitions act like epsilon transitions after the first EOF
|
|
930
|
+
# transition is traversed
|
|
931
|
+
if treat_eof_as_epsilon
|
|
932
|
+
if t.matches(Token::EOF, 0, 1)
|
|
933
|
+
c = ATNConfig.new
|
|
934
|
+
c.atn_config3(config, t.target)
|
|
935
|
+
return c
|
|
936
|
+
end
|
|
937
|
+
end
|
|
938
|
+
|
|
939
|
+
return nil
|
|
940
|
+
|
|
941
|
+
end
|
|
942
|
+
end
|
|
943
|
+
|
|
944
|
+
def action_transition(config, t)
|
|
945
|
+
puts('ACTION edge ' << t.rule_index << ':' << t.action_index) if @debug
|
|
946
|
+
c = ATNConfig.new
|
|
947
|
+
c.atn_config3(config, t.target)
|
|
948
|
+
c
|
|
949
|
+
end
|
|
950
|
+
|
|
951
|
+
def precedence_transition(config, pt, collect_predicates, in_context, full_ctx)
|
|
952
|
+
if @debug
|
|
953
|
+
puts('PRED (collect_predicates=' << collect_predicates << ') ' << pt.precedence << '>=_p' << ', ctx dependent=true')
|
|
954
|
+
unless @parser.nil?
|
|
955
|
+
puts('context surrounding pred is ' << @parser.getRuleInvocationStack)
|
|
956
|
+
end
|
|
957
|
+
end
|
|
958
|
+
|
|
959
|
+
c = nil
|
|
960
|
+
if collect_predicates && in_context
|
|
961
|
+
if full_ctx
|
|
962
|
+
# In full context mode, we can evaluate predicates on-the-fly
|
|
963
|
+
# during closure, which dramatically reduces the size of
|
|
964
|
+
# the config sets. It also obviates the need to test predicates
|
|
965
|
+
# later during conflict resolution.
|
|
966
|
+
current_position = @_input.index
|
|
967
|
+
@_input.seek(@_start_index)
|
|
968
|
+
pred_succeeds = eval_semantic_context(pt.predicate, @_outer_context, config.alt, full_ctx)
|
|
969
|
+
@_input.seek(current_position)
|
|
970
|
+
if pred_succeeds
|
|
971
|
+
c = ATNConfig.new
|
|
972
|
+
c.atn_config3(config, pt.target) # no pred context
|
|
973
|
+
end
|
|
974
|
+
else
|
|
975
|
+
new_sem_ctx = SemanticContext.and(config.semantic_context, pt.predicate)
|
|
976
|
+
c = ATNConfig.new
|
|
977
|
+
c.atn_config4(config, pt.target, new_sem_ctx)
|
|
978
|
+
end
|
|
979
|
+
else
|
|
980
|
+
c = ATNConfig.new
|
|
981
|
+
c.atn_config3(config, pt.target)
|
|
982
|
+
end
|
|
983
|
+
|
|
984
|
+
puts('config from pred transition=' << c) if @debug
|
|
985
|
+
c
|
|
986
|
+
end
|
|
987
|
+
|
|
988
|
+
def pred_transition(config, pt, collect_predicates, in_context, full_ctx)
|
|
989
|
+
if @debug
|
|
990
|
+
puts('PRED (collect_predicates=' << collect_predicates << ') ' << pt.rule_index << ':' << pt.pred_index << ', ctx dependent=' << pt.is_ctx_dependent)
|
|
991
|
+
unless @parser.nil?
|
|
992
|
+
puts('context surrounding pred is ' << @parser.getRuleInvocationStack)
|
|
993
|
+
end
|
|
994
|
+
end
|
|
995
|
+
|
|
996
|
+
c = nil
|
|
997
|
+
if collect_predicates && (!pt.is_ctx_dependent || (pt.is_ctx_dependent && in_context))
|
|
998
|
+
|
|
999
|
+
if full_ctx
|
|
1000
|
+
# In full context mode, we can evaluate predicates on-the-fly
|
|
1001
|
+
# during closure, which dramatically reduces the size of
|
|
1002
|
+
# the config sets. It also obviates the need to test predicates
|
|
1003
|
+
# later during conflict resolution.
|
|
1004
|
+
current_position = @_input.index
|
|
1005
|
+
@_input.seek(@_start_index)
|
|
1006
|
+
pred_succeeds = eval_semantic_context(pt.predicate, @_outer_context, config.alt, full_ctx)
|
|
1007
|
+
@_input.seek(current_position)
|
|
1008
|
+
if pred_succeeds
|
|
1009
|
+
c = ATNConfig.new
|
|
1010
|
+
c.atn_config3(config, pt.target) # no pred context
|
|
1011
|
+
end
|
|
1012
|
+
else
|
|
1013
|
+
new_sem_ctx = SemanticContext.and(config.semantic_context, pt.predicate)
|
|
1014
|
+
c = ATNConfig.new
|
|
1015
|
+
c.atn_config4(config, pt.target, new_sem_ctx)
|
|
1016
|
+
end
|
|
1017
|
+
else
|
|
1018
|
+
c = ATNConfig.new
|
|
1019
|
+
c.atn_config3(config, pt.target)
|
|
1020
|
+
end
|
|
1021
|
+
|
|
1022
|
+
puts('config from pred transition=' << c) if debug
|
|
1023
|
+
c
|
|
1024
|
+
end
|
|
1025
|
+
|
|
1026
|
+
def rule_transition(config, t)
|
|
1027
|
+
if @debug
|
|
1028
|
+
puts('CALL rule ' << rule_name(t.target.rule_index) << ', ctx=' << config.context.to_s)
|
|
1029
|
+
end
|
|
1030
|
+
|
|
1031
|
+
return_state = t.follow_state
|
|
1032
|
+
new_context = SingletonPredictionContext.new(config.context, return_state.state_number)
|
|
1033
|
+
c = ATNConfig.new
|
|
1034
|
+
c.atn_config6(config, t.target, new_context)
|
|
1035
|
+
c
|
|
1036
|
+
end
|
|
1037
|
+
|
|
1038
|
+
def conflicting_alts(configs)
|
|
1039
|
+
altsets = PredictionMode.conflicting_alt_subsets(configs)
|
|
1040
|
+
PredictionMode.get_alts1(altsets)
|
|
1041
|
+
end
|
|
1042
|
+
|
|
1043
|
+
def conflicting_alts_or_unique_alt(configs)
|
|
1044
|
+
if configs.unique_alt != ATN::INVALID_ALT_NUMBER
|
|
1045
|
+
conflict_alts = new BitSet
|
|
1046
|
+
conflict_alts.set(configs.unique_alt)
|
|
1047
|
+
else
|
|
1048
|
+
conflict_alts = configs.conflictingAlts
|
|
1049
|
+
end
|
|
1050
|
+
conflict_alts
|
|
1051
|
+
end
|
|
1052
|
+
|
|
1053
|
+
def token_name(t)
|
|
1054
|
+
return 'EOF' if t == Token::EOF
|
|
1055
|
+
|
|
1056
|
+
vocabulary = !@parser.nil? ? @parser.get_vocabulary : VocabularyImpl.EMPTY_VOCABULARY
|
|
1057
|
+
display_name = vocabulary.display_name(t)
|
|
1058
|
+
return display_name if display_name == t.to_s
|
|
1059
|
+
|
|
1060
|
+
result = ''
|
|
1061
|
+
result << display_name
|
|
1062
|
+
result << '<' << t.to_s << '>'
|
|
1063
|
+
end
|
|
1064
|
+
|
|
1065
|
+
def lookahead_name(input)
|
|
1066
|
+
token_name(input.la(1))
|
|
1067
|
+
end
|
|
1068
|
+
|
|
1069
|
+
def dump_dead_end_configs(nvae)
|
|
1070
|
+
STDERR.puts('dead end configs: ')
|
|
1071
|
+
nvae.getDeadEndConfigs.each do |c|
|
|
1072
|
+
trans = 'no edges'
|
|
1073
|
+
if c.state.number_of_transitions > 0
|
|
1074
|
+
t = c.state.transition(0)
|
|
1075
|
+
if t.is_a? AtomTransition
|
|
1076
|
+
at = t
|
|
1077
|
+
trans = 'Atom ' << token_name(at.label)
|
|
1078
|
+
elsif t.is_a? SetTransition
|
|
1079
|
+
st = t
|
|
1080
|
+
nott = st.is_a? NotSetTransition
|
|
1081
|
+
trans = (nott ? '~' : '') << 'Set ' << st.set.to_s
|
|
1082
|
+
end
|
|
1083
|
+
end
|
|
1084
|
+
STDERR.puts(c.to_s(@parser, true) << ':' << trans)
|
|
1085
|
+
end
|
|
1086
|
+
end
|
|
1087
|
+
|
|
1088
|
+
def unique_alt(configs)
|
|
1089
|
+
alt = ATN::INVALID_ALT_NUMBER
|
|
1090
|
+
i = 0
|
|
1091
|
+
while i < configs.configs.length
|
|
1092
|
+
c = configs.configs[i]
|
|
1093
|
+
if alt == ATN::INVALID_ALT_NUMBER
|
|
1094
|
+
alt = c.alt # found first alt
|
|
1095
|
+
elsif c.alt != alt
|
|
1096
|
+
return ATN::INVALID_ALT_NUMBER
|
|
1097
|
+
end
|
|
1098
|
+
i += 1
|
|
1099
|
+
end
|
|
1100
|
+
alt
|
|
1101
|
+
end
|
|
1102
|
+
|
|
1103
|
+
def add_dfa_edge(dfa, from, t, to)
|
|
1104
|
+
if @debug
|
|
1105
|
+
puts('EDGE ' << from.to_s << ' -> ' << to.to_s << ' upon ' << token_name(t))
|
|
1106
|
+
end
|
|
1107
|
+
|
|
1108
|
+
return nil if to.nil?
|
|
1109
|
+
|
|
1110
|
+
to = add_dfa_state(dfa, to) # used existing if possible not incoming
|
|
1111
|
+
return to if from.nil? || t < -1 || t > atn.max_token_type
|
|
1112
|
+
|
|
1113
|
+
from.edges = [] if from.edges.nil?
|
|
1114
|
+
|
|
1115
|
+
from.edges[t + 1] = to # connect
|
|
1116
|
+
|
|
1117
|
+
if @debug
|
|
1118
|
+
puts("DFA=\n" << dfa.to_s2(!@parser.nil? ? @parser.get_vocabulary : VocabularyImpl.EMPTY_VOCABULARY))
|
|
1119
|
+
end
|
|
1120
|
+
|
|
1121
|
+
to
|
|
1122
|
+
end
|
|
1123
|
+
|
|
1124
|
+
def add_dfa_state(dfa, d)
|
|
1125
|
+
return d if d == @@error
|
|
1126
|
+
|
|
1127
|
+
existing = dfa.states[d]
|
|
1128
|
+
return existing unless existing.nil?
|
|
1129
|
+
|
|
1130
|
+
d.state_number = dfa.states.size
|
|
1131
|
+
unless d.configs.readonly
|
|
1132
|
+
d.configs.optimize_configs(self)
|
|
1133
|
+
d.configs.readonly = true
|
|
1134
|
+
end
|
|
1135
|
+
dfa.states[d] = d
|
|
1136
|
+
puts('adding new DFA state: ' << d.to_s) if @debug
|
|
1137
|
+
d
|
|
1138
|
+
end
|
|
1139
|
+
|
|
1140
|
+
def report_attempting_full_context(dfa, conflict_alts, configs, start_index, stop_index)
|
|
1141
|
+
if @debug || @retry_debug
|
|
1142
|
+
interval = Interval.of(start_index, stop_index)
|
|
1143
|
+
puts('reportAttemptingFullContext decision=' << dfa.decision.to_s << ':' << configs.to_s << ', input=' << @parser._input.text2(interval).to_s)
|
|
1144
|
+
end
|
|
1145
|
+
unless @parser.nil?
|
|
1146
|
+
@parser.error_listener_dispatch.report_attempting_full_context(@parser, dfa, start_index, stop_index, conflict_alts, configs)
|
|
1147
|
+
end
|
|
1148
|
+
end
|
|
1149
|
+
|
|
1150
|
+
def report_context_sensitivity(dfa, prediction, configs, start_index, stop_index)
|
|
1151
|
+
if @debug || @retry_debug
|
|
1152
|
+
interval = Interval.of(start_index, stop_index)
|
|
1153
|
+
puts('reportContextSensitivity decision=' << dfa.decision.to_s << ':' << configs.to_s << ', input=' << @parser._input.text2(interval).to_s)
|
|
1154
|
+
end
|
|
1155
|
+
unless @parser.nil?
|
|
1156
|
+
@parser.error_listener_dispatch.report_context_sensitivity(@parser, dfa, start_index, stop_index, prediction, configs)
|
|
1157
|
+
end
|
|
1158
|
+
end
|
|
1159
|
+
|
|
1160
|
+
def report_ambiguity(dfa, _d, start_index, stop_index, exact, ambig_alts, configs) # configs that LL not SLL considered conflicting
|
|
1161
|
+
if @debug || @retry_debug
|
|
1162
|
+
interval = Interval.of(start_index, stop_index)
|
|
1163
|
+
puts('reportAmbiguity ' << ambig_alts.to_s << ':' << configs.to_s << ', input=' << @parser._input.text2(interval).to_s)
|
|
1164
|
+
end
|
|
1165
|
+
unless @parser.nil?
|
|
1166
|
+
@parser.error_listener_dispatch.report_ambiguity(@parser, dfa, start_index, stop_index, exact, ambig_alts, configs)
|
|
1167
|
+
end
|
|
1168
|
+
end
|
|
1169
|
+
|
|
1170
|
+
end
|
|
1171
|
+
end
|