rley 0.8.14 → 0.8.15

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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +20 -2
  3. data/CHANGELOG.md +3 -0
  4. data/examples/general/calc_iter1/spec/calculator_spec.rb +9 -9
  5. data/examples/general/calc_iter2/spec/calculator_spec.rb +39 -39
  6. data/examples/general/recursive_right.rb +2 -2
  7. data/lib/rley/constants.rb +1 -1
  8. data/lib/rley/gfg/grm_flow_graph.rb +0 -1
  9. data/lib/rley/parser/parse_entry_set.rb +0 -1
  10. data/lib/rley/parser/parse_walker_factory.rb +0 -1
  11. data/lib/rley/rgn/grammar_builder.rb +0 -2
  12. data/lib/rley/rgn/tokenizer.rb +1 -1
  13. data/lib/rley/syntax/base_grammar_builder.rb +0 -1
  14. data/lib/rley/syntax/grammar.rb +0 -1
  15. data/spec/rley/base/dotted_item_spec.rb +46 -46
  16. data/spec/rley/base/grm_items_builder_spec.rb +1 -1
  17. data/spec/rley/engine_spec.rb +50 -50
  18. data/spec/rley/formatter/asciitree_spec.rb +8 -8
  19. data/spec/rley/formatter/bracket_notation_spec.rb +10 -10
  20. data/spec/rley/formatter/debug_spec.rb +10 -10
  21. data/spec/rley/formatter/json_spec.rb +6 -7
  22. data/spec/rley/gfg/call_edge_spec.rb +6 -6
  23. data/spec/rley/gfg/edge_spec.rb +8 -7
  24. data/spec/rley/gfg/end_vertex_spec.rb +8 -7
  25. data/spec/rley/gfg/epsilon_edge_spec.rb +5 -4
  26. data/spec/rley/gfg/grm_flow_graph_spec.rb +33 -34
  27. data/spec/rley/gfg/item_vertex_spec.rb +34 -36
  28. data/spec/rley/gfg/non_terminal_vertex_spec.rb +12 -12
  29. data/spec/rley/gfg/return_edge_spec.rb +6 -6
  30. data/spec/rley/gfg/scan_edge_spec.rb +7 -6
  31. data/spec/rley/gfg/shortcut_edge_spec.rb +15 -15
  32. data/spec/rley/gfg/start_vertex_spec.rb +8 -8
  33. data/spec/rley/gfg/vertex_spec.rb +18 -18
  34. data/spec/rley/lexical/literal_spec.rb +5 -5
  35. data/spec/rley/lexical/token_range_spec.rb +55 -55
  36. data/spec/rley/lexical/token_spec.rb +17 -16
  37. data/spec/rley/parse_forest_visitor_spec.rb +30 -32
  38. data/spec/rley/parse_rep/ambiguous_parse_spec.rb +2 -2
  39. data/spec/rley/parse_rep/ast_builder_spec.rb +30 -30
  40. data/spec/rley/parse_rep/cst_builder_spec.rb +85 -85
  41. data/spec/rley/parse_rep/groucho_spec.rb +23 -23
  42. data/spec/rley/parse_rep/parse_forest_builder_spec.rb +42 -42
  43. data/spec/rley/parse_rep/parse_forest_factory_spec.rb +10 -12
  44. data/spec/rley/parse_rep/parse_tree_factory_spec.rb +10 -15
  45. data/spec/rley/parse_tree_visitor_spec.rb +43 -46
  46. data/spec/rley/parser/dangling_else_spec.rb +12 -12
  47. data/spec/rley/parser/error_reason_spec.rb +37 -37
  48. data/spec/rley/parser/gfg_chart_spec.rb +27 -29
  49. data/spec/rley/parser/gfg_earley_parser_spec.rb +55 -56
  50. data/spec/rley/parser/gfg_parsing_spec.rb +106 -103
  51. data/spec/rley/parser/parse_entry_set_spec.rb +63 -61
  52. data/spec/rley/parser/parse_entry_spec.rb +73 -71
  53. data/spec/rley/parser/parse_walker_factory_spec.rb +14 -15
  54. data/spec/rley/ptree/non_terminal_node_spec.rb +16 -16
  55. data/spec/rley/ptree/parse_tree_node_spec.rb +11 -11
  56. data/spec/rley/ptree/parse_tree_spec.rb +6 -8
  57. data/spec/rley/ptree/terminal_node_spec.rb +6 -6
  58. data/spec/rley/rgn/grammar_builder_spec.rb +69 -67
  59. data/spec/rley/rgn/parser_spec.rb +63 -63
  60. data/spec/rley/rgn/repetition_node_spec.rb +15 -15
  61. data/spec/rley/rgn/sequence_node_spec.rb +10 -10
  62. data/spec/rley/rgn/symbol_node_spec.rb +5 -6
  63. data/spec/rley/rgn/tokenizer_spec.rb +68 -67
  64. data/spec/rley/sppf/alternative_node_spec.rb +16 -16
  65. data/spec/rley/sppf/non_terminal_node_spec.rb +20 -20
  66. data/spec/rley/sppf/token_node_spec.rb +13 -13
  67. data/spec/rley/syntax/base_grammar_builder_spec.rb +76 -86
  68. data/spec/rley/syntax/grammar_spec.rb +40 -78
  69. data/spec/rley/syntax/grm_symbol_spec.rb +7 -7
  70. data/spec/rley/syntax/match_closest_spec.rb +8 -8
  71. data/spec/rley/syntax/non_terminal_spec.rb +25 -25
  72. data/spec/rley/syntax/production_spec.rb +33 -33
  73. data/spec/rley/syntax/symbol_seq_spec.rb +27 -27
  74. data/spec/rley/syntax/terminal_spec.rb +12 -11
  75. data/spec/support/base_tokenizer_spec.rb +9 -8
  76. metadata +2 -2
