rley 0.7.03 → 0.7.08
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 +4 -4
- data/.rubocop.yml +362 -62
- data/.travis.yml +6 -7
- data/CHANGELOG.md +20 -1
- data/LICENSE.txt +1 -1
- data/README.md +6 -7
- data/Rakefile +2 -0
- data/appveyor.yml +2 -4
- data/examples/NLP/benchmark_pico_en.rb +2 -0
- data/examples/NLP/engtagger.rb +193 -188
- data/examples/NLP/nano_eng/nano_en_demo.rb +2 -0
- data/examples/NLP/nano_eng/nano_grammar.rb +7 -5
- data/examples/NLP/pico_en_demo.rb +2 -0
- data/examples/data_formats/JSON/cli_options.rb +3 -1
- data/examples/data_formats/JSON/json_ast_builder.rb +14 -9
- data/examples/data_formats/JSON/json_ast_nodes.rb +14 -21
- data/examples/data_formats/JSON/json_demo.rb +2 -0
- data/examples/data_formats/JSON/json_grammar.rb +4 -2
- data/examples/data_formats/JSON/json_lexer.rb +10 -8
- data/examples/data_formats/JSON/json_minifier.rb +3 -1
- data/examples/general/calc_iter1/calc_ast_builder.rb +15 -10
- data/examples/general/calc_iter1/calc_ast_nodes.rb +25 -37
- data/examples/general/calc_iter1/calc_demo.rb +2 -0
- data/examples/general/calc_iter1/calc_grammar.rb +4 -2
- data/examples/general/calc_iter1/calc_lexer.rb +8 -4
- data/examples/general/calc_iter1/spec/calculator_spec.rb +7 -5
- data/examples/general/calc_iter2/calc_ast_builder.rb +7 -3
- data/examples/general/calc_iter2/calc_ast_nodes.rb +29 -43
- data/examples/general/calc_iter2/calc_demo.rb +2 -0
- data/examples/general/calc_iter2/calc_grammar.rb +5 -3
- data/examples/general/calc_iter2/calc_lexer.rb +13 -10
- data/examples/general/calc_iter2/spec/calculator_spec.rb +28 -26
- data/examples/general/left.rb +4 -2
- data/examples/general/right.rb +4 -2
- data/lib/rley.rb +2 -0
- data/lib/rley/base/base_parser.rb +2 -0
- data/lib/rley/base/dotted_item.rb +38 -41
- data/lib/rley/base/grm_items_builder.rb +2 -0
- data/lib/rley/constants.rb +5 -3
- data/lib/rley/engine.rb +22 -24
- data/lib/rley/formatter/asciitree.rb +6 -4
- data/lib/rley/formatter/base_formatter.rb +2 -0
- data/lib/rley/formatter/bracket_notation.rb +3 -8
- data/lib/rley/formatter/debug.rb +8 -6
- data/lib/rley/formatter/json.rb +4 -2
- data/lib/rley/gfg/call_edge.rb +3 -1
- data/lib/rley/gfg/edge.rb +7 -5
- data/lib/rley/gfg/end_vertex.rb +4 -6
- data/lib/rley/gfg/epsilon_edge.rb +3 -5
- data/lib/rley/gfg/grm_flow_graph.rb +31 -25
- data/lib/rley/gfg/item_vertex.rb +12 -22
- data/lib/rley/gfg/non_terminal_vertex.rb +6 -4
- data/lib/rley/gfg/return_edge.rb +2 -0
- data/lib/rley/gfg/scan_edge.rb +3 -1
- data/lib/rley/gfg/shortcut_edge.rb +4 -2
- data/lib/rley/gfg/start_vertex.rb +6 -8
- data/lib/rley/gfg/vertex.rb +47 -41
- data/lib/rley/lexical/token.rb +3 -1
- data/lib/rley/lexical/token_range.rb +8 -6
- data/lib/rley/parse_forest_visitor.rb +7 -5
- data/lib/rley/parse_rep/ast_base_builder.rb +11 -11
- data/lib/rley/parse_rep/cst_builder.rb +7 -4
- data/lib/rley/parse_rep/parse_forest_builder.rb +36 -25
- data/lib/rley/parse_rep/parse_forest_factory.rb +5 -3
- data/lib/rley/parse_rep/parse_rep_creator.rb +18 -13
- data/lib/rley/parse_rep/parse_tree_builder.rb +15 -15
- data/lib/rley/parse_rep/parse_tree_factory.rb +27 -25
- data/lib/rley/parse_tree_visitor.rb +3 -1
- data/lib/rley/parser/error_reason.rb +9 -8
- data/lib/rley/parser/gfg_chart.rb +54 -22
- data/lib/rley/parser/gfg_earley_parser.rb +3 -1
- data/lib/rley/parser/gfg_parsing.rb +51 -31
- data/lib/rley/parser/parse_entry.rb +29 -33
- data/lib/rley/parser/parse_entry_set.rb +32 -27
- data/lib/rley/parser/parse_entry_tracker.rb +6 -4
- data/lib/rley/parser/parse_state.rb +18 -21
- data/lib/rley/parser/parse_state_tracker.rb +6 -4
- data/lib/rley/parser/parse_tracer.rb +15 -13
- data/lib/rley/parser/parse_walker_factory.rb +28 -29
- data/lib/rley/parser/state_set.rb +11 -10
- data/lib/rley/ptree/non_terminal_node.rb +10 -6
- data/lib/rley/ptree/parse_tree.rb +6 -4
- data/lib/rley/ptree/parse_tree_node.rb +7 -5
- data/lib/rley/ptree/terminal_node.rb +9 -7
- data/lib/rley/rley_error.rb +12 -10
- data/lib/rley/sppf/alternative_node.rb +8 -6
- data/lib/rley/sppf/composite_node.rb +9 -7
- data/lib/rley/sppf/epsilon_node.rb +5 -3
- data/lib/rley/sppf/leaf_node.rb +5 -3
- data/lib/rley/sppf/non_terminal_node.rb +2 -0
- data/lib/rley/sppf/parse_forest.rb +19 -17
- data/lib/rley/sppf/sppf_node.rb +9 -8
- data/lib/rley/sppf/token_node.rb +5 -3
- data/lib/rley/syntax/grammar.rb +7 -5
- data/lib/rley/syntax/grammar_builder.rb +11 -9
- data/lib/rley/syntax/grm_symbol.rb +8 -6
- data/lib/rley/syntax/literal.rb +2 -0
- data/lib/rley/syntax/non_terminal.rb +11 -15
- data/lib/rley/syntax/production.rb +13 -11
- data/lib/rley/syntax/symbol_seq.rb +10 -10
- data/lib/rley/syntax/terminal.rb +6 -5
- data/lib/rley/syntax/verbatim_symbol.rb +5 -3
- data/lib/support/base_tokenizer.rb +23 -20
- data/spec/rley/base/dotted_item_spec.rb +4 -2
- data/spec/rley/base/grm_items_builder_spec.rb +2 -0
- data/spec/rley/engine_spec.rb +47 -9
- data/spec/rley/formatter/asciitree_spec.rb +11 -9
- data/spec/rley/formatter/bracket_notation_spec.rb +16 -14
- data/spec/rley/formatter/debug_spec.rb +4 -2
- data/spec/rley/formatter/json_spec.rb +5 -3
- data/spec/rley/gfg/call_edge_spec.rb +2 -0
- data/spec/rley/gfg/edge_spec.rb +2 -0
- data/spec/rley/gfg/end_vertex_spec.rb +7 -5
- data/spec/rley/gfg/epsilon_edge_spec.rb +2 -0
- data/spec/rley/gfg/grm_flow_graph_spec.rb +2 -0
- data/spec/rley/gfg/item_vertex_spec.rb +12 -10
- data/spec/rley/gfg/non_terminal_vertex_spec.rb +5 -3
- data/spec/rley/gfg/return_edge_spec.rb +2 -0
- data/spec/rley/gfg/scan_edge_spec.rb +2 -0
- data/spec/rley/gfg/shortcut_edge_spec.rb +3 -1
- data/spec/rley/gfg/start_vertex_spec.rb +7 -5
- data/spec/rley/gfg/vertex_spec.rb +5 -3
- data/spec/rley/lexical/token_range_spec.rb +18 -16
- data/spec/rley/lexical/token_spec.rb +4 -2
- data/spec/rley/parse_forest_visitor_spec.rb +167 -163
- data/spec/rley/parse_rep/ambiguous_parse_spec.rb +46 -44
- data/spec/rley/parse_rep/ast_builder_spec.rb +8 -6
- data/spec/rley/parse_rep/cst_builder_spec.rb +7 -5
- data/spec/rley/parse_rep/groucho_spec.rb +25 -25
- data/spec/rley/parse_rep/parse_forest_builder_spec.rb +28 -26
- data/spec/rley/parse_rep/parse_forest_factory_spec.rb +8 -6
- data/spec/rley/parse_rep/parse_tree_factory_spec.rb +4 -2
- data/spec/rley/parse_tree_visitor_spec.rb +12 -8
- data/spec/rley/parser/error_reason_spec.rb +8 -6
- data/spec/rley/parser/gfg_chart_spec.rb +17 -4
- data/spec/rley/parser/gfg_earley_parser_spec.rb +16 -11
- data/spec/rley/parser/gfg_parsing_spec.rb +41 -252
- data/spec/rley/parser/parse_entry_set_spec.rb +2 -0
- data/spec/rley/parser/parse_entry_spec.rb +21 -19
- data/spec/rley/parser/parse_state_spec.rb +7 -5
- data/spec/rley/parser/parse_tracer_spec.rb +16 -14
- data/spec/rley/parser/parse_walker_factory_spec.rb +10 -8
- data/spec/rley/parser/state_set_spec.rb +24 -22
- data/spec/rley/ptree/non_terminal_node_spec.rb +7 -3
- data/spec/rley/ptree/parse_tree_node_spec.rb +6 -4
- data/spec/rley/ptree/parse_tree_spec.rb +2 -0
- data/spec/rley/ptree/terminal_node_spec.rb +8 -6
- data/spec/rley/sppf/alternative_node_spec.rb +8 -6
- data/spec/rley/sppf/non_terminal_node_spec.rb +5 -3
- data/spec/rley/sppf/token_node_spec.rb +6 -4
- data/spec/rley/support/ambiguous_grammar_helper.rb +5 -4
- data/spec/rley/support/expectation_helper.rb +2 -0
- data/spec/rley/support/grammar_abc_helper.rb +4 -4
- data/spec/rley/support/grammar_ambig01_helper.rb +6 -5
- data/spec/rley/support/grammar_arr_int_helper.rb +6 -5
- data/spec/rley/support/grammar_b_expr_helper.rb +6 -5
- data/spec/rley/support/grammar_helper.rb +2 -0
- data/spec/rley/support/grammar_l0_helper.rb +15 -16
- data/spec/rley/support/grammar_pb_helper.rb +8 -5
- data/spec/rley/support/grammar_sppf_helper.rb +3 -1
- data/spec/rley/syntax/grammar_builder_spec.rb +7 -5
- data/spec/rley/syntax/grammar_spec.rb +8 -6
- data/spec/rley/syntax/grm_symbol_spec.rb +3 -1
- data/spec/rley/syntax/literal_spec.rb +2 -0
- data/spec/rley/syntax/non_terminal_spec.rb +10 -8
- data/spec/rley/syntax/production_spec.rb +15 -13
- data/spec/rley/syntax/symbol_seq_spec.rb +4 -2
- data/spec/rley/syntax/terminal_spec.rb +7 -5
- data/spec/rley/syntax/verbatim_symbol_spec.rb +3 -1
- data/spec/spec_helper.rb +2 -12
- data/spec/support/base_tokenizer_spec.rb +9 -2
- metadata +21 -63
- data/.simplecov +0 -7
- data/Gemfile +0 -8
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative '../base/base_parser'
|
2
4
|
require_relative '../gfg/grm_flow_graph'
|
3
5
|
require_relative 'gfg_parsing'
|
@@ -49,7 +51,7 @@ module Rley # This module is used as a namespace
|
|
49
51
|
result.chart[index].each do |entry|
|
50
52
|
# Is entry of the form? [A => alpha . B beta, k]...
|
51
53
|
next_symbol = entry.next_symbol
|
52
|
-
if next_symbol
|
54
|
+
if next_symbol&.kind_of?(Syntax::NonTerminal)
|
53
55
|
# ...apply the Call rule
|
54
56
|
call_rule(result, entry, index)
|
55
57
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'gfg_chart'
|
2
4
|
require_relative 'error_reason'
|
3
5
|
require_relative 'parse_entry_tracker'
|
@@ -13,7 +15,7 @@ module Rley # This module is used as a namespace
|
|
13
15
|
attr_reader(:gf_graph)
|
14
16
|
|
15
17
|
# The link to the chart object
|
16
|
-
# @return [GFGChart]
|
18
|
+
# @return [Parser::GFGChart]
|
17
19
|
attr_reader(:chart)
|
18
20
|
|
19
21
|
# The sequence of input token to parse
|
@@ -34,6 +36,7 @@ module Rley # This module is used as a namespace
|
|
34
36
|
# Constructor
|
35
37
|
# @param theGFG [GFG::GrmFlowGraph] the Grammar Flow Graph
|
36
38
|
def initialize(theGFG)
|
39
|
+
super()
|
37
40
|
@gf_graph = theGFG
|
38
41
|
@tokens = []
|
39
42
|
@chart = GFGChart.new(gf_graph)
|
@@ -71,6 +74,11 @@ module Rley # This module is used as a namespace
|
|
71
74
|
# [B., i]
|
72
75
|
# [A => alpha B . beta, k]
|
73
76
|
def nullable_rule(anEntry, aPosition)
|
77
|
+
# Terminology:
|
78
|
+
# .B : start node
|
79
|
+
# B => . rhs : entry node
|
80
|
+
# B => rhs . : exit node
|
81
|
+
# B. : end node
|
74
82
|
next_symbol = anEntry.next_symbol
|
75
83
|
pos = aPosition
|
76
84
|
start = gf_graph.start_vertex_for[next_symbol]
|
@@ -82,6 +90,8 @@ module Rley # This module is used as a namespace
|
|
82
90
|
succ = edge.successor # succ always an ItemVertex
|
83
91
|
if succ.dotted_item.production.nullable?
|
84
92
|
succ_entry = apply_rule(start_entry, succ, pos, pos, :nullable_rule)
|
93
|
+
next unless succ_entry.exit_entry?
|
94
|
+
|
85
95
|
apply_rule(succ_entry, end_vertex, pos, pos, :nullable_rule)
|
86
96
|
end
|
87
97
|
end
|
@@ -169,50 +179,36 @@ module Rley # This module is used as a namespace
|
|
169
179
|
end
|
170
180
|
end
|
171
181
|
|
172
|
-
|
182
|
+
true
|
173
183
|
end
|
174
184
|
|
175
185
|
# Return true if the parse was successful (= input tokens
|
176
186
|
# followed the syntax specified by the grammar)
|
177
|
-
def success?
|
187
|
+
def success?
|
178
188
|
return false if @failure_reason
|
179
|
-
|
180
|
-
|
189
|
+
|
190
|
+
chart.accepting_entry ? true : false
|
181
191
|
end
|
182
192
|
|
183
193
|
# Return true if there are more than one complete state
|
184
194
|
# for the same lhs and same origin in any state set.
|
185
|
-
def ambiguous?
|
195
|
+
def ambiguous?
|
186
196
|
found = chart.sets.find { |set| !set.ambiguities.empty? }
|
187
|
-
|
188
|
-
end
|
189
|
-
|
190
|
-
# Factory method. Builds a ParseForest from the parse result.
|
191
|
-
# @return [ParseForest]
|
192
|
-
def parse_forest()
|
193
|
-
msg = <<-END_MSG
|
194
|
-
Method Rley::Parser::GFGParsing.parse_forest is deprecated, call
|
195
|
-
Rley::Engine::to_pforest. It will be removed June 1st
|
196
|
-
or version 0.6.1 (whichever is first)
|
197
|
-
END_MSG
|
198
|
-
# warn(msg)
|
199
|
-
factory = ParseRep::ParseForestFactory.new(self)
|
200
|
-
|
201
|
-
return factory.create
|
197
|
+
!found.nil?
|
202
198
|
end
|
203
199
|
|
204
200
|
# Retrieve the very first parse entry added to the chart.
|
205
201
|
# This entry corresponds to the start vertex of the GF graph
|
206
202
|
# with origin equal to zero.
|
207
|
-
def initial_entry
|
208
|
-
|
203
|
+
def initial_entry
|
204
|
+
chart.initial_entry
|
209
205
|
end
|
210
206
|
|
211
207
|
# Retrieve the accepting parse entry that represents
|
212
208
|
# a complete, successful parse
|
213
209
|
# After a successful parse, the last chart entry set
|
214
210
|
# has an end parse entry that involves the start symbol
|
215
|
-
def accepting_entry
|
211
|
+
def accepting_entry
|
216
212
|
return chart.accepting_entry
|
217
213
|
end
|
218
214
|
|
@@ -222,7 +218,7 @@ END_MSG
|
|
222
218
|
end
|
223
219
|
|
224
220
|
# A notification that the parsing reached an end
|
225
|
-
def done
|
221
|
+
def done
|
226
222
|
# Parse not successful and no reason identified
|
227
223
|
# Assuming that parse failed because of a premature end
|
228
224
|
premature_end unless success? || failure_reason
|
@@ -230,12 +226,33 @@ END_MSG
|
|
230
226
|
|
231
227
|
# Clean and normalize the object.
|
232
228
|
# Call this method when the parsing is complete.
|
233
|
-
def tidy_up!
|
229
|
+
def tidy_up!
|
234
230
|
antecedence.each_key do |entry|
|
235
231
|
antecedence[entry].uniq!
|
236
232
|
end
|
237
233
|
end
|
238
234
|
|
235
|
+
def count_states
|
236
|
+
chart.count_states
|
237
|
+
end
|
238
|
+
|
239
|
+
def count_entries
|
240
|
+
chart.count_entries
|
241
|
+
end
|
242
|
+
|
243
|
+
def count_edges
|
244
|
+
chart.count_edges
|
245
|
+
end
|
246
|
+
|
247
|
+
# @return [String] A human readable representation of itself.
|
248
|
+
def to_s
|
249
|
+
result = +''
|
250
|
+
result << "success? #{success?}\n"
|
251
|
+
result << "chart:\n"
|
252
|
+
result << chart.to_s
|
253
|
+
|
254
|
+
result
|
255
|
+
end
|
239
256
|
|
240
257
|
private
|
241
258
|
|
@@ -266,8 +283,10 @@ END_MSG
|
|
266
283
|
|
267
284
|
antecedence[consequent] << antecedentEntry
|
268
285
|
|
286
|
+
=begin
|
269
287
|
# Invariant checks
|
270
288
|
antecedents = antecedence[consequent]
|
289
|
+
|
271
290
|
case aVertex
|
272
291
|
when Rley::GFG::EndVertex
|
273
292
|
# Rule: has 1..* antecedents, all of them are exit items
|
@@ -299,9 +318,9 @@ END_MSG
|
|
299
318
|
raise StandardError, msg_prefix + msg_suffix
|
300
319
|
end
|
301
320
|
end
|
302
|
-
|
321
|
+
=end
|
303
322
|
consequent.add_antecedent(antecedentEntry)
|
304
|
-
|
323
|
+
consequent
|
305
324
|
end
|
306
325
|
|
307
326
|
# Push a parse entry (vertex + origin) to the
|
@@ -316,15 +335,16 @@ END_MSG
|
|
316
335
|
def forest_builder(anIndex)
|
317
336
|
full_range = { low: 0, high: anIndex }
|
318
337
|
start_production = chart.start_dotted_rule.production
|
319
|
-
|
338
|
+
|
339
|
+
ParseForestBuilder.new(start_production, full_range)
|
320
340
|
end
|
321
341
|
|
322
342
|
# Factory method. Creates and initializes a ParseEntryTracker instance.
|
323
|
-
def new_entry_tracker
|
343
|
+
def new_entry_tracker
|
324
344
|
instance = ParseEntryTracker.new(chart.last_index)
|
325
345
|
instance.parse_entry = accepting_entry
|
326
346
|
|
327
|
-
|
347
|
+
instance
|
328
348
|
end
|
329
349
|
end # class
|
330
350
|
end # module
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative '../gfg/start_vertex'
|
2
4
|
require_relative '../gfg/end_vertex'
|
3
5
|
require_relative '../gfg/item_vertex'
|
@@ -30,7 +32,7 @@ module Rley # This module is used as a namespace
|
|
30
32
|
# Returns a string containing a human-readable representation of the
|
31
33
|
# production.
|
32
34
|
# @return [String]
|
33
|
-
def inspect
|
35
|
+
def inspect
|
34
36
|
result = selfie
|
35
37
|
result << ' @antecedents=['
|
36
38
|
antecedents.each do |antec|
|
@@ -38,10 +40,11 @@ module Rley # This module is used as a namespace
|
|
38
40
|
end
|
39
41
|
result << ']>'
|
40
42
|
|
41
|
-
|
43
|
+
result
|
42
44
|
end
|
43
45
|
|
44
46
|
# Add a link to an antecedent parse entry
|
47
|
+
# @param anAntecedent[ParseEntry]
|
45
48
|
def add_antecedent(anAntecedent)
|
46
49
|
antecedents << anAntecedent unless antecedents.include?(anAntecedent)
|
47
50
|
end
|
@@ -50,57 +53,55 @@ module Rley # This module is used as a namespace
|
|
50
53
|
def ==(other)
|
51
54
|
return true if equal? other
|
52
55
|
|
53
|
-
|
54
|
-
return result
|
56
|
+
(vertex == other.vertex) && (origin == other.origin)
|
55
57
|
end
|
56
|
-
|
58
|
+
|
57
59
|
def hash
|
58
|
-
@
|
59
|
-
@my_hash
|
60
|
+
@hash ||= (vertex.oid_str + "-#{origin}").hash
|
60
61
|
end
|
61
62
|
|
62
63
|
# Returns true iff the vertex is a start vertex (i.e. of the form: .X)
|
63
|
-
def start_entry?
|
64
|
-
|
64
|
+
def start_entry?
|
65
|
+
vertex.kind_of?(GFG::StartVertex)
|
65
66
|
end
|
66
67
|
|
67
68
|
# Returns true iff the vertex is at the start of rhs
|
68
69
|
# (i.e. of the form: X => .Y
|
69
|
-
def entry_entry?
|
70
|
+
def entry_entry?
|
70
71
|
return false unless vertex.kind_of?(GFG::ItemVertex)
|
71
72
|
|
72
|
-
|
73
|
+
vertex.dotted_item.at_start?
|
73
74
|
end
|
74
75
|
|
75
76
|
# Returns true iff the vertex corresponds to a dotted item
|
76
77
|
# X => Y
|
77
78
|
def dotted_entry?
|
78
|
-
|
79
|
+
vertex.kind_of?(GFG::ItemVertex)
|
79
80
|
end
|
80
81
|
|
81
82
|
# Returns true iff the vertex is at end of rhs (i.e. of the form: X => Y.)
|
82
|
-
def exit_entry?
|
83
|
-
|
83
|
+
def exit_entry?
|
84
|
+
vertex.complete?
|
84
85
|
end
|
85
86
|
|
86
87
|
# Returns true iff the vertex is an end vertex (i.e. of the form: X.)
|
87
|
-
def end_entry?
|
88
|
-
|
88
|
+
def end_entry?
|
89
|
+
vertex.kind_of?(GFG::EndVertex)
|
89
90
|
end
|
90
91
|
|
91
92
|
# Return the symbol before the dot (if any)
|
92
|
-
def prev_symbol
|
93
|
-
|
93
|
+
def prev_symbol
|
94
|
+
vertex.prev_symbol
|
94
95
|
end
|
95
96
|
|
96
97
|
# Return the symbol after the dot (if any)
|
97
|
-
def next_symbol
|
98
|
-
|
98
|
+
def next_symbol
|
99
|
+
vertex.next_symbol
|
99
100
|
end
|
100
101
|
|
101
102
|
# Return true if the entry has no antecedent entry
|
102
|
-
def orphan?
|
103
|
-
|
103
|
+
def orphan?
|
104
|
+
antecedents.empty?
|
104
105
|
end
|
105
106
|
|
106
107
|
=begin
|
@@ -115,11 +116,6 @@ module Rley # This module is used as a namespace
|
|
115
116
|
return vertex.predicted_item?
|
116
117
|
end
|
117
118
|
|
118
|
-
# Next expected symbol in the production
|
119
|
-
def next_symbol()
|
120
|
-
return vertex.next_symbol
|
121
|
-
end
|
122
|
-
|
123
119
|
# Does this parse state have the 'other' as successor?
|
124
120
|
def precedes?(other)
|
125
121
|
return false if self == other
|
@@ -143,21 +139,21 @@ module Rley # This module is used as a namespace
|
|
143
139
|
# The format of the text representation is
|
144
140
|
# "format of dotted rule" + " | " + origin
|
145
141
|
# @return [String]
|
146
|
-
def to_s
|
147
|
-
|
142
|
+
def to_s
|
143
|
+
vertex.label + " | #{origin}"
|
148
144
|
end
|
149
145
|
|
150
146
|
protected
|
151
147
|
|
152
148
|
# Returns a human-readable and partial representation of itself.
|
153
149
|
# @return [String]
|
154
|
-
def selfie
|
155
|
-
result = "#<#{self.class.name}:#{object_id}"
|
150
|
+
def selfie
|
151
|
+
result = +"#<#{self.class.name}:#{object_id}"
|
156
152
|
result << " @vertex=<#{vertex.class.name}:#{vertex.object_id}"
|
157
153
|
result << " label=#{vertex.label}>"
|
158
154
|
result << " @origin=#{origin}"
|
159
155
|
|
160
|
-
|
156
|
+
result
|
161
157
|
end
|
162
158
|
|
163
159
|
private
|
@@ -167,7 +163,7 @@ module Rley # This module is used as a namespace
|
|
167
163
|
def valid_vertex(aVertex)
|
168
164
|
raise StandardError, 'GFG vertex cannot be nil' if aVertex.nil?
|
169
165
|
|
170
|
-
|
166
|
+
aVertex
|
171
167
|
end
|
172
168
|
end # class
|
173
169
|
end # module
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'forwardable' # For the Delegation pattern
|
2
4
|
require 'set'
|
3
5
|
|
@@ -14,44 +16,45 @@ module Rley # This module is used as a namespace
|
|
14
16
|
|
15
17
|
# @return [Array<ParseEntry>] The array of parse entries
|
16
18
|
attr_reader :entries
|
17
|
-
|
19
|
+
|
18
20
|
# @return [Hash] A Hash with pairs { hash of ParseEntry => ParseEntry }
|
19
|
-
attr_reader :membership
|
21
|
+
attr_reader :membership
|
20
22
|
|
21
23
|
# Constructor.
|
22
|
-
def initialize
|
24
|
+
def initialize
|
23
25
|
@entries = []
|
24
26
|
@membership = {}
|
25
27
|
@entries4term = Hash.new { |hash, key| hash[key] = [] }
|
26
28
|
@entries4n_term = Hash.new { |hash, key| hash[key] = [] }
|
27
29
|
end
|
28
|
-
|
29
|
-
# Returns a string containing a human-readable representation of the
|
30
|
+
|
31
|
+
# Returns a string containing a human-readable representation of the
|
30
32
|
# set of parse entries.
|
31
33
|
# @return [String]
|
32
|
-
def inspect
|
33
|
-
result = "#<#{self.class.name}:#{object_id}"
|
34
|
+
def inspect
|
35
|
+
result = +"#<#{self.class.name}:#{object_id}"
|
34
36
|
result << ' @entries=['
|
35
37
|
entries.each { |e| result << e.inspect }
|
36
38
|
result << ']>'
|
37
|
-
|
39
|
+
|
40
|
+
result
|
38
41
|
end
|
39
42
|
|
40
43
|
# Access the entry at given position
|
41
44
|
def [](index)
|
42
|
-
|
45
|
+
entries[index]
|
43
46
|
end
|
44
47
|
|
45
48
|
# Returns a Hash with pairs of the form:
|
46
49
|
# terminal symbol => [ parse entry expecting the terminal ]
|
47
50
|
def entries4term(aTerminal)
|
48
|
-
|
51
|
+
@entries4term.fetch(aTerminal, [])
|
49
52
|
end
|
50
53
|
|
51
54
|
# Returns a Hash with pairs of the form:
|
52
55
|
# non terminal symbol => [ parse entry expecting the non-terminal ]
|
53
56
|
def entries4n_term(aNonTerminal)
|
54
|
-
|
57
|
+
@entries4n_term.fetch(aNonTerminal, [])
|
55
58
|
end
|
56
59
|
|
57
60
|
# Append the given entry (if it isn't yet in the set)
|
@@ -59,13 +62,9 @@ module Rley # This module is used as a namespace
|
|
59
62
|
# @param anEntry [ParseEntry] the parse entry to push.
|
60
63
|
# @return [ParseEntry] the passed parse entry if it pushes it
|
61
64
|
def push_entry(anEntry)
|
62
|
-
# TODO: control overhead next line
|
63
|
-
#match = entries.find { |entry| entry == anEntry }
|
64
65
|
entry_key = anEntry.hash
|
65
|
-
|
66
|
-
|
67
|
-
result = match
|
68
|
-
else
|
66
|
+
result = membership.fetch(entry_key, false)
|
67
|
+
unless result
|
69
68
|
@entries << anEntry
|
70
69
|
membership[entry_key] = anEntry
|
71
70
|
expecting = anEntry.next_symbol
|
@@ -73,11 +72,11 @@ module Rley # This module is used as a namespace
|
|
73
72
|
result = anEntry
|
74
73
|
end
|
75
74
|
|
76
|
-
|
75
|
+
result
|
77
76
|
end
|
78
77
|
|
79
78
|
# Return an Array of Arrays of ambiguous parse entries.
|
80
|
-
def ambiguities
|
79
|
+
def ambiguities
|
81
80
|
complete_entries = entries.select(&:exit_entry?)
|
82
81
|
return [] if complete_entries.size <= 1
|
83
82
|
|
@@ -92,25 +91,31 @@ module Rley # This module is used as a namespace
|
|
92
91
|
ambiguous_groups << a_group if a_group.size > 1
|
93
92
|
end
|
94
93
|
|
95
|
-
|
94
|
+
ambiguous_groups
|
96
95
|
end
|
97
96
|
|
98
97
|
# The list of distinct expected terminal symbols. An expected symbol
|
99
98
|
# is on the left of a dot in a parse state of the parse set.
|
100
|
-
def expected_terminals
|
99
|
+
def expected_terminals
|
101
100
|
return @entries4term.keys
|
102
101
|
end
|
103
102
|
|
103
|
+
def count_edges
|
104
|
+
# rubocop: disable Lint/UselessAssignment
|
105
|
+
entries.reduce(0) do |sub_result, entry|
|
106
|
+
sub_result += entry.vertex.edges.size
|
107
|
+
end
|
108
|
+
end
|
109
|
+
# rubocop: enable Lint/UselessAssignment
|
110
|
+
|
104
111
|
private
|
105
112
|
|
106
113
|
def add_lookup4symbol(anEntry)
|
107
114
|
symb = anEntry.next_symbol
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
when Syntax::NonTerminal
|
113
|
-
@entries4n_term[symb] << anEntry
|
115
|
+
if symb.kind_of?(Syntax::Terminal)
|
116
|
+
@entries4term[symb] << anEntry
|
117
|
+
else
|
118
|
+
@entries4n_term[symb] << anEntry
|
114
119
|
end
|
115
120
|
end
|
116
121
|
end # class
|