rley 0.3.04 → 0.3.05

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 (99) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +7 -3
  3. data/CHANGELOG.md +3 -0
  4. data/Rakefile +30 -30
  5. data/examples/parsers/parsing_L0.rb +1 -1
  6. data/examples/parsers/parsing_L1.rb +1 -1
  7. data/examples/parsers/parsing_abc.rb +1 -1
  8. data/examples/parsers/parsing_ambig.rb +1 -1
  9. data/examples/parsers/parsing_another.rb +1 -1
  10. data/examples/parsers/parsing_b_expr.rb +1 -1
  11. data/examples/parsers/parsing_err_expr.rb +1 -1
  12. data/examples/parsers/parsing_groucho.rb +1 -1
  13. data/examples/parsers/parsing_right_recursive.rb +1 -1
  14. data/examples/parsers/parsing_tricky.rb +1 -1
  15. data/lib/rley/constants.rb +2 -2
  16. data/lib/rley/formatter/base_formatter.rb +0 -2
  17. data/lib/rley/formatter/debug.rb +0 -2
  18. data/lib/rley/formatter/json.rb +1 -3
  19. data/lib/rley/gfg/call_edge.rb +31 -30
  20. data/lib/rley/gfg/edge.rb +22 -23
  21. data/lib/rley/gfg/end_vertex.rb +22 -24
  22. data/lib/rley/gfg/epsilon_edge.rb +20 -21
  23. data/lib/rley/gfg/grm_flow_graph.rb +39 -39
  24. data/lib/rley/gfg/item_vertex.rb +16 -17
  25. data/lib/rley/gfg/non_terminal_vertex.rb +3 -4
  26. data/lib/rley/gfg/return_edge.rb +32 -31
  27. data/lib/rley/gfg/scan_edge.rb +25 -26
  28. data/lib/rley/gfg/shortcut_edge.rb +25 -26
  29. data/lib/rley/gfg/start_vertex.rb +0 -2
  30. data/lib/rley/gfg/vertex.rb +8 -8
  31. data/lib/rley/parse_forest_visitor.rb +113 -115
  32. data/lib/rley/parse_tree_visitor.rb +0 -2
  33. data/lib/rley/parser/base_parser.rb +27 -27
  34. data/lib/rley/parser/chart.rb +14 -14
  35. data/lib/rley/parser/dotted_item.rb +33 -33
  36. data/lib/rley/parser/earley_parser.rb +6 -6
  37. data/lib/rley/parser/gfg_chart.rb +8 -15
  38. data/lib/rley/parser/gfg_earley_parser.rb +15 -13
  39. data/lib/rley/parser/gfg_parsing.rb +26 -22
  40. data/lib/rley/parser/grm_items_builder.rb +3 -2
  41. data/lib/rley/parser/parse_entry.rb +3 -9
  42. data/lib/rley/parser/parse_entry_set.rb +14 -19
  43. data/lib/rley/parser/parse_entry_tracker.rb +56 -56
  44. data/lib/rley/parser/parse_forest_builder.rb +215 -214
  45. data/lib/rley/parser/parse_forest_factory.rb +57 -56
  46. data/lib/rley/parser/parse_state.rb +8 -11
  47. data/lib/rley/parser/parse_state_tracker.rb +56 -56
  48. data/lib/rley/parser/parse_tracer.rb +3 -3
  49. data/lib/rley/parser/parse_tree_builder.rb +10 -10
  50. data/lib/rley/parser/parse_walker_factory.rb +30 -33
  51. data/lib/rley/parser/parsing.rb +8 -8
  52. data/lib/rley/parser/state_set.rb +23 -26
  53. data/lib/rley/ptree/non_terminal_node.rb +1 -1
  54. data/lib/rley/ptree/token_range.rb +2 -2
  55. data/lib/rley/sppf/alternative_node.rb +32 -34
  56. data/lib/rley/sppf/composite_node.rb +27 -27
  57. data/lib/rley/sppf/epsilon_node.rb +26 -27
  58. data/lib/rley/sppf/leaf_node.rb +11 -12
  59. data/lib/rley/sppf/non_terminal_node.rb +37 -38
  60. data/lib/rley/sppf/sppf_node.rb +1 -1
  61. data/lib/rley/sppf/token_node.rb +29 -29
  62. data/lib/rley/syntax/grammar.rb +1 -3
  63. data/lib/rley/syntax/grammar_builder.rb +8 -8
  64. data/lib/rley/syntax/non_terminal.rb +2 -4
  65. data/lib/rley/syntax/production.rb +3 -3
  66. data/lib/rley/syntax/symbol_seq.rb +1 -1
  67. data/spec/rley/gfg/call_edge_spec.rb +50 -51
  68. data/spec/rley/gfg/edge_spec.rb +33 -33
  69. data/spec/rley/gfg/end_vertex_spec.rb +26 -27
  70. data/spec/rley/gfg/epsilon_edge_spec.rb +25 -25
  71. data/spec/rley/gfg/grm_flow_graph_spec.rb +1 -1
  72. data/spec/rley/gfg/item_vertex_spec.rb +3 -4
  73. data/spec/rley/gfg/return_edge_spec.rb +51 -51
  74. data/spec/rley/gfg/scan_edge_spec.rb +32 -30
  75. data/spec/rley/gfg/shortcut_edge_spec.rb +1 -1
  76. data/spec/rley/gfg/vertex_spec.rb +3 -3
  77. data/spec/rley/parse_forest_visitor_spec.rb +239 -238
  78. data/spec/rley/parser/dotted_item_spec.rb +1 -1
  79. data/spec/rley/parser/earley_parser_spec.rb +16 -16
  80. data/spec/rley/parser/gfg_earley_parser_spec.rb +30 -31
  81. data/spec/rley/parser/gfg_parsing_spec.rb +11 -10
  82. data/spec/rley/parser/grm_items_builder_spec.rb +2 -2
  83. data/spec/rley/parser/parse_entry_set_spec.rb +4 -4
  84. data/spec/rley/parser/parse_entry_spec.rb +0 -2
  85. data/spec/rley/parser/parse_forest_builder_spec.rb +82 -57
  86. data/spec/rley/parser/parse_forest_factory_spec.rb +84 -82
  87. data/spec/rley/parser/parse_walker_factory_spec.rb +10 -9
  88. data/spec/rley/parser/parsing_spec.rb +0 -1
  89. data/spec/rley/sppf/alternative_node_spec.rb +2 -2
  90. data/spec/rley/sppf/non_terminal_node_spec.rb +0 -1
  91. data/spec/rley/support/ambiguous_grammar_helper.rb +1 -1
  92. data/spec/rley/support/expectation_helper.rb +37 -36
  93. data/spec/rley/support/grammar_abc_helper.rb +17 -17
  94. data/spec/rley/support/grammar_b_expr_helper.rb +40 -39
  95. data/spec/rley/support/grammar_helper.rb +2 -1
  96. data/spec/rley/support/{grammar_L0_helper.rb → grammar_l0_helper.rb} +82 -81
  97. data/spec/rley/support/grammar_sppf_helper.rb +24 -25
  98. data/spec/rley/syntax/grammar_spec.rb +1 -1
  99. metadata +2 -2