@@ -18,6 +18,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
18
18
  include GrammarHelper # Mix-in with token factory method
19
19
  include ExpectationHelper # Mix-in with expectation on parse entry sets
20
20
 
21
+ subject(:a_builder) { described_class.new(sample_tokens) }
22
+
21
23
  let(:sample_grammar) do
22
24
  # Grammar based on paper from Elisabeth Scott
23
25
  # "SPPF=Style Parsing From Earley Recognizers" in
@@ -45,11 +47,9 @@ module Rley # Open this namespace to avoid module qualifier prefixes
45
47
  parser.parse(sample_tokens)
46
48
  end
47
49
 
48
- subject { ParseForestBuilder.new(sample_tokens) }
49
-
50
50
  # Emit a text representation of the current path.
51
51
  def path_to_s
52
- text_parts = subject.curr_path.map do |path_element|
52
+ text_parts = a_builder.curr_path.map do |path_element|
53
53
  path_element.to_string(0)
54
54
  end
55
55
  text_parts.join('/')
@@ -57,13 +57,13 @@ module Rley # Open this namespace to avoid module qualifier prefixes
57
57
 
58
58
  def next_event(eventType, anEntryText)
59
59
  event = @walker.next
60
- subject.receive_event(*event)
60
+ a_builder.receive_event(*event)
61
61
  expect(event[0]).to eq(eventType)
62
62
  expect(event[1].to_s).to eq(anEntryText)
63
63
  end
64
64
 
65
65
  def expected_curr_parent(anExpectation)
66
- expect(subject.curr_parent.to_string(0)).to eq(anExpectation)
66
+ expect(a_builder.curr_parent.to_string(0)).to eq(anExpectation)
67
67
  end
68
68
 
69
69
  def expected_curr_path(anExpectation)
@@ -71,41 +71,41 @@ module Rley # Open this namespace to avoid module qualifier prefixes
71
71
  end
72
72
 
73
73
  def expected_first_child(anExpectation)
74
- child = subject.curr_parent.subnodes.first
74
+ child = a_builder.curr_parent.subnodes.first
75
75
  expect(child.to_string(0)).to eq(anExpectation)
76
76
  end
77
77
 
78
78
  context 'Initialization:' do
79
- it 'should be created with a sequence of tokens' do
80
- expect { ParseForestBuilder.new(sample_tokens) }.not_to raise_error
79
+ it 'is created with a sequence of tokens' do
80
+ expect { described_class.new(sample_tokens) }.not_to raise_error
81
81
  end
82
82
 
83
- it 'should know the input tokens' do
84
- expect(subject.tokens).to eq(sample_tokens)
83
+ it 'knows the input tokens' do
84
+ expect(a_builder.tokens).to eq(sample_tokens)
85
85
  end
