rley 0.3.04 → 0.3.05

Sign up to get free protection for your applications and to get access to all the features.
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