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
@@ -40,4 +40,4 @@ module Rley # Open this namespace to avoid module qualifier prefixes
40
40
  end # module
41
41
  end # module
42
42
 
43
- # End of file
43
+ # End of file
@@ -6,11 +6,11 @@ require_relative '../../../lib/rley/gfg/vertex'
6
6
  module Rley # Open this namespace to avoid module qualifier prefixes
7
7
  module GFG # Open this namespace to avoid module qualifier prefixes
8
8
  describe Vertex do
9
- subject { Vertex.new() }
9
+ subject { Vertex.new }
10
10
 
11
11
  context 'Initialization:' do
12
12
  it 'should be created without argument' do
13
- expect { Vertex.new() }.not_to raise_error
13
+ expect { Vertex.new }.not_to raise_error
14
14
  end
15
15
 
16
16
  it "shouldn't have edges at start" do
@@ -50,4 +50,4 @@ module Rley # Open this namespace to avoid module qualifier prefixes
50
50
  end # module
51
51
  end # module
52
52
 
53
- # End of file
53
+ # End of file
@@ -1,238 +1,239 @@
1
- require_relative '../spec_helper'
2
-
3
- require_relative './support/grammar_helper'
4
- require_relative './support/grammar_sppf_helper'
5
- require_relative '../../lib/rley/parser/token'
6
- require_relative '../../lib/rley/parser/gfg_earley_parser'
7
- require_relative '../../lib/rley/sppf/non_terminal_node'
8
- require_relative '../../lib/rley/sppf/parse_forest'
9
-
10
- # Load the class under test
11
- require_relative '../../lib/rley/parse_forest_visitor'
12
-
13
- module Rley # Open this namespace to avoid module qualifier prefixes
14
- describe ParseForestVisitor do
15
- include GrammarSPPFHelper # Mix-in module with builder for grammar sppf
16
- include GrammarHelper # Mix-in with token factory method
17
-
18
- # Assumption the aParseEntry corresponds to an end GFG node
19
- def create_non_terminal_node(aParseEntry, aRange)
20
- a_vertex = aParseEntry.vertex
21
- return Rley::SPPF::NonTerminalNode.new(a_vertex.non_terminal, aRange)
22
- end
23
-
24
- let(:grammar_sppf) do
25
- builder = grammar_sppf_builder
26
- builder.grammar
27
- end
28
-
29
- let(:sample_tokens) do
30
- build_token_sequence(%w(a b b b), grammar_sppf)
31
- end
32
-
33
- # A forest with just a root node
34
- let(:rooted_forest) do
35
- parser = Parser::GFGEarleyParser.new(grammar_sppf)
36
- parse_result = parser.parse(sample_tokens)
37
- full_range = { low: 0, high: parse_result.chart.last_index }
38
- root_node = create_non_terminal_node(parse_result.accepting_entry, full_range)
39
- Rley::SPPF::ParseForest.new(root_node)
40
- end
41
-
42
- =begin
43
- # Factory method that builds a sample parse forest.
44
- # Generated forest has the following structure:
45
- # S[0,5]
46
- # +- A[0,5]
47
- # +- a[0,0]
48
- # +- A[1,4]
49
- # | +- a[1,1]
50
- # | +- A[2,3]
51
- # | | +- b[2,3]
52
- # | +- c[3,4]
53
- # +- c[4,5]
54
- # Capital letters represent non-terminal nodes
55
- let(:grm_abc_pforest1) do
56
- parser = Parser::EarleyParser.new(grammar_abc)
57
- parse_result = parser.parse(grm_abc_tokens1)
58
- parse_result.parse_forest
59
- end
60
- =end
61
-
62
- # Default instantiation rule
63
- subject { ParseForestVisitor.new(rooted_forest) }
64
-
65
-
66
- context 'Standard creation & initialization:' do
67
- it 'should be initialized with a parse forest argument' do
68
- expect { ParseForestVisitor.new(rooted_forest) }.not_to raise_error
69
- end
70
-
71
- it 'should know the parse forest to visit' do
72
- expect(subject.pforest).to eq(rooted_forest)
73
- end
74
-
75
- it "shouldn't have subscribers at start" do
76
- expect(subject.subscribers).to be_empty
77
- end
78
- end # context
79
-
80
-
81
- context 'Subscribing:' do
82
- let(:listener1) { double('fake-subscriber1') }
83
- let(:listener2) { double('fake-subscriber2') }
84
-
85
- it 'should allow subscriptions' do
86
- subject.subscribe(listener1)
87
- expect(subject.subscribers.size).to eq(1)
88
- expect(subject.subscribers).to eq([listener1])
89
-
90
- subject.subscribe(listener2)
91
- expect(subject.subscribers.size).to eq(2)
92
- expect(subject.subscribers).to eq([listener1, listener2])
93
- end
94
-
95
- it 'should allow un-subcriptions' do
96
- subject.subscribe(listener1)
97
- subject.subscribe(listener2)
98
- subject.unsubscribe(listener2)
99
- expect(subject.subscribers.size).to eq(1)
100
- expect(subject.subscribers).to eq([listener1])
101
- subject.unsubscribe(listener1)
102
- expect(subject.subscribers).to be_empty
103
- end
104
- end # context
105
-
106
-
107
- context 'Notifying visit events:' do
108
- # Use doubles/mocks to simulate subscribers
109
- let(:listener1) { double('fake-subscriber1') }
110
- let(:listener2) { double('fake-subscriber2') }
111
-
112
- it 'should react to the start_visit_pforest message' do
113
- subject.subscribe(listener1)
114
-
115
- # Notify subscribers when start the visit of the pforest
116
- expect(listener1).to receive(:before_pforest).with(rooted_forest)
117
- subject.start_visit_pforest(rooted_forest)
118
- end
119
- =begin
120
- # Default instantiation rule
121
- subject do
122
- instance = ParseForestVisitor.new(grm_abc_pforest1)
123
- instance.subscribe(listener1)
124
- instance
125
- end
126
-
127
-
128
-
129
- # Sample non-terminal node
130
- let(:nterm_node) do
131
- first_big_a = grm_abc_pforest1.root.children[0]
132
- second_big_a = first_big_a.children[1]
133
- second_big_a.children[1]
134
- end
135
-
136
- # Sample terminal node
137
- let(:term_node) { nterm_node.children[0] }
138
-
139
- it 'should react to the start_visit_pforest message' do
140
- # Notify subscribers when start the visit of the pforest
141
- expect(listener1).to receive(:before_pforest).with(grm_abc_pforest1)
142
- subject.start_visit_pforest(grm_abc_pforest1)
143
- end
144
-
145
- it 'should react to the start_visit_nonterminal message' do
146
- # Notify subscribers when start the visit of a non-terminal node
147
- expect(listener1).to receive(:before_non_terminal).with(nterm_node)
148
- subject.visit_nonterminal(nterm_node)
149
- end
150
-
151
- it 'should react to the visit_children message' do
152
- # Notify subscribers when start the visit of children nodes
153
- children = nterm_node.children
154
- args = [nterm_node, children]
155
- expect(listener1).to receive(:before_children).with(*args)
156
- expect(listener1).to receive(:before_terminal).with(children[0])
157
- expect(listener1).to receive(:after_terminal).with(children[0])
158
- expect(listener1).to receive(:after_children).with(nterm_node, children)
159
- subject.send(:traverse_children, nterm_node)
160
- end
161
-
162
- it 'should react to the end_visit_nonterminal message' do
163
- # Notify subscribers when ending the visit of a non-terminal node
164
- expect(listener1).to receive(:after_non_terminal).with(nterm_node)
165
- subject.end_visit_nonterminal(nterm_node)
166
- end
167
-
168
- it 'should react to the visit_terminal message' do
169
- # Notify subscribers when start & ending the visit of a terminal node
170
- expect(listener1).to receive(:before_terminal).with(term_node)
171
- expect(listener1).to receive(:after_terminal).with(term_node)
172
- subject.visit_terminal(term_node)
173
- end
174
-
175
- it 'should react to the end_visit_pforest message' do
176
- # Notify subscribers when ending the visit of the pforest
177
- expect(listener1).to receive(:after_pforest).with(grm_abc_pforest1)
178
- subject.end_visit_pforest(grm_abc_pforest1)
179
- end
180
-
181
- it 'should begin the visit when requested' do
182
- # Reminder: parse forest structure is
183
- # S[0,5]
184
- # +- A[0,5]
185
- # +- a[0,0]
186
- # +- A[1,4]
187
- # | +- a[1,1]
188
- # | +- A[2,3]
189
- # | | +- b[2,3]
190
- # | +- c[3,4]
191
- # +- c[4,5]
192
- root = grm_abc_pforest1.root
193
- children = root.children
194
- big_a_1 = children[0]
195
- big_a_1_children = big_a_1.children
196
- big_a_2 = big_a_1_children[1]
197
- big_a_2_children = big_a_2.children
198
- big_a_3 = big_a_2_children[1]
199
- big_a_3_children = big_a_3.children
200
- expectations = [
201
- [:before_pforest, [grm_abc_pforest1]],
202
- [:before_non_terminal, [root]],
203
- [:before_children, [root, children]],
204
- [:before_non_terminal, [big_a_1]],
205
- [:before_children, [big_a_1, big_a_1_children]],
206
- [:before_terminal, [big_a_1_children[0]]],
207
- [:after_terminal, [big_a_1_children[0]]],
208
- [:before_non_terminal, [big_a_2]],
209
- [:before_children, [big_a_2, big_a_2_children]],
210
- [:before_terminal, [big_a_2_children[0]]],
211
- [:after_terminal, [big_a_2_children[0]]],
212
- [:before_non_terminal, [big_a_3]],
213
- [:before_children, [big_a_3, big_a_3_children]],
214
- [:before_terminal, [big_a_3_children[0]]],
215
- [:after_terminal, [big_a_3_children[0]]],
216
- [:after_children, [big_a_3, big_a_3_children]],
217
- [:before_terminal, [big_a_2_children[2]]],
218
- [:after_terminal, [big_a_2_children[2]]],
219
- [:after_children, [big_a_2, big_a_2_children]],
220
- [:before_terminal, [big_a_1_children[2]]],
221
- [:after_terminal, [big_a_1_children[2]]],
222
- [:after_children, [big_a_1, big_a_1_children]],
223
- [:after_children, [root, children]],
224
- [:after_pforest, [grm_abc_pforest1]]
225
- ]
226
- expectations.each do |(msg, args)|
227
- expect(listener1).to receive(msg).with(*args).ordered
228
- end
229
-
230
- # Here we go...
231
- subject.start
232
- end
233
- =end
234
- end # context
235
- end # describe
236
- end # module
237
-
238
- # End of file
1
+ require_relative '../spec_helper'
2
+
3
+ require_relative './support/grammar_helper'
4
+ require_relative './support/grammar_sppf_helper'
5
+ require_relative '../../lib/rley/parser/token'
6
+ require_relative '../../lib/rley/parser/gfg_earley_parser'
7
+ require_relative '../../lib/rley/sppf/non_terminal_node'
8
+ require_relative '../../lib/rley/sppf/parse_forest'
9
+
10
+ # Load the class under test
11
+ require_relative '../../lib/rley/parse_forest_visitor'
12
+
13
+ module Rley # Open this namespace to avoid module qualifier prefixes
14
+ describe ParseForestVisitor do
15
+ include GrammarSPPFHelper # Mix-in module with builder for grammar sppf
16
+ include GrammarHelper # Mix-in with token factory method
17
+
18
+ # Assumption the aParseEntry corresponds to an end GFG node
19
+ def create_non_terminal_node(aParseEntry, aRange)
20
+ a_vertex = aParseEntry.vertex
21
+ return Rley::SPPF::NonTerminalNode.new(a_vertex.non_terminal, aRange)
22
+ end
23
+
24
+ let(:grammar_sppf) do
25
+ builder = grammar_sppf_builder
26
+ builder.grammar
27
+ end
28
+
29
+ let(:sample_tokens) do
30
+ build_token_sequence(%w(a b b b), grammar_sppf)
31
+ end
32
+
33
+ # A forest with just a root node
34
+ let(:rooted_forest) do
35
+ parser = Parser::GFGEarleyParser.new(grammar_sppf)
36
+ parse_result = parser.parse(sample_tokens)
37
+ accepting_entry = parse_result.accepting_entry
38
+ full_range = { low: 0, high: parse_result.chart.last_index }
39
+ root_node = create_non_terminal_node(accepting_entry, full_range)
40
+ Rley::SPPF::ParseForest.new(root_node)
41
+ end
42
+
43
+ =begin
44
+ # Factory method that builds a sample parse forest.
45
+ # Generated forest has the following structure:
46
+ # S[0,5]
47
+ # +- A[0,5]
48
+ # +- a[0,0]
49
+ # +- A[1,4]
50
+ # | +- a[1,1]
51
+ # | +- A[2,3]
52
+ # | | +- b[2,3]
53
+ # | +- c[3,4]
54
+ # +- c[4,5]
55
+ # Capital letters represent non-terminal nodes
56
+ let(:grm_abc_pforest1) do
57
+ parser = Parser::EarleyParser.new(grammar_abc)
58
+ parse_result = parser.parse(grm_abc_tokens1)
59
+ parse_result.parse_forest
60
+ end
61
+ =end
62
+
63
+ # Default instantiation rule
64
+ subject { ParseForestVisitor.new(rooted_forest) }
65
+
66
+
67
+ context 'Standard creation & initialization:' do
68
+ it 'should be initialized with a parse forest argument' do
69
+ expect { ParseForestVisitor.new(rooted_forest) }.not_to raise_error
70
+ end
71
+
72
+ it 'should know the parse forest to visit' do
73
+ expect(subject.pforest).to eq(rooted_forest)
74
+ end
75
+
76
+ it "shouldn't have subscribers at start" do
77
+ expect(subject.subscribers).to be_empty
78
+ end
79
+ end # context
80
+
81
+
82
+ context 'Subscribing:' do
83
+ let(:listener1) { double('fake-subscriber1') }
84
+ let(:listener2) { double('fake-subscriber2') }
85
+
86
+ it 'should allow subscriptions' do
87
+ subject.subscribe(listener1)
88
+ expect(subject.subscribers.size).to eq(1)
89
+ expect(subject.subscribers).to eq([listener1])
90
+
91
+ subject.subscribe(listener2)
92
+ expect(subject.subscribers.size).to eq(2)
93
+ expect(subject.subscribers).to eq([listener1, listener2])
94
+ end
95
+
96
+ it 'should allow un-subcriptions' do
97
+ subject.subscribe(listener1)
98
+ subject.subscribe(listener2)
99
+ subject.unsubscribe(listener2)
100
+ expect(subject.subscribers.size).to eq(1)
101
+ expect(subject.subscribers).to eq([listener1])
102
+ subject.unsubscribe(listener1)
103
+ expect(subject.subscribers).to be_empty
104
+ end
105
+ end # context
106
+
107
+
108
+ context 'Notifying visit events:' do
109
+ # Use doubles/mocks to simulate subscribers
110
+ let(:listener1) { double('fake-subscriber1') }
111
+ let(:listener2) { double('fake-subscriber2') }
112
+
113
+ it 'should react to the start_visit_pforest message' do
114
+ subject.subscribe(listener1)
115
+
116
+ # Notify subscribers when start the visit of the pforest
117
+ expect(listener1).to receive(:before_pforest).with(rooted_forest)
118
+ subject.start_visit_pforest(rooted_forest)
119
+ end
120
+ =begin
121
+ # Default instantiation rule
122
+ subject do
123
+ instance = ParseForestVisitor.new(grm_abc_pforest1)
124
+ instance.subscribe(listener1)
125
+ instance
126
+ end
127
+
128
+
129
+
130
+ # Sample non-terminal node
131
+ let(:nterm_node) do
132
+ first_big_a = grm_abc_pforest1.root.children[0]
133
+ second_big_a = first_big_a.children[1]
134
+ second_big_a.children[1]
135
+ end
136
+
137
+ # Sample terminal node
138
+ let(:term_node) { nterm_node.children[0] }
139
+
140
+ it 'should react to the start_visit_pforest message' do
141
+ # Notify subscribers when start the visit of the pforest
142
+ expect(listener1).to receive(:before_pforest).with(grm_abc_pforest1)
143
+ subject.start_visit_pforest(grm_abc_pforest1)
144
+ end
145
+
146
+ it 'should react to the start_visit_nonterminal message' do
147
+ # Notify subscribers when start the visit of a non-terminal node
148
+ expect(listener1).to receive(:before_non_terminal).with(nterm_node)
149
+ subject.visit_nonterminal(nterm_node)
150
+ end
151
+
152
+ it 'should react to the visit_children message' do
153
+ # Notify subscribers when start the visit of children nodes
154
+ children = nterm_node.children
155
+ args = [nterm_node, children]
156
+ expect(listener1).to receive(:before_children).with(*args)
157
+ expect(listener1).to receive(:before_terminal).with(children[0])
158
+ expect(listener1).to receive(:after_terminal).with(children[0])
159
+ expect(listener1).to receive(:after_children).with(nterm_node, children)
160
+ subject.send(:traverse_children, nterm_node)
161
+ end
162
+
163
+ it 'should react to the end_visit_nonterminal message' do
164
+ # Notify subscribers when ending the visit of a non-terminal node
165
+ expect(listener1).to receive(:after_non_terminal).with(nterm_node)
166
+ subject.end_visit_nonterminal(nterm_node)
167
+ end
168
+
169
+ it 'should react to the visit_terminal message' do
170
+ # Notify subscribers when start & ending the visit of a terminal node
171
+ expect(listener1).to receive(:before_terminal).with(term_node)
172
+ expect(listener1).to receive(:after_terminal).with(term_node)
173
+ subject.visit_terminal(term_node)
174
+ end
175
+
176
+ it 'should react to the end_visit_pforest message' do
177
+ # Notify subscribers when ending the visit of the pforest
178
+ expect(listener1).to receive(:after_pforest).with(grm_abc_pforest1)
179
+ subject.end_visit_pforest(grm_abc_pforest1)
180
+ end
181
+
182
+ it 'should begin the visit when requested' do
183
+ # Reminder: parse forest structure is
184
+ # S[0,5]
185
+ # +- A[0,5]
186
+ # +- a[0,0]
187
+ # +- A[1,4]
188
+ # | +- a[1,1]
189
+ # | +- A[2,3]
190
+ # | | +- b[2,3]
191
+ # | +- c[3,4]
192
+ # +- c[4,5]
193
+ root = grm_abc_pforest1.root
194
+ children = root.children
195
+ big_a_1 = children[0]
196
+ big_a_1_children = big_a_1.children
197
+ big_a_2 = big_a_1_children[1]
198
+ big_a_2_children = big_a_2.children
199
+ big_a_3 = big_a_2_children[1]
200
+ big_a_3_children = big_a_3.children
201
+ expectations = [
202
+ [:before_pforest, [grm_abc_pforest1]],
203
+ [:before_non_terminal, [root]],
204
+ [:before_children, [root, children]],
205
+ [:before_non_terminal, [big_a_1]],
206
+ [:before_children, [big_a_1, big_a_1_children]],
207
+ [:before_terminal, [big_a_1_children[0]]],
208
+ [:after_terminal, [big_a_1_children[0]]],
209
+ [:before_non_terminal, [big_a_2]],
210
+ [:before_children, [big_a_2, big_a_2_children]],
211
+ [:before_terminal, [big_a_2_children[0]]],
212
+ [:after_terminal, [big_a_2_children[0]]],
213
+ [:before_non_terminal, [big_a_3]],
214
+ [:before_children, [big_a_3, big_a_3_children]],
215
+ [:before_terminal, [big_a_3_children[0]]],
216
+ [:after_terminal, [big_a_3_children[0]]],
217
+ [:after_children, [big_a_3, big_a_3_children]],
218
+ [:before_terminal, [big_a_2_children[2]]],
219
+ [:after_terminal, [big_a_2_children[2]]],
220
+ [:after_children, [big_a_2, big_a_2_children]],
221
+ [:before_terminal, [big_a_1_children[2]]],
222
+ [:after_terminal, [big_a_1_children[2]]],
223
+ [:after_children, [big_a_1, big_a_1_children]],
224
+ [:after_children, [root, children]],
225
+ [:after_pforest, [grm_abc_pforest1]]
226
+ ]
227
+ expectations.each do |(msg, args)|
228
+ expect(listener1).to receive(msg).with(*args).ordered
229
+ end
230
+
231
+ # Here we go...
232
+ subject.start
233
+ end
234
+ =end
235
+ end # context
236
+ end # describe
237
+ end # module
238
+
239
+ # End of file