86
86
 
87
- it 'should have an empty path' do
88
- expect(subject.curr_path).to be_empty
87
+ it 'has an empty path' do
88
+ expect(a_builder.curr_path).to be_empty
89
89
  end
90
90
  end # context
91
91
 
92
92
  context 'Parse forest construction' do
93
- before(:each) do
93
+ before do
94
94
  factory = Parser::ParseWalkerFactory.new
95
95
  accept_entry = sample_result.accepting_entry
96
96
  accept_index = sample_result.chart.last_index
97
97
  @walker = factory.build_walker(accept_entry, accept_index, true)
98
98
  end
99
99
 
100
- it 'should initialize the root node' do
100
+ it 'initializes the root node' do
101
101
  next_event(:visit, 'Phi. | 0')
102
- forest = subject.result
102
+ forest = a_builder.result
103
103
 
104
104
  expect(forest.root.to_string(0)).to eq('Phi[0, 4]')
105
105
  expected_curr_path('Phi[0, 4]')
106
106
  end
107
107
 
108
- it 'should initialize the first child of the root node' do
108
+ it 'initializes the first child of the root node' do
109
109
  next_event(:visit, 'Phi. | 0') # Event 1
110
110
  next_event(:visit, 'Phi => S . | 0') # Event 2
111
111
  next_event(:visit, 'S. | 0') # Event 3
@@ -113,41 +113,41 @@ module Rley # Open this namespace to avoid module qualifier prefixes
113
113
  expected_curr_path('Phi[0, 4]/S[0, 4]')
114
114
  end
115
115
 
116
- it 'should build alternative node when detecting backtrack point' do
116
+ it 'builds alternative node when detecting backtrack point' do
117
117
  3.times do
118
118
  event = @walker.next
119
- subject.receive_event(*event)
119
+ a_builder.receive_event(*event)
120
120
  end
121
121
 
122
122
  next_event(:visit, 'S => a T . | 0') # Event 4
123
123
  expected_curr_path('Phi[0, 4]/S[0, 4]/Alt(S => a T .)[0, 4]')
124
- expect(subject.curr_path[-2].refinement).to eq(:or)
124
+ expect(a_builder.curr_path[-2].refinement).to eq(:or)
125
125
  end
126
126
 
127
- it 'should build token node when scan edge was detected' do
127
+ it 'builds token node when scan edge was detected' do
128
128
  4.times do
129
129
  event = @walker.next
130
- subject.receive_event(*event)
130
+ a_builder.receive_event(*event)
131
131
  end
132
132
 
133
133
  next_event(:visit, 'T. | 1') # Event5
134
134
  expected_curr_path('Phi[0, 4]/S[0, 4]/Alt(S => a T .)[0, 4]/T[1, 4]')
135
- expect(subject.curr_parent.subnodes).to be_empty
135
+ expect(a_builder.curr_parent.subnodes).to be_empty
136
136
 
137
137
  next_event(:visit, 'T => b b b . | 1') # Event 6
138
- expect(subject.curr_parent.to_string(0)).to eq('T[1, 4]')
138
+ expect(a_builder.curr_parent.to_string(0)).to eq('T[1, 4]')
139
139
  expected_curr_path('Phi[0, 4]/S[0, 4]/Alt(S => a T .)[0, 4]/T[1, 4]')
140
- expect(subject.curr_parent.subnodes.size).to eq(1)
140
+ expect(a_builder.curr_parent.subnodes.size).to eq(1)
141
141
  expected_first_child('b[3, 4]')
142
142
 
143
143
  next_event(:visit, 'T => b b . b | 1') # Event 7
144
144
  expected_curr_path('Phi[0, 4]/S[0, 4]/Alt(S => a T .)[0, 4]/T[1, 4]')
145
- expect(subject.curr_parent.subnodes.size).to eq(2)
145
+ expect(a_builder.curr_parent.subnodes.size).to eq(2)
146
146
  expected_first_child('b[2, 3]')
147
147
 
148
148
  next_event(:visit, 'T => b . b b | 1') # Event 8
149
149
  expected_curr_path('Phi[0, 4]/S[0, 4]/Alt(S => a T .)[0, 4]/T[1, 4]')