@@ -16,11 +16,8 @@ module Rley # This module is used as a namespace
16
16
  def ==(other)
17
17
  return true if object_id == other.object_id
18
18
 
19
- if (dotted_rule == other.dotted_rule) && (origin == other.origin)
20
- result = true
21
- else
22
- result = false
23
- end
19
+ result = (dotted_rule == other.dotted_rule) &&
20
+ (origin == other.origin)
24
21
 
25
22
  return result
26
23
  end
@@ -50,11 +47,11 @@ module Rley # This module is used as a namespace
50
47
  return false unless dotted_rule.production == other_production
51
48
 
52
49
  prev_position = other.dotted_rule.prev_position
53
- if prev_position.nil?
54
- result = false
55
- else
56
- result = dotted_rule.position == prev_position
57
- end
50
+ result = if prev_position.nil?
51
+ false
52
+ else
53
+ dotted_rule.position == prev_position
54
+ end
58
55
 
59
56
  return result
60
57
  end
@@ -72,7 +69,7 @@ module Rley # This module is used as a namespace
72
69
 
73
70
  # Return the validated dotted item(rule)
74
71
  def valid_dotted_rule(aDottedRule)
75
- fail StandardError, 'Dotted item cannot be nil' if aDottedRule.nil?
72
+ raise StandardError, 'Dotted item cannot be nil' if aDottedRule.nil?
76
73
 
