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,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,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,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
|