150
- expect(subject.curr_parent.subnodes.size).to eq(3)
150
+ expect(a_builder.curr_parent.subnodes.size).to eq(3)
151
151
  expected_first_child('b[1, 2]')
152
152
 
153
153
  next_event(:visit, 'T => . b b b | 1') # Event 9
@@ -158,7 +158,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
158
158
 
159
159
  next_event(:visit, 'S => a . T | 0') # Event 11
160
160
  expected_curr_path('Phi[0, 4]/S[0, 4]/Alt(S => a T .)[0, 4]')
161
- expect(subject.curr_parent.subnodes.size).to eq(2)
161
+ expect(a_builder.curr_parent.subnodes.size).to eq(2)
162
162
  expected_first_child('a[0, 1]')
163
163
 
164
164
  next_event(:visit, 'S => . a T | 0') # Event 12
@@ -175,26 +175,26 @@ module Rley # Open this namespace to avoid module qualifier prefixes
175
175
  expect(path_to_s).to be_empty
176
176
  end
177
177
 
178
- it 'should handle backtracking' do
178
+ it 'handles backtracking' do
179
179
  15.times do
180
180
  event = @walker.next
181
- subject.receive_event(*event)
181
+ a_builder.receive_event(*event)
182
182
  end
183
183
 
184
184
  # Backtracking is occurring
185
185
  next_event(:backtrack, 'S. | 0') # Event 16
186
186
  expected_curr_path('Phi[0, 4]/S[0, 4]')
187
187
 
188
- # Alternate node should be created
188
+ # Alternate node is created
189
189
  next_event(:visit, 'S => A T . | 0') # Event 17
190
190
  expected_curr_path('Phi[0, 4]/S[0, 4]/Alt(S => A T .)[0, 4]')
191
- expect(subject.curr_path[-2].refinement).to eq(:or)
191
+ expect(a_builder.curr_path[-2].refinement).to eq(:or)
192
192
  end
193
193
 
194
- it 'should detect second time visit of an entry' do
194
+ it 'detects second time visit of an entry' do
195
195
  17.times do
196
196
  event = @walker.next
197
- subject.receive_event(*event)
197
+ a_builder.receive_event(*event)
198
198
  end
199
199
 
200
200
  next_event(:revisit, 'T. | 1') # REVISIT Event 18
@@ -210,7 +210,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
210
210
 
211
211
  next_event(:visit, 'A => a . | 0') # Event 21
212
212
  expected_curr_path("#{path_prefix}Alt(A => a .)[0, 1]")
213
- expect(subject.curr_path[-2].refinement).to eq(:or)
213
+ expect(a_builder.curr_path[-2].refinement).to eq(:or)
214
214
 
215
215
  next_event(:visit, 'A => . a | 0') # Event 22
216
216
  expected_curr_path(expected_path20)
@@ -231,10 +231,10 @@ module Rley # Open this namespace to avoid module qualifier prefixes
231
231
  expected_curr_path('')
232
232
  end
233
233
 
234
- it 'should handle remaining # Events' do
234
+ it 'handles remaining # Events' do
235
235
  27.times do
236
236
  event = @walker.next
237
- subject.receive_event(*event)
237
+ a_builder.receive_event(*event)
238
238
  end
239
239
 
240
240
  # Backtracking is occurring
@@ -280,6 +280,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
280
280
  context 'Natural language processing' do
281
281
  include GrammarL0Helper
282
282
 
283
+ subject(:a_builder) { described_class.new(sentence_tokens) }
284
+
283
285
  let(:grammar_l0) do
284
286
  builder = grammar_l0_builder
285
287
  builder.grammar
@@ -295,16 +297,14 @@ module Rley # Open this namespace to avoid module qualifier prefixes
295
297
  parser.parse(sentence_tokens)
296
298
  end
297
299
 
298
- before(:each) do
300
+ before do
299
301
  factory = Parser::ParseWalkerFactory.new
300
302
  accept_entry = sentence_result.accepting_entry
301
303
  accept_index = sentence_result.chart.last_index
302
304
  @walker = factory.build_walker(accept_entry, accept_index)
303
305
  end
304
306
 
305
- subject { ParseForestBuilder.new(sentence_tokens) }
306
-
307
- it 'should handle walker events' do
307
+ it 'handles walker events' do
308
308
  next_event(:visit, 'S. | 0') # Event 1
