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
@@ -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