77
74
  return aDottedRule
78
75
  end
@@ -1,56 +1,56 @@
1
- module Rley # This module is used as a namespace
2
- module Parser # This module is used as a namespace
3
- # Helper class that keeps track of the parse states used
4
- # while a Parsing instance is constructing a parse tree.
5
- class ParseStateTracker
6
- # The index of the current state set
7
- attr_reader(:state_set_index)
8
-
9
- # The current parse state
10
- attr_reader(:parse_state)
11
-
12
- # The already processed states from current state set
13
- attr_reader(:processed_states)
14
-
15
- # Constructor. Refined variant of the inherited constructor.
16
- def initialize(aStateSetIndex)
17
- self.state_set_index = aStateSetIndex
18
- end
19
-
20
- # Write accessor. Sets the value of the state set index
21
- def state_set_index=(anIndex)
22
- @state_set_index = anIndex
23
- @processed_states = {}
24
- end
25
-
26
- # Write accessor. Set the given parse state as the current one.
27
- def parse_state=(aParseState)
28
- fail StandardError, 'Nil parse state' if aParseState.nil?
29
- @parse_state = aParseState
30
- processed_states[parse_state] = true
31
- end
32
-
33
- # Take the first provided state that wasn't processed yet.
34
- def select_state(theStates)
35
- a_state = theStates.find { |st| !processed_states.include?(st) }
36
- self.parse_state = a_state
37
- end
38
-
39
- # The dotted item for the current parse state.
40
- def curr_dotted_item()
41
- parse_state.dotted_rule
42
- end
43
-
44
- def symbol_on_left()
45
- return curr_dotted_item.prev_symbol
46
- end
47
-
48
- # Notification that one begins with the previous state set
49
- def to_prev_state_set()
50
- self.state_set_index = state_set_index - 1
51
- end
52
- end # class
53
- end # module
54
- end # module
55
-
56
- # End of file
1
+ module Rley # This module is used as a namespace
2
+ module Parser # This module is used as a namespace
3
+ # Helper class that keeps track of the parse states used
4
+ # while a Parsing instance is constructing a parse tree.
5
+ class ParseStateTracker
6
+ # The index of the current state set
7
+ attr_reader(:state_set_index)
8
+
9
+ # The current parse state
10
+ attr_reader(:parse_state)
11
+
12
+ # The already processed states from current state set
13
+ attr_reader(:processed_states)
14
+
15
+ # Constructor. Refined variant of the inherited constructor.
16
+ def initialize(aStateSetIndex)
17
+ self.state_set_index = aStateSetIndex
18
+ end
19
+
20
+ # Write accessor. Sets the value of the state set index
21
+ def state_set_index=(anIndex)
22
+ @state_set_index = anIndex
23
+ @processed_states = {}
24
+ end
25
+
26
+ # Write accessor. Set the given parse state as the current one.
27
+ def parse_state=(aParseState)
28
+ raise StandardError, 'Nil parse state' if aParseState.nil?
29
+ @parse_state = aParseState
30
+ processed_states[parse_state] = true
31
+ end
32
+
33
+ # Take the first provided state that wasn't processed yet.
34
+ def select_state(theStates)
35
+ a_state = theStates.find { |st| !processed_states.include?(st) }
36
+ self.parse_state = a_state
37
+ end
38
+
39
+ # The dotted item for the current parse state.
40
+ def curr_dotted_item()
41
+ parse_state.dotted_rule
42
+ end
43
+
44
+ def symbol_on_left()
45
+ return curr_dotted_item.prev_symbol
46
+ end
47
+
48
+ # Notification that one begins with the previous state set
49
+ def to_prev_state_set()
50
+ self.state_set_index = state_set_index - 1
51
+ end
52
+ end # class
53
+ end # module
54
+ end # module
55
+
56
+ # End of file
@@ -49,7 +49,7 @@ module Rley # This module is used as a namespace
49
49
  def trace_completion(aStatesetIndex, aParseState)
50
50
  return unless level
51
51
 
52
- if aStatesetIndex == lexemes.size && aParseState.origin == 0 &&
52
+ if aStatesetIndex == lexemes.size && aParseState.origin.zero? &&
53
53
  aParseState.complete?
54
54
  picture = '=' * (col_width * lexemes.size - 1)
55
55
  else