309
309
  expected_curr_path('S[0, 5]')
310
310
 
@@ -329,7 +329,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
329
329
 
330
330
  next_event(:visit, 'Nominal => Nominal Noun . | 3') # Event 8
331
331
  expected_curr_path('S[0, 5]/VP[1, 5]/NP[2, 5]/Nominal[3, 5]')
332
- expect(subject.curr_parent.subnodes.size).to eq(1)
332
+ expect(a_builder.curr_parent.subnodes.size).to eq(1)
333
333
  expected_first_child('Noun[4, 5]')
334
334
 
335
335
 
@@ -344,7 +344,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
344
344
  next_event(:visit, 'Nominal => Noun . | 3') # Event11
345
345
  path11 = 'S[0, 5]/VP[1, 5]/NP[2, 5]/Nominal[3, 5]/Nominal[3, 4]'
346
346
  expected_curr_path(path11)
347
- expect(subject.curr_parent.subnodes.size).to eq(1)
347
+ expect(a_builder.curr_parent.subnodes.size).to eq(1)
348
348
  expected_first_child('Noun[3, 4]')
349
349
 
350
350
  next_event(:visit, 'Nominal => . Noun | 3') # Event 12
@@ -17,6 +17,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
17
17
  include GrammarHelper # Mix-in with token factory method
18
18
  include ExpectationHelper # Mix-in with expectation on parse entry sets
19
19
 
20
+ subject(:a_factory) { described_class.new(sample_result) }
21
+
20
22
  let(:sample_grammar) do
21
23
  # Grammar based on paper from Elisabeth Scott
22
24
  # "SPPF-Style Parsing From Earley Recognizers" in
@@ -44,32 +46,28 @@ module Rley # Open this namespace to avoid module qualifier prefixes
44
46
  parser.parse(sample_tokens)
45
47
  end
46
48
 
47
- subject do
48
- ParseForestFactory.new(sample_result)
49
- end
50
-
51
49
  # Emit a text representation of the current path.
52
50
  def path_to_s
53
- text_parts = subject.curr_path.map do |path_element|
51
+ text_parts = a_factory.curr_path.map do |path_element|
54
52
  path_element.to_string(0)
55
53
  end
56
54
  text_parts.join('/')
57
55
  end
58
56
 
59
57
  context 'Initialization:' do
60
- it 'should be created with a GFGParsing' do
61
- expect { ParseForestFactory.new(sample_result) }.not_to raise_error
58
+ it 'is created with a GFGParsing' do
59
+ expect { described_class.new(sample_result) }.not_to raise_error
62
60
  end
63
61
 
64
- it 'should know the parse result' do
65
- expect(subject.parsing).to eq(sample_result)
62
+ it 'knows the parse result' do
63
+ expect(a_factory.parsing).to eq(sample_result)
66
64
  end
67
65
  end
68
66
 
69
67
  context 'Parse forest construction' do
70
- it 'should build a parse forest' do
71
- forest = subject.create
72
- expect(forest).to be_kind_of(SPPF::ParseForest)
68
+ it 'builds a parse forest' do
69
+ forest = a_factory.create
70
+ expect(forest).to be_a(SPPF::ParseForest)
73
71
  end
74
72
  end # context
75
73
  end # describe
@@ -18,28 +18,23 @@ module Rley # Open this namespace to avoid module qualifier prefixes
18
18
  include ExpectationHelper # Mix-in with expectation on parse entry sets
19
19
  include GrammarABCHelper # Mix-in for a sample grammar
20
20
 
21
+ subject(:a_factory) { described_class.new(sample_result) }
22
+
21
23
  let(:sample_grammar) do
22
24
  builder = grammar_abc_builder
23
25
  builder.grammar
24
26
  end
25
-
26
27
  let(:sample_tokens) do
27
28
  build_token_sequence(%w[a b c], sample_grammar)
28
29
  end
29
-
30
30
  let(:sample_result) do
31
31
  parser = Parser::GFGEarleyParser.new(sample_grammar)
32
32
  parser.parse(sample_tokens)
33
33
  end
34
34
 
35
-
36
- subject do
37
- ParseTreeFactory.new(sample_result)
38
- end
39
-
40
35
  # Emit a text representation of the current path.
41
36
  def path_to_s
