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.
Files changed (156) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +7 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +4 -0
  7. data/Gemfile.lock +35 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +65 -0
  10. data/Rakefile +6 -0
  11. data/antlr4-runtime.gemspec +30 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/ext/rumourhash/Makefile +264 -0
  15. data/ext/rumourhash/extconf.rb +3 -0
  16. data/ext/rumourhash/rumourhash.c +59 -0
  17. data/lib/antlr4/runtime.rb +37 -0
  18. data/lib/antlr4/runtime/abstract_parse_tree_visitor.rb +43 -0
  19. data/lib/antlr4/runtime/abstract_predicate_transition.rb +11 -0
  20. data/lib/antlr4/runtime/action_transition.rb +29 -0
  21. data/lib/antlr4/runtime/ambiguity_info.rb +10 -0
  22. data/lib/antlr4/runtime/antlr_error_listener.rb +15 -0
  23. data/lib/antlr4/runtime/antlr_error_strategy.rb +24 -0
  24. data/lib/antlr4/runtime/antlr_file_stream.rb +17 -0
  25. data/lib/antlr4/runtime/antlr_input_stream.rb +6 -0
  26. data/lib/antlr4/runtime/array_2d_hash_set.rb +471 -0
  27. data/lib/antlr4/runtime/array_prediction_context.rb +76 -0
  28. data/lib/antlr4/runtime/atn.rb +100 -0
  29. data/lib/antlr4/runtime/atn_config.rb +140 -0
  30. data/lib/antlr4/runtime/atn_config_set.rb +150 -0
  31. data/lib/antlr4/runtime/atn_deserialization_options.rb +48 -0
  32. data/lib/antlr4/runtime/atn_deserializer.rb +737 -0
  33. data/lib/antlr4/runtime/atn_simulator.rb +69 -0
  34. data/lib/antlr4/runtime/atn_state.rb +118 -0
  35. data/lib/antlr4/runtime/atn_type.rb +8 -0
  36. data/lib/antlr4/runtime/atom_transition.rb +27 -0
  37. data/lib/antlr4/runtime/bail_error_strategy.rb +31 -0
  38. data/lib/antlr4/runtime/base_error_listener.rb +18 -0
  39. data/lib/antlr4/runtime/basic_block_start_state.rb +12 -0
  40. data/lib/antlr4/runtime/basic_state.rb +11 -0
  41. data/lib/antlr4/runtime/bit_set.rb +54 -0
  42. data/lib/antlr4/runtime/block_end_state.rb +15 -0
  43. data/lib/antlr4/runtime/block_start_state.rb +12 -0
  44. data/lib/antlr4/runtime/buffered_token_stream.rb +335 -0
  45. data/lib/antlr4/runtime/char_stream.rb +6 -0
  46. data/lib/antlr4/runtime/char_streams.rb +12 -0
  47. data/lib/antlr4/runtime/chunk.rb +4 -0
  48. data/lib/antlr4/runtime/code_point_char_stream.rb +83 -0
  49. data/lib/antlr4/runtime/common_token.rb +125 -0
  50. data/lib/antlr4/runtime/common_token_factory.rb +30 -0
  51. data/lib/antlr4/runtime/common_token_stream.rb +63 -0
  52. data/lib/antlr4/runtime/console_error_listener.rb +12 -0
  53. data/lib/antlr4/runtime/context_sensitivity_info.rb +7 -0
  54. data/lib/antlr4/runtime/decision_event_info.rb +19 -0
  55. data/lib/antlr4/runtime/decision_info.rb +36 -0
  56. data/lib/antlr4/runtime/decision_state.rb +15 -0
  57. data/lib/antlr4/runtime/default_error_strategy.rb +314 -0
  58. data/lib/antlr4/runtime/dfa.rb +97 -0
  59. data/lib/antlr4/runtime/dfa_serializer.rb +62 -0
  60. data/lib/antlr4/runtime/dfa_state.rb +109 -0
  61. data/lib/antlr4/runtime/diagnostic_error_listener.rb +58 -0
  62. data/lib/antlr4/runtime/double_key_map.rb +49 -0
  63. data/lib/antlr4/runtime/empty_prediction_context.rb +35 -0
  64. data/lib/antlr4/runtime/epsilon_transition.rb +27 -0
  65. data/lib/antlr4/runtime/equality_comparator.rb +4 -0
  66. data/lib/antlr4/runtime/error_info.rb +7 -0
  67. data/lib/antlr4/runtime/error_node.rb +5 -0
  68. data/lib/antlr4/runtime/error_node_impl.rb +12 -0
  69. data/lib/antlr4/runtime/failed_predicate_exception.rb +33 -0
  70. data/lib/antlr4/runtime/flexible_hash_map.rb +232 -0
  71. data/lib/antlr4/runtime/input_mismatch_exception.rb +20 -0
  72. data/lib/antlr4/runtime/int_stream.rb +31 -0
  73. data/lib/antlr4/runtime/integer.rb +14 -0
  74. data/lib/antlr4/runtime/interval.rb +111 -0
  75. data/lib/antlr4/runtime/interval_set.rb +540 -0
  76. data/lib/antlr4/runtime/lexer.rb +257 -0
  77. data/lib/antlr4/runtime/lexer_action.rb +12 -0
  78. data/lib/antlr4/runtime/lexer_action_executor.rb +75 -0
  79. data/lib/antlr4/runtime/lexer_action_type.rb +12 -0
  80. data/lib/antlr4/runtime/lexer_atn_config.rb +50 -0
  81. data/lib/antlr4/runtime/lexer_atn_simulator.rb +522 -0
  82. data/lib/antlr4/runtime/lexer_channel_action.rb +51 -0
  83. data/lib/antlr4/runtime/lexer_custom_action.rb +49 -0
  84. data/lib/antlr4/runtime/lexer_dfa_serializer.rb +12 -0
  85. data/lib/antlr4/runtime/lexer_indexed_custom_action.rb +49 -0
  86. data/lib/antlr4/runtime/lexer_mode_action.rb +51 -0
  87. data/lib/antlr4/runtime/lexer_more_action.rb +41 -0
  88. data/lib/antlr4/runtime/lexer_no_viable_alt_exception.rb +4 -0
  89. data/lib/antlr4/runtime/lexer_pop_mode_action.rb +41 -0
  90. data/lib/antlr4/runtime/lexer_push_mode_action.rb +51 -0
  91. data/lib/antlr4/runtime/lexer_skip_action.rb +43 -0
  92. data/lib/antlr4/runtime/lexer_type_action.rb +51 -0
  93. data/lib/antlr4/runtime/ll1_analyzer.rb +133 -0
  94. data/lib/antlr4/runtime/lookahead_event_info.rb +10 -0
  95. data/lib/antlr4/runtime/loop_end_state.rb +15 -0
  96. data/lib/antlr4/runtime/murmur_hash.rb +99 -0
  97. data/lib/antlr4/runtime/no_viable_alt_exception.rb +7 -0
  98. data/lib/antlr4/runtime/not_set_transition.rb +20 -0
  99. data/lib/antlr4/runtime/object_equality_comparator.rb +18 -0
  100. data/lib/antlr4/runtime/ordered_atn_config_set.rb +15 -0
  101. data/lib/antlr4/runtime/parse_cancellation_exception.rb +5 -0
  102. data/lib/antlr4/runtime/parse_tree.rb +7 -0
  103. data/lib/antlr4/runtime/parse_tree_listener.rb +4 -0
  104. data/lib/antlr4/runtime/parse_tree_visitor.rb +4 -0
  105. data/lib/antlr4/runtime/parser.rb +522 -0
  106. data/lib/antlr4/runtime/parser_atn_simulator.rb +1171 -0
  107. data/lib/antlr4/runtime/parser_rule_context.rb +186 -0
  108. data/lib/antlr4/runtime/plus_block_start_state.rb +11 -0
  109. data/lib/antlr4/runtime/plus_loopback_state.rb +12 -0
  110. data/lib/antlr4/runtime/precedence_predicate_transition.rb +31 -0
  111. data/lib/antlr4/runtime/predicate.rb +6 -0
  112. data/lib/antlr4/runtime/predicate_eval_info.rb +16 -0
  113. data/lib/antlr4/runtime/predicate_transition.rb +35 -0
  114. data/lib/antlr4/runtime/prediction_context.rb +103 -0
  115. data/lib/antlr4/runtime/prediction_context_cache.rb +28 -0
  116. data/lib/antlr4/runtime/prediction_context_utils.rb +407 -0
  117. data/lib/antlr4/runtime/prediction_mode.rb +213 -0
  118. data/lib/antlr4/runtime/profiling_atn_simulator.rb +149 -0
  119. data/lib/antlr4/runtime/proxy_error_listener.rb +33 -0
  120. data/lib/antlr4/runtime/range_transition.rb +29 -0
  121. data/lib/antlr4/runtime/recognition_exception.rb +17 -0
  122. data/lib/antlr4/runtime/recognizer.rb +136 -0
  123. data/lib/antlr4/runtime/rule_context.rb +131 -0
  124. data/lib/antlr4/runtime/rule_context_with_alt_num.rb +11 -0
  125. data/lib/antlr4/runtime/rule_node.rb +8 -0
  126. data/lib/antlr4/runtime/rule_start_state.rb +17 -0
  127. data/lib/antlr4/runtime/rule_stop_state.rb +12 -0
  128. data/lib/antlr4/runtime/rule_tag_token.rb +64 -0
  129. data/lib/antlr4/runtime/rule_transition.rb +29 -0
  130. data/lib/antlr4/runtime/semantic_context.rb +313 -0
  131. data/lib/antlr4/runtime/set_transition.rb +29 -0
  132. data/lib/antlr4/runtime/singleton_prediction_context.rb +56 -0
  133. data/lib/antlr4/runtime/star_block_start_state.rb +12 -0
  134. data/lib/antlr4/runtime/star_loop_entry_state.rb +17 -0
  135. data/lib/antlr4/runtime/star_loopback_state.rb +16 -0
  136. data/lib/antlr4/runtime/syntax_tree.rb +6 -0
  137. data/lib/antlr4/runtime/tag_chunk.rb +22 -0
  138. data/lib/antlr4/runtime/terminal_node.rb +5 -0
  139. data/lib/antlr4/runtime/terminal_node_impl.rb +50 -0
  140. data/lib/antlr4/runtime/text_chunk.rb +16 -0
  141. data/lib/antlr4/runtime/token.rb +13 -0
  142. data/lib/antlr4/runtime/token_stream.rb +13 -0
  143. data/lib/antlr4/runtime/token_tag_token.rb +22 -0
  144. data/lib/antlr4/runtime/tokens_start_state.rb +14 -0
  145. data/lib/antlr4/runtime/transition.rb +51 -0
  146. data/lib/antlr4/runtime/tree.rb +4 -0
  147. data/lib/antlr4/runtime/trees.rb +195 -0
  148. data/lib/antlr4/runtime/triple.rb +40 -0
  149. data/lib/antlr4/runtime/utils.rb +117 -0
  150. data/lib/antlr4/runtime/uuid.rb +46 -0
  151. data/lib/antlr4/runtime/version.rb +5 -0
  152. data/lib/antlr4/runtime/vocabulary.rb +12 -0
  153. data/lib/antlr4/runtime/vocabulary_impl.rb +82 -0
  154. data/lib/antlr4/runtime/wildcard_transition.rb +20 -0
  155. data/lib/antlr4/runtime/writable_token.rb +7 -0
  156. 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