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,186 @@
1
+ require 'antlr4/runtime/rule_context'
2
+
3
+ module Antlr4::Runtime
4
+
5
+ class ParserRuleContext < RuleContext
6
+ EMPTY = ParserRuleContext.new
7
+
8
+ attr_accessor :children
9
+ attr_accessor :start
10
+ attr_accessor :stop
11
+ attr_accessor :exception
12
+
13
+ def copy_from(ctx)
14
+ @parent = ctx.parent
15
+ @invoking_state = ctx.invoking_state
16
+
17
+ @start = ctx.start
18
+ @stop = ctx.stop
19
+
20
+ # copy any error nodes to alt label node
21
+ unless ctx.children.nil?
22
+ @children = []
23
+ # reset parent pointer for any error nodes
24
+ i = 0
25
+ while i < ctx.children.length
26
+ child = ctx.children[i]
27
+ add_child_terminal_node(child) if child.is_a? ErrorNode
28
+ i += 1
29
+ end
30
+ end
31
+ end
32
+
33
+ def initialize(parent = nil, invoking_state_number = nil)
34
+ super(parent, invoking_state_number)
35
+ @children = []
36
+ end
37
+
38
+ def enter_rule(_listener)
39
+ end
40
+
41
+ def exit_rule(_listener)
42
+ end
43
+
44
+ def add_any_child(t)
45
+ @children = [] if @children.nil?
46
+ @children << t
47
+ t
48
+ end
49
+
50
+ def add_child_rule_invocation(rule_invocation)
51
+ add_any_child(rule_invocation)
52
+ end
53
+
54
+ def add_child_terminal_node(t)
55
+ t.parent = self
56
+ add_any_child(t)
57
+ end
58
+
59
+ def add_error_node(error_node)
60
+ error_node.setParent(self)
61
+ add_any_child(error_node)
62
+ end
63
+
64
+ def remove_last_child
65
+ @children.delete_at(-1) unless @children.nil?
66
+ end
67
+
68
+ def child_at(i)
69
+ !@children.nil? && i >= 0 && i < @children.length ? @children[i] : nil
70
+ end
71
+
72
+ def child(ctxType, i)
73
+ return nil if @children.nil? || i < 0 || i >= @children.length
74
+
75
+ j = -1 # what element have we found with ctx_type?
76
+ k = 0
77
+ while k < @children.length
78
+ o = @children[k]
79
+ unless o.class.name.end_with? ctxType
80
+ k += 1
81
+ next
82
+ end
83
+
84
+ j += 1
85
+ return o if j == i
86
+ k += 1
87
+ end
88
+ nil
89
+ end
90
+
91
+ def token(ttype, i)
92
+ return nil if @children.nil? || i < 0 || i >= @children.length
93
+
94
+ j = -1 # what token with ttype have we found?
95
+ k = 0
96
+ while k < @children.length
97
+ o = @children[k]
98
+ unless o.is_a? TerminalNode
99
+ k += 1
100
+ next
101
+ end
102
+
103
+ tnode = o
104
+ symbol = tnode.symbol
105
+ if !symbol.nil? && symbol.type == ttype
106
+ j += 1
107
+ return tnode if j == i
108
+ end
109
+ k += 1
110
+ end
111
+
112
+ nil
113
+ end
114
+
115
+ def tokens(ttype)
116
+ return [] if @children.nil?
117
+
118
+ tokens = nil
119
+ i = 0
120
+ while i < @children.length
121
+ o = @children[i]
122
+ unless o.is_a? TerminalNode
123
+ i += 1
124
+ next
125
+ end
126
+
127
+ tnode = o
128
+ symbol = tnode.symbol
129
+ if symbol.type == ttype
130
+ tokens = [] if tokens.nil?
131
+ tokens << tnode
132
+ end
133
+ i += 1
134
+ end
135
+
136
+ return [] if tokens.nil?
137
+
138
+ tokens
139
+ end
140
+
141
+ def rule_context(ctx_type, i)
142
+ child(ctx_type, i)
143
+ end
144
+
145
+ def rule_contexts(ctxType)
146
+ return [] if @children.nil?
147
+
148
+ contexts = nil
149
+ i = 0
150
+ while i < @children.length
151
+ o = @children[i]
152
+ unless o.class.name.end_with? ctxType
153
+ i += 1
154
+ next
155
+ end
156
+
157
+ contexts = [] if contexts.nil?
158
+ contexts << o
159
+ i += 1
160
+ end
161
+
162
+ return [] if contexts.nil?
163
+
164
+ contexts
165
+ end
166
+
167
+ def child_count
168
+ !@children.nil? ? @children.length : 0
169
+ end
170
+
171
+ def source_interval
172
+ return Interval.invalid if @start.nil?
173
+ if @stop.nil? || @stop.token_index < @start.token_index
174
+ return Interval.of(@start.token_index, @start.token_index - 1) # empty
175
+ end
176
+
177
+ Interval.of(@start.token_index, @stop.token_index)
178
+ end
179
+
180
+ def to_info_string(recognizer)
181
+ rules = recognizer.rule_invocation_stack2(self)
182
+ rules.reverse!
183
+ 'ParserRuleContext' + rules + '' + 'start=' + @start + ', stop=' + @stop + 'end'
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,11 @@
1
+ module Antlr4::Runtime
2
+
3
+ class PlusBlockStartState < BlockStartState
4
+ attr_accessor :loopback_state
5
+ @loopback_state = nil
6
+
7
+ def state_type
8
+ PLUS_BLOCK_START
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module Antlr4::Runtime
2
+
3
+ class PlusLoopbackState < DecisionState
4
+ def initialize
5
+ super
6
+ end
7
+
8
+ def state_type
9
+ PLUS_LOOP_BACK
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,31 @@
1
+ module Antlr4::Runtime
2
+
3
+ class PrecedencePredicateTransition < AbstractPredicateTransition
4
+ attr_reader :precedence
5
+
6
+ def initialize(target, precedence)
7
+ super(target)
8
+ @precedence = precedence
9
+ end
10
+
11
+ def serialization_type
12
+ PRECEDENCE
13
+ end
14
+
15
+ def epsilon?
16
+ true
17
+ end
18
+
19
+ def matches(_symbol, _min_vocab_symbol, _max_vocab_symbol)
20
+ false
21
+ end
22
+
23
+ def predicate
24
+ SemanticContext.PrecedencePredicate.new(@precedence)
25
+ end
26
+
27
+ def to_s
28
+ @precedence + ' >= _p'
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,6 @@
1
+ module Antlr4::Runtime
2
+ class Predicate
3
+ def test(t)
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,16 @@
1
+ module Antlr4::Runtime
2
+ class PredicateEvalInfo < DecisionEventInfo
3
+ attr_reader :semctx
4
+
5
+ attr_reader :predicted_alt
6
+
7
+ attr_reader :eval_result
8
+
9
+ def initialize(decision, input, start_index, stop_index, semctx, eval_result, predicted_alt, full_ctx)
10
+ super(decision, ATNConfigSet().new, input, start_index, stop_index, full_ctx)
11
+ @semctx = semctx
12
+ @eval_result = eval_result
13
+ @predicted_alt = predicted_alt
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,35 @@
1
+ module Antlr4::Runtime
2
+
3
+ class PredicateTransition < AbstractPredicateTransition
4
+ attr_reader :rule_index
5
+ attr_reader :pred_index
6
+ attr_reader :is_ctx_dependent # e.g., $i ref in pred
7
+
8
+ def initialize(target, rule_index, pred_index, is_ctx_dependent)
9
+ super(target)
10
+ @rule_index = rule_index
11
+ @pred_index = pred_index
12
+ @is_ctx_dependent = is_ctx_dependent
13
+ end
14
+
15
+ def serialization_type
16
+ PREDICATE
17
+ end
18
+
19
+ def epsilon?
20
+ true
21
+ end
22
+
23
+ def matches(_symbol, _min_vocab_symbol, _max_vocab_symbol)
24
+ false
25
+ end
26
+
27
+ def predicate
28
+ SemanticContext::Predicate.new(@rule_index, @pred_index, @is_ctx_dependent)
29
+ end
30
+
31
+ def to_s
32
+ 'pred_' + @rule_index + ':' + @pred_index
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,103 @@
1
+ require 'antlr4/runtime/integer'
2
+
3
+ module Antlr4::Runtime
4
+
5
+ class PredictionContext
6
+ INITIAL_HASH = 1
7
+ EMPTY_RETURN_STATE = Integer::MAX
8
+
9
+ class << self
10
+ @@global_node_count = 0
11
+ end
12
+
13
+ attr_accessor :cachedHashCode
14
+
15
+ def initialize(cached_hash_code)
16
+ @id = @@global_node_count
17
+ @@global_node_count += 1
18
+ @cached_hash_code = cached_hash_code
19
+ end
20
+
21
+ def empty_path? # since EMPTY_RETURN_STATE can only appear in the last position, we check last one
22
+ get_return_state(size - 1) == EMPTY_RETURN_STATE
23
+ end
24
+
25
+ def hash
26
+ @cached_hash_code
27
+ end
28
+
29
+ def to_s_recog(_recog)
30
+ to_s
31
+ end
32
+
33
+ def to_strings(recognizer, current_state)
34
+ to_strings3(recognizer, EMPTY, current_state)
35
+ end
36
+
37
+ def to_strings3(_recognizer, _stop, _current_state)
38
+ result = []
39
+
40
+ while to_strings3_inner result
41
+
42
+ end
43
+
44
+ result
45
+ end
46
+
47
+ def to_strings3_inner(result)
48
+ perm = 0
49
+ while perm
50
+ offset = 0
51
+ last = true
52
+ p = self
53
+ state_number = current_state
54
+ local_buffer = ''
55
+ local_buffer << '['
56
+ while !p.empty? && p != stop
57
+ index = 0
58
+ unless p.empty?
59
+ bits = 1
60
+ bits += 1 while (1 << bits) < p.size
61
+
62
+ mask = (1 << bits) - 1
63
+ index = (perm >> offset) & mask
64
+ last &= index >= p.size - 1
65
+ return true if index >= p.size
66
+
67
+ offset += bits
68
+ end
69
+
70
+ if !recognizer.nil?
71
+ if local_buffer.length > 1
72
+ # first char is '[', if more than that this isn't the first rule
73
+ local_buffer << ' '
74
+ end
75
+
76
+ atn = recognizer.getATN
77
+ s = atn.states.get(state_number)
78
+ ruleName = recognizer.rule_names[s.rule_index]
79
+ local_buffer << ruleName
80
+ elsif p.get_return_state(index) != EMPTY_RETURN_STATE
81
+ unless p.empty?
82
+ if local_buffer.length > 1
83
+ # first char is '[', if more than that this isn't the first rule
84
+ local_buffer << ' '
85
+ end
86
+
87
+ local_buffer << p.get_return_state(index)
88
+ end
89
+ end
90
+ state_number = p.get_return_state(index)
91
+ p = p.getParent(index)
92
+ end
93
+ local_buffer << ']'
94
+ result.push(local_buffer.to_s)
95
+
96
+ break if last
97
+
98
+ perm += 1
99
+ end
100
+ false
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,28 @@
1
+ require 'antlr4/runtime/empty_prediction_context'
2
+
3
+ module Antlr4::Runtime
4
+
5
+ class PredictionContextCache
6
+ def initialize
7
+ @cache = {}
8
+ end
9
+
10
+ def add(ctx)
11
+ return EmptyPredictionContext::EMPTY if ctx == EmptyPredictionContext::EMPTY
12
+
13
+ existing = @cache[ctx]
14
+ return existing unless existing.nil?
15
+
16
+ @cache[ctx] = ctx
17
+ ctx
18
+ end
19
+
20
+ def get(ctx)
21
+ @cache[ctx]
22
+ end
23
+
24
+ def size
25
+ @cache.size
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,407 @@
1
+ require 'antlr4/runtime/murmur_hash'
2
+ require 'antlr4/runtime/array_prediction_context'
3
+
4
+ module Antlr4::Runtime
5
+
6
+ class PredictionContextUtils
7
+ INITIAL_HASH = 1
8
+ EMPTY_RETURN_STATE = Integer::MAX
9
+
10
+ def self.from_rule_context(atn, outer_ctx)
11
+ outer_ctx = ParserRuleContext::EMPTY if outer_ctx.nil?
12
+
13
+ # if we are in RuleContext of start rule, s, then PredictionContext
14
+ # is EMPTY. Nobody called us. (if we are empty, return empty)
15
+ if outer_ctx.parent.nil? || outer_ctx == ParserRuleContext::EMPTY
16
+ return EmptyPredictionContext::EMPTY
17
+ end
18
+
19
+ # If we have a parent, convert it to a PredictionContext graph
20
+ parent = PredictionContextUtils.from_rule_context(atn, outer_ctx.parent)
21
+
22
+ state = atn.states[outer_ctx.invoking_state]
23
+ transition = state.transition(0)
24
+ SingletonPredictionContext.new(parent, transition.follow_state.state_number)
25
+ end
26
+
27
+ def self.merge(a, b, root_is_wildcard, merge_cache)
28
+ # share same graph if both same
29
+ return a if a == b || a.eql?(b)
30
+
31
+ if a.is_a?(SingletonPredictionContext) && b.is_a?(SingletonPredictionContext)
32
+ return merge_singletons(a, b, root_is_wildcard, merge_cache)
33
+ end
34
+
35
+ # At least one of a or b is array
36
+ # If one is $ and root_is_wildcard, return $ as * wildcard
37
+ if root_is_wildcard
38
+ return a if a.is_a? EmptyPredictionContext
39
+ return b if b.is_a? EmptyPredictionContext
40
+ end
41
+
42
+ # convert singleton so both are arrays to normalize
43
+ a = ArrayPredictionContext.new(a) if a.is_a? SingletonPredictionContext
44
+ b = ArrayPredictionContext.new(b) if b.is_a? SingletonPredictionContext
45
+ merge_arrays(a, b, root_is_wildcard, merge_cache)
46
+ end
47
+
48
+ def self.merge_singletons(a, b, root_is_wildcard, merge_cache)
49
+ unless merge_cache.nil?
50
+ previous = merge_cache.get2(a, b)
51
+ return previous unless previous.nil?
52
+
53
+ previous = merge_cache.get2(b, a)
54
+ return previous unless previous.nil?
55
+ end
56
+
57
+ root_merge = merge_root(a, b, root_is_wildcard)
58
+ unless root_merge.nil?
59
+ merge_cache.put(a, b, root_merge) unless merge_cache.nil?
60
+ return root_merge
61
+ end
62
+
63
+ if a.return_state == b.return_state # a == b
64
+ parent = merge(a.parent, b.parent, root_is_wildcard, merge_cache)
65
+ # if parent is same as existing a or b parent or reduced to a parent, return it
66
+ if parent == a.parent
67
+ return a # ax + bx = ax, if a=b
68
+ end
69
+ if parent == b.parent
70
+ return b # ax + bx = bx, if a=b
71
+ end
72
+
73
+ # else: ax + ay = a'[x,y]
74
+ # merge parents x and y, giving array node with x,y then remainders
75
+ # of those graphs. dup a, a' points at merged array
76
+ # new joined parent so create new singleton pointing to it, a'
77
+ a_ = SingletonPredictionContext.new(parent, a.return_state)
78
+ merge_cache.put(a, b, a_) unless merge_cache.nil?
79
+ return a_
80
+ else # a != b payloads differ
81
+ # see if we can collapse parents due to $+x parents if local ctx
82
+ single_parent = nil
83
+ if a == b || (!a.parent.nil? && a.parent.eql?(b.parent)) # ax + bx = [a,b]x
84
+ single_parent = a.parent
85
+ end
86
+ unless single_parent.nil? # parents are same
87
+ # sort payloads and use same parent
88
+ payloads = [a.return_state, b.return_state]
89
+ if a.return_state > b.return_state
90
+ payloads[0] = b.return_state
91
+ payloads[1] = a.return_state
92
+ end
93
+ parents = [single_parent, single_parent]
94
+ a_ = ArrayPredictionContext.new(parents, payloads)
95
+ merge_cache.put(a, b, a_) unless merge_cache.nil?
96
+ return a_
97
+ end
98
+ # parents differ and can't merge them. Just pack together
99
+ # into array can't merge.
100
+ # ax + by = [ax,by]
101
+ payloads = [a.return_state, b.return_state]
102
+ parents = [a.parent, b.parent]
103
+ if a.return_state > b.return_state # sort by payload
104
+ payloads[0] = b.return_state
105
+ payloads[1] = a.return_state
106
+ parents = [b.parent, a.parent]
107
+ end
108
+ a_ = ArrayPredictionContext.new(parents, payloads)
109
+ merge_cache.put(a, b, a_) unless merge_cache.nil?
110
+ return a_
111
+ end
112
+ end
113
+
114
+ def self.merge_root(a, b, root_is_wildcard)
115
+ if root_is_wildcard
116
+ if a.return_state == EMPTY_RETURN_STATE
117
+ return EmptyPredictionContext::EMPTY # * + b = *
118
+ end
119
+ if b.return_state == EMPTY_RETURN_STATE
120
+ return EmptyPredictionContext::EMPTY # a + * = *
121
+ end
122
+ else
123
+ if a.return_state == EMPTY_RETURN_STATE && b.return_state == EMPTY_RETURN_STATE
124
+ return EmptyPredictionContext::EMPTY # $ + $ = $
125
+ end
126
+
127
+ if a.return_state == EMPTY_RETURN_STATE # $ + x = [x,$]
128
+ payloads = [b.return_state, EMPTY_RETURN_STATE]
129
+ parents = [b.parent, nil]
130
+ joined = ArrayPredictionContext.new(parents, payloads)
131
+ return joined
132
+ end
133
+ if b.return_state == EMPTY_RETURN_STATE # x + $ = [x,$] ($ is always last if present)
134
+ payloads = [a.return_state, EMPTY_RETURN_STATE]
135
+ parents = [a.parent, nil]
136
+ joined = ArrayPredictionContext.new(parents, payloads)
137
+ return joined
138
+ end
139
+ end
140
+ nil
141
+ end
142
+
143
+ def self.merge_arrays(a, b, root_is_wildcard, merge_cache)
144
+ unless merge_cache.nil?
145
+ previous = merge_cache.get2(a, b)
146
+ return previous unless previous.nil?
147
+
148
+ previous = merge_cache.get2(b, a)
149
+ return previous unless previous.nil?
150
+ end
151
+
152
+ # merge sorted payloads a + b => M
153
+ i = 0 # walks a
154
+ j = 0 # walks b
155
+ k = 0 # walks target M array
156
+
157
+ merged_return_states = []
158
+ merged_parents = []
159
+ # walk and merge to yield merged_parents, merged_return_states
160
+ while i < a.return_states.length && j < b.return_states.length
161
+ a_parent = a.parents[i]
162
+ b_parent = b.parents[j]
163
+ if a.return_states[i] == b.return_states[j]
164
+ # same payload (stack tops are equal), must yield merged singleton
165
+ payload = a.return_states[i]
166
+ # $+$ = $
167
+ both = payload == EMPTY_RETURN_STATE && a_parent.nil? && b_parent.nil?
168
+ ax_ax = (!a_parent.nil? && !b_parent.nil?) && a_parent.eql?(b_parent) # ax+ax -> ax
169
+ if both || ax_ax
170
+ merged_parents[k] = a_parent # choose left
171
+ merged_return_states[k] = payload
172
+ else # ax+ay -> a'[x,y]
173
+ merged_parent = merge(a_parent, b_parent, root_is_wildcard, merge_cache)
174
+ merged_parents[k] = merged_parent
175
+ merged_return_states[k] = payload
176
+ end
177
+ i += 1 # hop over left one as usual
178
+ j += 1 # but also skip one in right side since we merge
179
+ elsif a.return_states[i] < b.return_states[j] # copy a[i] to M
180
+ merged_parents[k] = a_parent
181
+ merged_return_states[k] = a.return_states[i]
182
+ i += 1
183
+ else # b > a, copy b[j] to M
184
+ merged_parents[k] = b_parent
185
+ merged_return_states[k] = b.return_states[j]
186
+ j += 1
187
+ end
188
+
189
+ k += 1
190
+ end
191
+
192
+ # copy over any payloads remaining in either array
193
+ if i < a.return_states.length
194
+ p = i
195
+ while p < a.return_states.length
196
+ merged_parents[k] = a.parents[p]
197
+ merged_return_states[k] = a.return_states[p]
198
+ k += 1
199
+ p += 1
200
+ end
201
+ else
202
+ p = j
203
+ while p < b.return_states.length
204
+ merged_parents[k] = b.parents[p]
205
+ merged_return_states[k] = b.return_states[p]
206
+ k += 1
207
+ p += 1
208
+ end
209
+ end
210
+
211
+ # trim merged if we combined a few that had same stack tops
212
+ if k < merged_parents.length # write index < last position trim
213
+ if k == 1 # for just one merged element, return singleton top
214
+ a_ = SingletonPredictionContext.create(merged_parents[0], merged_return_states[0])
215
+ merge_cache.put(a, b, a_) unless merge_cache.nil?
216
+ return a_
217
+ end
218
+ end
219
+
220
+ m = ArrayPredictionContext.new(merged_parents, merged_return_states)
221
+
222
+ # if we created same array as a or b, return that instead
223
+ # TODO: track whether this is possible above during merge sort for speed
224
+ if m.equals(a)
225
+ merge_cache.put(a, b, a) unless merge_cache.nil?
226
+ return a
227
+ end
228
+ if m.equals(b)
229
+ merge_cache.put(a, b, b) unless merge_cache.nil?
230
+ return b
231
+ end
232
+
233
+ combine_common_parents(merged_parents)
234
+
235
+ merge_cache.put(a, b, m) unless merge_cache.nil?
236
+ m
237
+ end
238
+
239
+ def self.combine_common_parents(parents)
240
+ unique_parents = {}
241
+
242
+ p = 0
243
+ while p < parents.length
244
+ parent = parents[p]
245
+ unique_parents[parent] = parent unless unique_parents.key?(parent) # don't replace
246
+ p += 1
247
+ end
248
+
249
+ p = 0
250
+ while p < parents.length
251
+ parents[p] = unique_parents[parents[p]]
252
+ p += 1
253
+ end
254
+ end
255
+
256
+ def self.to_dot_string(context)
257
+ return '' if context.nil?
258
+
259
+ buf = ''
260
+ buf << "digraph G \n"
261
+ buf << "rankdir=LR\n"
262
+
263
+ nodes = all_context_nodes(context)
264
+ nodes.sort {|a, b| a.id - b.id}
265
+
266
+ nodes.each do |current|
267
+ if current.is_a? SingletonPredictionContext
268
+ s = current.id.to_s
269
+ buf << ' s' << s
270
+ return_state = current.get_return_state(0).to_s
271
+ return_state = '$' if current.is_a? EmptyPredictionContext
272
+ buf << ' [label="' << return_state << "\"]\n"
273
+ next
274
+ end
275
+ arr = current
276
+ buf << ' s' << arr.id
277
+ buf << ' [shape=box, label="'
278
+ buf << '['
279
+ first = true
280
+ arr.return_states.each do |inv|
281
+ buf << ', ' unless first
282
+ buf << if inv == EMPTY_RETURN_STATE
283
+ '$'
284
+ else
285
+ inv
286
+ end
287
+ first = false
288
+ end
289
+ buf << ']'
290
+ buf << "\"]\n"
291
+ end
292
+
293
+ nodes.each do |current|
294
+ next if current == EMPTY
295
+
296
+ i = 0
297
+ while i < current.size
298
+ if current.get_parent(i).nil?
299
+ i += 1
300
+ next
301
+ end
302
+ String s = String.valueOf(current.id)
303
+ buf << ' s' << s
304
+ buf << '->'
305
+ buf << 's'
306
+ buf << current.get_parent(i).id
307
+ buf << if current.size > 1
308
+ ' [label="parent[' + i + "]\"]\n"
309
+ else
310
+ "\n"
311
+ end
312
+ i += 1
313
+ end
314
+ end
315
+
316
+ buf << "end\n"
317
+ buf
318
+ end
319
+
320
+ def self.cached_context(context, context_cache, visited)
321
+ return context if context.empty?
322
+
323
+ existing = visited[context]
324
+ return existing unless existing.nil?
325
+
326
+ existing = context_cache.get(context)
327
+ unless existing.nil?
328
+ visited[context] = existing
329
+ return existing
330
+ end
331
+
332
+ changed = false
333
+ parents = []
334
+ i = 0
335
+ while i < parents.length
336
+ parent = cached_context(context.get_parent(i), context_cache, visited)
337
+ if changed || parent != context.get_parent(i)
338
+ unless changed
339
+ parents = []
340
+ j = 0
341
+ while j < context.size
342
+ parents[j] = context.get_parent(j)
343
+ j += 1
344
+ end
345
+ changed = true
346
+ end
347
+ parents[i] = parent
348
+ end
349
+ i += 1
350
+ end
351
+
352
+ unless changed
353
+ context_cache.add(context)
354
+ visited[context] = context
355
+ return context
356
+ end
357
+
358
+ if parents.empty?
359
+ updated = EMPTY
360
+ elsif parents.length == 1
361
+ updated = SingletonPredictionContext.create(parents[0], context.get_return_state(0))
362
+ else
363
+ array_pred_ctx = context
364
+ updated = ArrayPredictionContext.new(parents, array_pred_ctx.return_states)
365
+ end
366
+
367
+ context_cache.add(updated)
368
+ visited[updated] = updated
369
+ visited[context] = updated
370
+
371
+ updated
372
+ end
373
+
374
+ def self.all_context_nodes(context)
375
+ nodes = []
376
+ visited = {}
377
+ all_context_nodes_(context, nodes, visited)
378
+ nodes
379
+ end
380
+
381
+ def self.all_context_nodes_(context, nodes, visited)
382
+ return if context.nil? || visited.key?(context)
383
+
384
+ visited[context] = context
385
+ nodes.add(context)
386
+ i = 0
387
+ while i < context.size
388
+ all_context_nodes_(context.get_parent(i), nodes, visited)
389
+ i += 1
390
+ end
391
+ end
392
+
393
+ def self.calculate_empty_hash_code
394
+ return @_hash unless @_hash.nil?
395
+
396
+ @_hash = MurmurHash.hash_int(INITIAL_HASH)
397
+ end
398
+
399
+ def self.calculate_hash_code1(parent, return_state)
400
+ MurmurHash.hash_int_obj(return_state, parent)
401
+ end
402
+
403
+ def self.calculate_hash_code2(parents, return_states)
404
+ MurmurHash.hash_ints_objs(return_states, parents)
405
+ end
406
+ end
407
+ end