42
- text_parts = subject.curr_path.map do |path_element|
37
+ text_parts = a_factory.curr_path.map do |path_element|
43
38
  path_element.to_string(0)
44
39
  end
45
40
  text_parts.join('/')
@@ -47,19 +42,19 @@ module Rley # Open this namespace to avoid module qualifier prefixes
47
42
 
48
43
 
49
44
  context 'Initialization:' do
50
- it 'should be created with a GFGParsing' do
51
- expect { ParseTreeFactory.new(sample_result) }.not_to raise_error
45
+ it 'is created with a GFGParsing' do
46
+ expect { described_class.new(sample_result) }.not_to raise_error
52
47
  end
53
48
 
54
- it 'should know the parse result' do
55
- expect(subject.parsing).to eq(sample_result)
49
+ it 'knows the parse result' do
50
+ expect(a_factory.parsing).to eq(sample_result)
56
51
  end
57
52
  end
58
53
 
59
54
  context 'Parse tree construction' do
60
- it 'should build a parse tree' do
61
- forest = subject.create
62
- expect(forest).to be_kind_of(PTree::ParseTree)
55
+ it 'builds a parse tree' do
56
+ forest = a_factory.create
57
+ expect(forest).to be_a(PTree::ParseTree)
63
58
  end
64
59
  end # context
65
60
  end # describe
@@ -19,11 +19,13 @@ module Rley # Open this namespace to avoid module qualifier prefixes
19
19
  builder.grammar
20
20
  end
21
21
 
22
+ # Default instantiation rule
23
+ subject(:ptree_visitor) { described_class.new(grm_abc_ptree1) }
24
+
22
25
  let(:a_) { grammar_abc.name2symbol['a'] }
23
26
  let(:b_) { grammar_abc.name2symbol['b'] }
24
27
  let(:c_) { grammar_abc.name2symbol['c'] }
25
28
 
26
-
27
29
  # Helper method that mimicks the output of a tokenizer
28
30
  # for the language specified by grammar_abc
29
31
  let(:grm_abc_tokens1) do
@@ -51,22 +53,17 @@ module Rley # Open this namespace to avoid module qualifier prefixes
51
53
  ptree
52
54
  end
53
55
 
54
-
55
- # Default instantiation rule
56
- subject { ParseTreeVisitor.new(grm_abc_ptree1) }
57
-
58
-
59
56
  context 'Standard creation & initialization:' do
60
- it 'should be initialized with a parse tree argument' do
61
- expect { ParseTreeVisitor.new(grm_abc_ptree1) }.not_to raise_error
57
+ it 'is initialized with a parse tree argument' do
58
+ expect { described_class.new(grm_abc_ptree1) }.not_to raise_error
62
59
  end
63
60
 
64
- it 'should know the parse tree to visit' do
65
- expect(subject.ptree).to eq(grm_abc_ptree1)
61
+ it 'knows the parse tree to visit' do
62
+ expect(ptree_visitor.ptree).to eq(grm_abc_ptree1)
66
63
  end
67
64
 
68
- it "shouldn't have subscribers at start" do
69
- expect(subject.subscribers).to be_empty
65
+ it "doesn't have subscribers at start" do
66
+ expect(ptree_visitor.subscribers).to be_empty
70
67
  end
71
68
  end # context
72
69
 
@@ -75,32 +72,32 @@ module Rley # Open this namespace to avoid module qualifier prefixes
75
72
  let(:listener1) { double('fake-subscriber1') }
76
73
  let(:listener2) { double('fake-subscriber2') }
77
74
 
78
- it 'should allow subscriptions' do
79
- subject.subscribe(listener1)
80
- expect(subject.subscribers.size).to eq(1)
81
- expect(subject.subscribers).to eq([listener1])
75
+ it 'allows subscriptions' do
76
+ ptree_visitor.subscribe(listener1)
77
+ expect(ptree_visitor.subscribers.size).to eq(1)
78
+ expect(ptree_visitor.subscribers).to eq([listener1])
82
79
 
83
- subject.subscribe(listener2)
84
- expect(subject.subscribers.size).to eq(2)
85
- expect(subject.subscribers).to eq([listener1, listener2])
80
+ ptree_visitor.subscribe(listener2)
81
+ expect(ptree_visitor.subscribers.size).to eq(2)
82
+ expect(ptree_visitor.subscribers).to eq([listener1, listener2])
86
83
  end