@@ -70,13 +70,13 @@ module Rley # This module is used as a namespace
70
70
  def emit_heading()
71
71
  longest = lexemes.map(&:length).max
72
72
  @col_width = longest + 3
73
- headers = lexemes.map { |l| "#{l.center(col_width - 1, ' ')}" }
73
+ headers = lexemes.map { |l| l.center(col_width - 1, ' ').to_s }
74
74
  print_if 1, '|.' + headers.join('.') + ".|\n"
75
75
  end
76
76
 
77
77
  def padding(aStatesetIndex, aParseState, aPicture)
78
78
  l_pad_pattern = '.' + ' ' * (col_width - 1)
79
- left_padding = l_pad_pattern * ([0, aParseState.origin].max)
79
+ left_padding = l_pad_pattern * [0, aParseState.origin].max
80
80
  r_pad_pattern = ' ' * (col_width - 1) + '.'
81
81
  right_padding = r_pad_pattern * (lexemes.size - aStatesetIndex)
82
82
  return left_padding + aPicture + right_padding
@@ -49,7 +49,7 @@ module Rley # This module is used as a namespace
49
49
  curr_node = current_node
50
50
  unless curr_node.is_a?(PTree::NonTerminalNode)
51
51
  msg = "Current node isn't a non-terminal node #{curr_node.class}"
52
- fail StandardError, msg
52
+ raise StandardError, msg
53
53
  end
54
54
  children = curr_node.children
55
55
  path_increment = [children.size - 1, children.last]
@@ -122,7 +122,7 @@ module Rley # This module is used as a namespace
122
122
  if curr_node.symbol != prod.lhs
123
123
  snapshot = root.to_string(0)
124
124
  msg = "Current node is a #{curr_node.symbol} instead of #{prod.lhs}."
125
- fail StandardError, msg + "\n" + snapshot
125
+ raise StandardError, msg + "\n" + snapshot
126
126
  end
127
127
  self.range = aRange
128
128
  prod.rhs.each { |symb| add_node(symb, {}) }
@@ -153,20 +153,20 @@ module Rley # This module is used as a namespace
153
153
 
154
154
  def low_bound(aRange)
155
155
  result = case aRange
156
- when Fixnum then aRange
157
- when Hash then aRange[:low]
158
- when PTree::TokenRange then aRange.low
159
- end
156
+ when Integer then aRange
157
+ when Hash then aRange[:low]
158
+ when PTree::TokenRange then aRange.low
159
+ end
160
160
 
161
161
  return { low: result }
162
162
  end
163
163
 
164
164
  def high_bound(aRange)
165
165
  result = case aRange
166
- when Fixnum then aRange
167
- when Hash then aRange[:high]
168
- when PTree::TokenRange then aRange.high
169
- end
166
+ when Integer then aRange
167
+ when Hash then aRange[:high]
168
+ when PTree::TokenRange then aRange.high
169
+ end
170
170
 
171
171
  return { high: result }
172
172
  end
@@ -9,16 +9,16 @@ require_relative '../gfg/start_vertex'
9
9
  module Rley # This module is used as a namespace
10
10
  module Parser # This module is used as a namespace
11
11
  ParseWalkerContext = Struct.new(
12
- :curr_entry, # Parse entry currently being visited
13
- :entry_set_index, # Sigma set index of current parse entry
14
- :visitees, # The set of already visited parse entries
12
+ :curr_entry, # Parse entry currently being visited
13
+ :entry_set_index, # Sigma set index of current parse entry
14
+ :visitees, # The set of already visited parse entries
15
15
  :nterm2start, # A Hash non-terminal symbol => start entry
16
16
  :return_stack, # A stack of parse entries
17
17
  :backtrack_points
18
18
  )
19
19
 