87
84
 
88
- it 'should allow un-subcriptions' do
89
- subject.subscribe(listener1)
90
- subject.subscribe(listener2)
91
- subject.unsubscribe(listener2)
92
- expect(subject.subscribers.size).to eq(1)
93
- expect(subject.subscribers).to eq([listener1])
94
- subject.unsubscribe(listener1)
95
- expect(subject.subscribers).to be_empty
85
+ it 'allows un-subcriptions' do
86
+ ptree_visitor.subscribe(listener1)
87
+ ptree_visitor.subscribe(listener2)
88
+ ptree_visitor.unsubscribe(listener2)
89
+ expect(ptree_visitor.subscribers.size).to eq(1)
90
+ expect(ptree_visitor.subscribers).to eq([listener1])
91
+ ptree_visitor.unsubscribe(listener1)
92
+ expect(ptree_visitor.subscribers).to be_empty
96
93
  end
97
94
  end # context
98
95
 
99
96
 
100
97
  context 'Notifying visit events:' do
101
98
  # Default instantiation rule
102
- subject do
103
- instance = ParseTreeVisitor.new(grm_abc_ptree1)
99
+ subject(:ptree_visitor) do
100
+ instance = described_class.new(grm_abc_ptree1)
104
101
  instance.subscribe(listener1)
105
102
  instance
106
103
  end
@@ -119,19 +116,19 @@ module Rley # Open this namespace to avoid module qualifier prefixes
119
116
  # Sample terminal node
120
117
  let(:term_node) { nterm_node.subnodes[0] }
121
118
 
122
- it 'should react to the start_visit_ptree message' do
119
+ it 'reacts to the start_visit_ptree message' do
123
120
  # Notify subscribers when start the visit of the ptree
124
121
  expect(listener1).to receive(:before_ptree).with(grm_abc_ptree1)
125
- subject.start_visit_ptree(grm_abc_ptree1)
122
+ ptree_visitor.start_visit_ptree(grm_abc_ptree1)
126
123
  end
127
124
 
128
- it 'should react to the start_visit_nonterminal message' do
125
+ it 'reacts to the start_visit_nonterminal message' do
129
126
  # Notify subscribers when start the visit of a non-terminal node
130
127
  expect(listener1).to receive(:before_non_terminal).with(nterm_node)
131
- subject.visit_nonterminal(nterm_node)
128
+ ptree_visitor.visit_nonterminal(nterm_node)
132
129
  end
133
130
 
134
- it 'should react to the visit_children message' do
131
+ it 'reacts to the visit_children message' do
135
132
  # Notify subscribers when start the visit of children nodes
136
133
  children = nterm_node.subnodes
137
134
  args = [nterm_node, children]
@@ -139,30 +136,30 @@ module Rley # Open this namespace to avoid module qualifier prefixes
139
136
  expect(listener1).to receive(:before_terminal).with(children[0])
140
137
  expect(listener1).to receive(:after_terminal).with(children[0])
141
138
  expect(listener1).to receive(:after_subnodes).with(nterm_node, children)
142
- subject.send(:traverse_subnodes, nterm_node)
139
+ ptree_visitor.send(:traverse_subnodes, nterm_node)
143
140
  end
144
141
 
145
- it 'should react to the end_visit_nonterminal message' do
142
+ it 'reacts to the end_visit_nonterminal message' do
146
143
  # Notify subscribers when ending the visit of a non-terminal node
147
144
  expect(listener1).to receive(:after_non_terminal).with(nterm_node)
148
- subject.end_visit_nonterminal(nterm_node)
145
+ ptree_visitor.end_visit_nonterminal(nterm_node)
149
146
  end
150
147
 
151
- it 'should react to the visit_terminal message' do
148
+ it 'reacts to the visit_terminal message' do
152
149
  # Notify subscribers when start & ending the visit of a terminal node
153
150
  expect(listener1).to receive(:before_terminal).with(term_node)
154
151
  expect(listener1).to receive(:after_terminal).with(term_node)
155
- subject.visit_terminal(term_node)
152
+ ptree_visitor.visit_terminal(term_node)
156
153
  end
157
154
 