20
20
  WalkerBacktrackpoint = Struct.new(
21
- :entry_set_index, # Sigma set index of current parse entry
21
+ :entry_set_index, # Sigma set index of current parse entry
22
22
  :return_stack, # A stack of parse entries
23
23
  :visitee, # The parse entry being visited
24
24
  :antecedent_index
@@ -31,11 +31,11 @@ module Rley # This module is used as a namespace
31
31
  # Terminology warning: this class implements an external iterator
32
32
  # for a given GFGParsing object. In other words, its instances are objects
33
33
  # distinct for the GFGParsing.
34
- # This is different from the internal iterators, usually implemented in Ruby
35
- # with an each method.
34
+ # This is different from the internal iterators, usually implemented
35
+ # in Ruby with an :each method.
36
36
  # Allows to perform a backwards traversal over the relevant parse entries.
37
- # backwards traversal means that the traversal starts from the accepting (final)
38
- # parse entries and goes to the initial parse entry.
37
+ # backwards traversal means that the traversal starts from the
38
+ # accepting (final) parse entries and goes to the initial parse entry.
39
39
  # Relevant parse entries are parse entries that "count" in the parse
40
40
  # (i.e. they belong to a path that leads to the accepting parse entry)
41
41
  class ParseWalkerFactory
@@ -53,16 +53,13 @@ module Rley # This module is used as a namespace
53
53
  receiver << event unless event.nil?
54
54
 
55
55
  if ctx.curr_entry.orphan? # No antecedent?...
56
- if ctx.backtrack_points.empty?
57
- break
58
- else
59
- receiver << use_backtrack_point(ctx)
60
- receiver << visit_entry(ctx.curr_entry, ctx)
61
- end
56
+ break if ctx.backtrack_points.empty?
57
+ receiver << use_backtrack_point(ctx)
58
+ receiver << visit_entry(ctx.curr_entry, ctx)
62
59
  end
63
60
 
64
61
  result = jump_to_antecedent(ctx)
65
- # Emit detection of scan edge if any...
62
+ # Emit detection of scan edge if any...
66
63
  receiver << result[0] if result.size > 1
67
64
  ctx.curr_entry = result.last
68
65
  end
@@ -71,7 +68,8 @@ module Rley # This module is used as a namespace
71
68
  return walker
72
69
  end
73
70
 
74
- private
71
+ private
72
+
75
73
  # Context factory method
76
74
  def init_context(acceptingEntry, maxIndex)
77
75
  context = ParseWalkerContext.new
@@ -108,8 +106,8 @@ private
108
106
  when GFG::ItemVertex
109
107
  # Skip item entries while revisiting
110
108
  event = nil
111
- else
112
- fail NotImplementedError
109
+ else
110
+ raise NotImplementedError
113
111
  end
114
112
  else
115
113
  # first time visit
@@ -120,7 +118,7 @@ private
120
118
  return event
121
119
  end
122
120
 
123
- def detect_scan_edge(ctx)
121
+ def detect_scan_edge(_ctx)
124
122
  return nil unless aContext.curr_entry.dotted_entry?
125
123
  end
126
124
 
@@ -131,12 +129,12 @@ private
131
129
  def jump_to_antecedent(aContext)
132
130
  entries = []
133
131
  return entries if aContext.curr_entry.orphan?
134
-
135
- if aContext.curr_entry.antecedents.size == 1
136
- entries = antecedent_of(aContext)
137
- else
138
- entries = select_antecedent(aContext)
139
- end
132
+
133
+ entries = if aContext.curr_entry.antecedents.size == 1
134
+ antecedent_of(aContext)
135
+ else
136
+ select_antecedent(aContext)
137
+ end
140
138
 
141
139
  return entries
142
140
  end
@@ -153,15 +151,15 @@ private
153
151
  aContext.return_stack << aContext.curr_entry
154
152
  elsif traversed_edge.kind_of?(GFG::CallEdge)
155
153
  # Pop top of stack
156
- tos = aContext.return_stack.pop
154
+ aContext.return_stack.pop
157
155
  # puts "Pop from return stack matching entry #{new_entry}"
158
- elsif traversed_edge.kind_of?(GFG::ScanEdge)
156
+ elsif traversed_edge.kind_of?(GFG::ScanEdge)
159
157
  # Scan edge encountered, decrease sigma set index
160
158
  aContext.entry_set_index -= 1
161
159
  elsif traversed_edge.kind_of?(GFG::EpsilonEdge)
162
160
  # Do nothing
163
161
  else
164
- fail NotImplementedError, "edge is a #{traversed_edge.class}"
162
+ raise NotImplementedError, "edge is a #{traversed_edge.class}"
165
163
  end
166
164
 
167
165
  return events
@@ -180,7 +178,7 @@ private
180
178
  when GFG::StartVertex
181
179
  new_entry = select_calling_entry(aContext)
182
180
  else
183
- fail StandardError, "Internal error"
181
+ raise StandardError, 'Internal error'
184
182
  end
185
183
 
186
184
  return [ new_entry ]
@@ -213,7 +211,7 @@ private
213
211
  aContext.backtrack_points.pop
214
212
  end
215
213
  # puts "Backtracking to #{bp.visitee}"
216
-
214
+
217
215
  # Emit a backtrack event
218
216
  return [:backtrack, bp.visitee, aContext.entry_set_index]
219
217
  end
@@ -233,8 +231,7 @@ private
233
231
  item = antecd.vertex.dotted_item
234
232
  (antecd.origin == tos.origin) && tos_dotted_item.successor_of?(item)
235
233
  end
236
-
237
- # TODO: double-check validity of next line
234
+
238
235
  new_entry = aContext.curr_entry unless new_entry
239
236
 
240
237
  # puts "Pop from return stack matching entry #{new_entry}"
@@ -242,4 +239,4 @@ private
242
239
  end
243
240
  end # class
244
241
  end # module
245
- end # module
242
+ end # module
@@ -32,7 +32,7 @@ module Rley # This module is used as a namespace
32
32
 
33
33
  # Retrieve all the complete states with start symbol in lhs
34
34
  end_states = last_chart_entry.states_rewriting(start_symbol)
35
- success_states = end_states.select { |st| st.origin == 0 }
35
+ success_states = end_states.select { |st| st.origin.zero? }
36
36
 
37
37
  return !success_states.empty?
38
38
  end
@@ -41,7 +41,7 @@ module Rley # This module is used as a namespace
41
41
  # for the same lhs and same origin in any state set.
42
42
  def ambiguous?()
43
43
  found = chart.state_sets.find { |set| !set.ambiguities.empty? }
44
- return ! found.nil?
44
+ return !found.nil?
45
45
  end
46
46
 
47
47
  # Factory method. Builds a ParseTree from the parse result.
@@ -74,7 +74,7 @@ module Rley # This module is used as a namespace
74
74
  # Push a parse state (dotted item + origin) to the
75
75
  # chart entry with given index if it isn't yet in the chart entry.
76
76
  def push_state(aDottedItem, anOrigin, aChartIndex, aReason)
77
- fail StandardError, 'Dotted item may not be nil' if aDottedItem.nil?
77
+ raise StandardError, 'Dotted item may not be nil' if aDottedItem.nil?
78
78
  chart.push_state(aDottedItem, anOrigin, aChartIndex, aReason)
79
79
  end
80
80
 
@@ -93,13 +93,13 @@ module Rley # This module is used as a namespace
93
93
  # @param aPosition [Fixnum] position in the input token sequence.
94
94
  # @param nextMapping [Proc or Lambda] code to evaluate in order to
95
95
  # determine the "next" dotted rule for a given one.
96
- def scanning(aTerminal, aPosition, &nextMapping)
96
+ def scanning(aTerminal, aPosition, &_nextMapping)
97
97
  curr_token = tokens[aPosition]
98
98
  return unless curr_token.terminal == aTerminal
99
99
 
100
100
  states = states_expecting(aTerminal, aPosition, false)
101
101
  states.each do |s|
102
- next_item = nextMapping.call(s.dotted_rule)
102
+ next_item = yield s.dotted_rule
103
103
  push_state(next_item, s.origin, aPosition + 1, :scanning)
104
104
  end
105
105
  end
@@ -115,12 +115,12 @@ module Rley # This module is used as a namespace
115
115
  # In other words, rules that predicted the non-terminal X.
116
116
  # For each s, add to chart[aPosition] a state of the form
117
117
  # { dotted_rule: Y → α X • β, origin: i})
118
- def completion(aState, aPosition, &nextMapping)
118
+ def completion(aState, aPosition, &_nextMapping)
119
119
  curr_origin = aState.origin
120
120
  curr_lhs = aState.dotted_rule.lhs
121
121
  states = states_expecting(curr_lhs, curr_origin, false)
122
122
  states.each do |s|
123
- next_item = nextMapping.call(s.dotted_rule)
123
+ next_item = yield s.dotted_rule
124
124
  push_state(next_item, s.origin, aPosition, :completion)
125
125
  end
126
126
  end
@@ -207,7 +207,7 @@ module Rley # This module is used as a namespace
207
207
  aTreeBuilder.current_node.range = { low: index, high: index + 1 }
208
208
  link_node_to_token(aTreeBuilder, aStateTracker.state_set_index)
209
209
  unless aTreeBuilder.current_node.is_a?(PTree::TerminalNode)
210
- fail StandardError, 'Expected terminal node'
210
+ raise StandardError, 'Expected terminal node'
211
211
  end
212
212
  aTreeBuilder.move_back
213
213
  state_set = chart[aStateTracker.state_set_index]
@@ -9,7 +9,6 @@ module Rley # This module is used as a namespace
9
9
  # The set of parse states
10
10
  attr_reader(:states)
11
11
 
12
-
13
12
  def initialize()
14
13
  @states = []
15
14
  end
@@ -22,72 +21,70 @@ module Rley # This module is used as a namespace
22
21
  if include?(aState)
23
22
  result = false
24
23
  else
25
- @states << aState
24
+ @states << aState
26
25
  result = true
27
26
  end
28
-
27
+
29
28
  return result
30
29
  end
31
30
 
32
31
  # The list of ParseState that expect the given symbol.
33
- # @param aSymbol [GrmSymbol] the expected symbol
32
+ # @param aSymbol [GrmSymbol] the expected symbol
34
33
  # (=on the right of the dot)
35
34
  def states_expecting(aSymbol)
36
35
  return states.select { |s| s.dotted_rule.next_symbol == aSymbol }
37
36
  end
38
-
39
37
 
40
- # The list of complete ParseState that have the given non-terminal
38
+
39
+ # The list of complete ParseState that have the given non-terminal
41
40
  # symbol as the lhs of their production.
42
41
  def states_rewriting(aNonTerm)
43
- return states.select do |s|
42
+ return states.select do |s|
44
43
  (s.dotted_rule.production.lhs == aNonTerm) && s.complete?
45
44
  end
46
45
  end
47
-
46
+
48
47
  # The list of ParseState that involve the given production
49
48
  def states_for(aProduction)
50
49
  return states.select { |s| s.dotted_rule.production == aProduction }
51
50
  end
52
-
51
+
53
52
  # Retrieve the parse state that is the predecessor of the given one.
54
- def predecessor_state(aParseState)
55
- if aParseState.dotted_rule.prev_position.nil?
56
- fail StandardError, "#{aParseState}"
57
- else
58
- candidate = states.find { |s| s.precedes?(aParseState) }
59
- end
60
-
53
+ def predecessor_state(aPState)
54
+ dotted_rule = aPState.dotted_rule
55
+ raise StandardError, aPState.to_s unless dotted_rule.prev_position
56
+
57
+ candidate = states.find { |s| s.precedes?(aPState) }
61
58
  return candidate
62
59
  end
63
-
60
+
64
61
  # The list of distinct expected terminal symbols. An expected symbol
65
62
  # is on the left of a dot in a parse state of the parse set.
66
63
  def expected_terminals()
67
- expecting_terminals = states.select do |s|
68
- s.dotted_rule.next_symbol.kind_of?(Rley::Syntax::Terminal)
64
+ expecting_terminals = states.select do |s|
65
+ s.dotted_rule.next_symbol.kind_of?(Rley::Syntax::Terminal)
69
66
  end
70
-
67
+
71
68
  terminals = expecting_terminals.map { |s| s.dotted_rule.next_symbol }
72
69
  return terminals.uniq
73
70
  end
74
-
71
+
75
72
  # Return an Array of Arrays of ambiguous parse states.
76
73
  def ambiguities()
77
- complete_states = states.select { |st| st.complete? }
74
+ complete_states = states.select(&:complete?)
78
75
  return [] if complete_states.size <= 1
79
-
76
+
80
77
  # Group parse state by lhs symbol and origin
81
78
  groupings = complete_states.group_by do |st|
82
- "#{st.dotted_rule.lhs.object_id}"
79
+ st.dotted_rule.lhs.object_id.to_s
83
80
  end
84
-
81
+
85
82
  # Retain the groups having more than one element.
86
83
  ambiguous_groups = []
87
84
  groupings.each_value do |a_group|
88
85
  ambiguous_groups << a_group if a_group.size > 1
89
86
  end
90
-
87
+
91
88
  return ambiguous_groups
92
89
  end
93
90