158
- it 'should react to the end_visit_ptree message' do
155
+ it 'reacts to the end_visit_ptree message' do
159
156
  # Notify subscribers when ending the visit of the ptree
160
157
  expect(listener1).to receive(:after_ptree).with(grm_abc_ptree1)
161
- subject.end_visit_ptree(grm_abc_ptree1)
158
+ ptree_visitor.end_visit_ptree(grm_abc_ptree1)
162
159
  end
163
160
 
164
161
  # rubocop: disable Naming/VariableNumber
165
- it 'should begin the visit when requested' do
162
+ it 'begins the visit when requested' do
166
163
  # Reminder: parse tree structure is
167
164
  # S[0,5]
168
165
  # +- A[0,5]
@@ -212,10 +209,10 @@ module Rley # Open this namespace to avoid module qualifier prefixes
212
209
  end
213
210
 
214
211
  # Here we go...
215
- subject.start
212
+ ptree_visitor.start
216
213
  end
217
214
 
218
- it 'should also visit in pre-order' do
215
+ it 'also visits in pre-order' do
219
216
  # Reminder: parse tree structure is
220
217
  # S[0,5]
221
218
  # +- A[0,5]
@@ -228,7 +225,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
228
225
  # +- c[4,5]
229
226
  root = grm_abc_ptree1.root
230
227
  # Here we defeat encapsulation for the good cause
231
- subject.instance_variable_set(:@traversal, :pre_order)
228
+ ptree_visitor.instance_variable_set(:@traversal, :pre_order)
232
229
 
233
230
  children = root.subnodes
234
231
  big_a_1 = children[0]
@@ -270,7 +267,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
270
267
  end
271
268
 
272
269
  # Here we go...
273
- subject.start
270
+ ptree_visitor.start
274
271
  end
275
272
  # rubocop: enable Naming/VariableNumber
276
273
  end # context
@@ -61,7 +61,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
61
61
 
62
62
  let(:input) { 'if false then if true then 1 else 2' }
63
63
 
64
- context 'Ambiguous parse: ' do
64
+ context 'Ambiguous parse:' do
65
65
  # Factory method. Creates a grammar builder for a simple grammar.
66
66
  def grammar_if_else_amb
67
67
  builder = Rley::RGN::GrammarBuilder.new do
@@ -81,13 +81,13 @@ module Rley # Open this namespace to avoid module qualifier prefixes
81
81
  builder.grammar
82
82
  end
83
83
 
84
- subject { GFGEarleyParser.new(grammar_if_else_amb) }
84
+ subject(:a_parser) { described_class.new(grammar_if_else_amb) }
85
85
 
86
- it 'should parse a valid simple input' do
86
+ it 'parses a valid simple input' do
87
87
  tokens = tokenizer(input)
88
- parse_result = subject.parse(tokens)
89
- expect(parse_result.success?).to eq(true)
90
- expect(parse_result.ambiguous?).to eq(true)
88
+ parse_result = a_parser.parse(tokens)
89
+ expect(parse_result.success?).to be(true)
90
+ expect(parse_result.ambiguous?).to be(true)
91
91
  ######################
92
92
  # Expectation chart[0]:
93
93
  expected = [
@@ -280,7 +280,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
280
280
  end
281
281
  end # context
282
282
 
283
- context 'Disambiguated parse: ' do
283
+ context 'Disambiguated parse:' do
284
284
  def match_else_with_if(grammar)
285
285
  # Brittle code
286
286
  prod = grammar.rules[2]
@@ -310,13 +310,13 @@ module Rley # Open this namespace to avoid module qualifier prefixes
310
310
  builder.grammar
311
311
  end
312
312
 
313
- subject { GFGEarleyParser.new(grammar_if_else) }
313
+ subject(:a_parser) { described_class.new(grammar_if_else) }
314
314
 
315
- it 'should cope with dangling else problem' do
315
+ it 'copes with dangling else problem' do
316
316
  tokens = tokenizer(input)
317
- parse_result = subject.parse(tokens)
318
- expect(parse_result.success?).to eq(true)
319
- expect(parse_result.ambiguous?).to eq(true)
317
+ parse_result = a_parser.parse(tokens)
318
+ expect(parse_result.success?).to be(true)
319
+ expect(parse_result.ambiguous?).to be(true)
320
320
  ######################
321
321
  # Expectation chart[0]:
322
322
  expected = [