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
@@ -11,37 +11,37 @@ require_relative '../../lib/rley/engine'
11
11
 
12
12
  module Rley # Open this namespace to avoid module qualifier prefixes
13
13
  describe Engine do
14
- subject { Engine.new }
14
+ subject(:an_engine) { described_class.new }
15
15
 
16
16
  context 'Creation and initialization:' do
17
- it 'could be created without argument' do
18
- expect { Engine.new }.not_to raise_error
17
+ it 'is created without argument' do
18
+ expect { described_class.new }.not_to raise_error
19
19
  end
20
20
 
21
- it 'could be created with block argument' do
21
+ it 'is created with block argument' do
22
22
  expect do
23
- Engine.new do |config|
23
+ described_class.new do |config|
24
24
  config.parse_repr = :raw
25
25
  end
26
26
  end.not_to raise_error
27
27
  end
28
28
 
29
- it "shouldn't have a link to a grammar yet" do
30
- expect(subject.grammar).to be_nil
29
+ it "doesn't have a link to a grammar yet" do
30
+ expect(an_engine.grammar).to be_nil
31
31
  end
32
32
  end # context
33
33
 
34
34
  context 'Grammar building:' do
35
- it 'should build grammar' do
36
- subject.build_grammar do
35
+ it 'builds grammar' do
36
+ an_engine.build_grammar do
37
37
  add_terminals('a', 'b', 'c')
38
38
  add_production('S' => 'A')
39
39
  add_production('A' => 'a A c')
40
40
  add_production('A' => 'b')
41
41
  end
42
42
 
43
- expect(subject.grammar).to be_kind_of(Rley::Syntax::Grammar)
44
- expect(subject.grammar.rules.size).to eq(3)
43
+ expect(an_engine.grammar).to be_a(Rley::Syntax::Grammar)
44
+ expect(an_engine.grammar.rules.size).to eq(3)
45
45
  end
46
46
  end # context
47
47
 
@@ -78,34 +78,34 @@ module Rley # Open this namespace to avoid module qualifier prefixes
78
78
  end
79
79
 
80
80
  context 'Parsing:' do
81
- subject do
82
- instance = Engine.new
81
+ subject(:an_engine) do
82
+ instance = described_class.new
83
83
  add_sample_grammar(instance)
84
84
  instance
85
85
  end
86
86
 
87
- it 'should parse a stream of tokens' do
87
+ it 'parses a stream of tokens' do
88
88
  sample_text = 'a a b c c'
89
89
  tokenizer = ABCTokenizer.new(sample_text)
90
- result = subject.parse(tokenizer)
90
+ result = an_engine.parse(tokenizer)
91
91
  expect(result).to be_success
92
92
  end
93
93
  end # context
94
94
 
95
95
  context 'Parse tree manipulation:' do
96
- subject do
97
- instance = Engine.new
98
- add_sample_grammar(instance)
99
- instance
100
- end
101
-
102
96
  let(:sample_tokenizer) do
103
97
  sample_text = 'a a b c c'
104
98
  ABCTokenizer.new(sample_text)
105
99
  end
106
100
 
107
- it 'should build a parse tree even for a nullable production' do
108
- instance = Engine.new
101
+ subject(:an_engine) do
102
+ instance = described_class.new
103
+ add_sample_grammar(instance)
104
+ instance
105
+ end
106
+
107
+ it 'builds a parse tree even for a nullable production' do
108
+ instance = described_class.new
109
109
  instance.build_grammar do
110
110
  add_terminals('a', 'b', 'c')
111
111
  add_production 'S' => 'A BC'
@@ -121,31 +121,31 @@ module Rley # Open this namespace to avoid module qualifier prefixes
121
121
  expect { instance.to_ptree(raw_result) }.not_to raise_error
122
122
  end
123
123
 
124
- it 'should build default parse trees' do
125
- raw_result = subject.parse(sample_tokenizer)
126
- ptree = subject.convert(raw_result)
127
- expect(ptree).to be_kind_of(PTree::ParseTree)
124
+ it 'builds default parse trees' do
125
+ raw_result = an_engine.parse(sample_tokenizer)
126
+ ptree = an_engine.convert(raw_result)
127
+ expect(ptree).to be_a(PTree::ParseTree)
128
128
  end
129
129
 
130
- it 'should build custom parse trees' do
130
+ it 'builds custom parse trees' do
131
131
  # Cheating: we point to default tree builder (CST)
132
- subject.configuration.repr_builder = ParseRep::CSTBuilder
133
- raw_result = subject.parse(sample_tokenizer)
134
- ptree = subject.convert(raw_result)
135
- expect(ptree).to be_kind_of(PTree::ParseTree)
132
+ an_engine.configuration.repr_builder = ParseRep::CSTBuilder
133
+ raw_result = an_engine.parse(sample_tokenizer)
134
+ ptree = an_engine.convert(raw_result)
135
+ expect(ptree).to be_a(PTree::ParseTree)
136
136
  end
137
137
 
138
- it 'should provide a parse visitor' do
139
- raw_result = subject.parse(sample_tokenizer)
140
- ptree = subject.to_ptree(raw_result)
141
- visitor = subject.ptree_visitor(ptree)
142
- expect(visitor).to be_kind_of(ParseTreeVisitor)
138
+ it 'provides a parse visitor' do
139
+ raw_result = an_engine.parse(sample_tokenizer)
140
+ ptree = an_engine.to_ptree(raw_result)
141
+ visitor = an_engine.ptree_visitor(ptree)
142
+ expect(visitor).to be_a(ParseTreeVisitor)
143
143
  end
144
144
  end # context
145
145
 
146
146
  context 'Parse forest manipulation:' do
147
- subject do
148
- instance = Engine.new
147
+ subject(:an_engine) do
148
+ instance = described_class.new
149
149
  add_sample_grammar(instance)
150
150
  instance
151
151
  end
@@ -155,8 +155,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
155
155
  ABCTokenizer.new(sample_text)
156
156
  end
157
157
 
158
- it 'should build a parse forest even for a nullable production' do
159
- instance = Engine.new
158
+ it 'builds a parse forest even for a nullable production' do
159
+ instance = described_class.new
160
160
  instance.build_grammar do
161
161
  add_terminals('a', 'b', 'c')
162
162
  add_production 'S' => 'A BC'
@@ -172,17 +172,17 @@ module Rley # Open this namespace to avoid module qualifier prefixes
172
172
  expect { instance.to_pforest(raw_result) }.not_to raise_error
173
173
  end
174
174
 
175
- it 'should build parse forest' do
176
- raw_result = subject.parse(sample_tokenizer)
177
- pforest = subject.to_pforest(raw_result)
178
- expect(pforest).to be_kind_of(SPPF::ParseForest)
175
+ it 'builds parse forest' do
176
+ raw_result = an_engine.parse(sample_tokenizer)
177
+ pforest = an_engine.to_pforest(raw_result)
178
+ expect(pforest).to be_a(SPPF::ParseForest)
179
179
  end
180
180
 
181
- it 'should provide a parse visitor' do
182
- raw_result = subject.parse(sample_tokenizer)
183
- ptree = subject.to_pforest(raw_result)
184
- visitor = subject.pforest_visitor(ptree)
185
- expect(visitor).to be_kind_of(ParseForestVisitor)
181
+ it 'provides a parse visitor' do
182
+ raw_result = an_engine.parse(sample_tokenizer)
183
+ ptree = an_engine.to_pforest(raw_result)
184
+ visitor = an_engine.pforest_visitor(ptree)
185
+ expect(visitor).to be_a(ParseForestVisitor)
186
186
  end
187
187
  end # context
188
188
  end # describe
@@ -15,6 +15,8 @@ require_relative '../../../lib/rley/formatter/asciitree'
15
15
  module Rley # Re-open the module to get rid of qualified names
16
16
  module Formatter
17
17
  describe Asciitree do
18
+ subject(:a_formatter) { described_class.new(destination) }
19
+
18
20
  # Factory method. Build a production with the given sequence
19
21
  # of symbols as its rhs.
20
22
  let(:grammar_abc) do
@@ -55,25 +57,23 @@ module Rley # Re-open the module to get rid of qualified names
55
57
  ptree = engine.convert(parse_result)
56
58
  ptree
57
59
  end
58
-
59
60
  let(:destination) { StringIO.new(+'', 'w') }
60
- subject { Asciitree.new(destination) }
61
61
 
62
62
  context 'Standard creation & initialization:' do
63
- it 'should be initialized with an IO argument' do
64
- expect { Asciitree.new(StringIO.new(+'', 'w')) }.not_to raise_error
63
+ it 'is initialized with an IO argument' do
64
+ expect { described_class.new(StringIO.new(+'', 'w')) }.not_to raise_error
65
65
  end
66
66
 
67
- it 'should know its output destination' do
68
- expect(subject.output).to eq(destination)
67
+ it 'knows its output destination' do
68
+ expect(a_formatter.output).to eq(destination)
69
69
  end
70
70
  end # context
71
71
 
72
72
 
73
73
  context 'Rendering:' do
74
- it 'should render a parse tree' do
74
+ it 'renders a parse tree' do
75
75
  visitor = Rley::ParseTreeVisitor.new(grm_abc_ptree1)
76
- subject.render(visitor)
76
+ a_formatter.render(visitor)
77
77
  expectations = <<-SNIPPET
78
78
  S
79
79
  +-- A
@@ -15,6 +15,8 @@ require_relative '../../../lib/rley/formatter/bracket_notation'
15
15
  module Rley # Re-open the module to get rid of qualified names
16
16
  module Formatter
17
17
  describe BracketNotation do
18
+ subject(:a_formatter) { described_class.new(destination) }
19
+
18
20
  # Factory method. Build a production with the given sequence
19
21
  # of symbols as its rhs.
20
22
  let(:grammar_abc) do
@@ -57,36 +59,34 @@ module Rley # Re-open the module to get rid of qualified names
57
59
  end
58
60
 
59
61
  let(:destination) { StringIO.new(+'', 'w') }
60
- subject { BracketNotation.new(destination) }
61
62
 
62
63
  context 'Standard creation & initialization:' do
63
- it 'should be initialized with an IO argument' do
64
+ it 'is initialized with an IO argument' do
64
65
  expect do
65
- BracketNotation.new(StringIO.new(+'', 'w'))
66
+ described_class.new(StringIO.new(+'', 'w'))
66
67
  end.not_to raise_error
67
68
  end
68
69
 
69
- it 'should know its output destination' do
70
- expect(subject.output).to eq(destination)
70
+ it 'knows its output destination' do
71
+ expect(a_formatter.output).to eq(destination)
71
72
  end
72
73
  end # context
73
74
 
74
-
75
75
  context 'Formatting events:' do
76
- it 'should support visit events of a parse tree' do
76
+ it 'supports visit events of a parse tree' do
77
77
  visitor = Rley::ParseTreeVisitor.new(grm_abc_ptree1)
78
- subject.render(visitor)
78
+ a_formatter.render(visitor)
79
79
  expectations = '[S [A [a a][A [a a][A [b b]][c c]][c c]]]'
80
80
  expect(destination.string).to eq(expectations)
81
81
  end
82
82
 
83
- it 'should escape square brackets' do
83
+ it 'escapes square brackets' do
84
84
  f_node = double('fake-node')
85
85
  f_token = double('fake-token')
86
86
  expect(f_node).to receive(:token).and_return(f_token)
87
87
  expect(f_token).to receive(:lexeme).and_return('[][]')
88
88
 
89
- subject.after_terminal(f_node)
89
+ a_formatter.after_terminal(f_node)
90
90
  expectations = '\[\]\[\]]'
91
91
  expect(destination.string).to eq(expectations)
92
92
  end
@@ -79,24 +79,24 @@ module Rley # Re-open the module to get rid of qualified names
79
79
  let(:destination) { StringIO.new(+'', 'w') }
80
80
 
81
81
  context 'Standard creation & initialization:' do
82
- it 'should be initialized with an IO argument' do
83
- expect { Debug.new(StringIO.new(+'', 'w')) }.not_to raise_error
82
+ it 'is initialized with an IO argument' do
83
+ expect { described_class.new(StringIO.new(+'', 'w')) }.not_to raise_error
84
84
  end
85
85
 
86
- it 'should know its output destination' do
87
- instance = Debug.new(destination)
86
+ it 'knows its output destination' do
87
+ instance = described_class.new(destination)
88
88
  expect(instance.output).to eq(destination)
89
89
  end
90
90
 
91
- it 'should have a zero indentation' do
92
- instance = Debug.new(destination)
91
+ it 'has a zero indentation' do
92
+ instance = described_class.new(destination)
93
93
  expect(instance.indentation).to be_zero
94
94
  end
95
95
  end # context
96
96
 
97
97
  context 'Formatting events:' do
98
- it 'should support visit events of a parse tree' do
99
- instance = Debug.new(destination)
98
+ it 'supports visit events of a parse tree' do
99
+ instance = described_class.new(destination)
100
100
  expect(instance.output).to eq(destination)
101
101
  visitor = Rley::ParseTreeVisitor.new(grm_abc_ptree1)
102
102
  instance.render(visitor)
@@ -133,8 +133,8 @@ SNIPPET
133
133
  expect(destination.string).to eq(expectations)
134
134
  end
135
135
 
136
- it 'should support visit events of a parse forest' do
137
- instance = Debug.new(destination)
136
+ it 'supports visit events of a parse forest' do
137
+ instance = described_class.new(destination)
138
138
  expect(instance.output).to eq(destination)
139
139
  visitor = Rley::ParseForestVisitor.new(grm_sppf_pforest1)
140
140
  instance.render(visitor)
@@ -54,24 +54,23 @@ module Rley # Re-open the module to get rid of qualified names
54
54
  ptree = engine.convert(parse_result)
55
55
  ptree
56
56
  end
57
-
58
57
  let(:destination) { StringIO.new(+'', 'w') }
59
58
 
60
59
  context 'Standard creation & initialization:' do
61
- it 'should be initialized with an IO argument' do
62
- expect { Json.new(StringIO.new(+'', 'w')) }.not_to raise_error
60
+ it 'is initialized with an IO argument' do
61
+ expect { described_class.new(StringIO.new(+'', 'w')) }.not_to raise_error
63
62
  end
64
63
 
65
- it 'should know its output destination' do
66
- instance = Json.new(destination)
64
+ it 'knows its output destination' do
65
+ instance = described_class.new(destination)
67
66
  expect(instance.output).to eq(destination)
68
67
  end
69
68
  end # context
70
69
 
71
70
 
72
71
  context 'Formatting events:' do
73
- it 'should render a parse tree in JSON' do
74
- instance = Json.new(destination)
72
+ it 'renders a parse tree in JSON' do
73
+ instance = described_class.new(destination)
75
74
  visitor = Rley::ParseTreeVisitor.new(grm_abc_ptree1)
76
75
  instance.render(visitor)
77
76
  expectations = <<-SNIPPET
@@ -21,6 +21,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
21
21
  return Syntax::Production.new(theLHS, theRHSSymbols)
22
22
  end
23
23
 
24
+ subject(:an_edge) { described_class.new(vertex1, vertex2) }
25
+
24
26
  let(:t_a) { Rley::Syntax::Terminal.new('a') }
25
27
  let(:t_b) { Rley::Syntax::Terminal.new('b') }
26
28
  let(:t_c) { Rley::Syntax::Terminal.new('c') }
@@ -28,21 +30,19 @@ module Rley # Open this namespace to avoid module qualifier prefixes
28
30
  let(:nt_b_sequence) { Rley::Syntax::NonTerminal.new('b_sequence') }
29
31
  let(:sample_prod) { build_prod(nt_sentence, t_a, nt_b_sequence, t_c) }
30
32
  let(:sample_item) { Base::DottedItem.new(sample_prod, 1) }
31
-
32
33
  let(:vertex1) { ItemVertex.new(sample_item) }
33
34
  let(:vertex2) { StartVertex.new('to') }
34
- subject { CallEdge.new(vertex1, vertex2) }
35
35
 
36
36
  context 'Initialization:' do
37
- it 'should be created with two vertice arguments' do
38
- expect { CallEdge.new(vertex1, vertex2) }.not_to raise_error
37
+ it 'is created with two vertice arguments' do
38
+ expect { described_class.new(vertex1, vertex2) }.not_to raise_error
39
39
  end
40
40
  end # context
41
41
 
42
42
  context 'Provided services:' do
43
- it 'should know its key' do
43
+ it 'knows its key' do
44
44
  expectation = "CALL_#{sample_prod.object_id}_#{sample_item.position}"
45
- expect(subject.key).to eq(expectation)
45
+ expect(an_edge.key).to eq(expectation)
46
46
  end
47
47
  end # context
48
48
  end # describe
@@ -11,21 +11,22 @@ require_relative '../../../lib/rley/gfg/edge'
11
11
  module Rley # Open this namespace to avoid module qualifier prefixes
12
12
  module GFG # Open this namespace to avoid module qualifier prefixes
13
13
  describe Edge do
14
+ subject(:an_edge) { described_class.new(vertex1, vertex2) }
15
+
14
16
  let(:vertex1) { StartVertex.new('from') }
15
17
  let(:vertex2) { StartVertex.new('to') }
16
- subject { Edge.new(vertex1, vertex2) }
17
18
 
18
19
  context 'Initialization:' do
19
- it 'should be created with two vertice arguments' do
20
- expect { Edge.new(vertex1, vertex2) }.not_to raise_error
20
+ it 'is created with two vertice arguments' do
21
+ expect { described_class.new(vertex1, vertex2) }.not_to raise_error
21
22
  end
22
23
 
23
- it 'should be registered by the predecessor vertex' do
24
- expect(subject).to eq(vertex1.edges.last)
24
+ it 'is registered by the predecessor vertex' do
25
+ expect(an_edge).to eq(vertex1.edges.last)
25
26
  end
26
27
 
27
- it 'should know the successor vertex' do
28
- expect(subject.successor).to eq(vertex2)
28
+ it 'knows the successor vertex' do
29
+ expect(an_edge.successor).to eq(vertex2)
29
30
  end
30
31
  end # context
31
32
  end # describe
@@ -9,24 +9,25 @@ require_relative '../../../lib/rley/gfg/end_vertex'
9
9
  module Rley # Open this namespace to avoid module qualifier prefixes
10
10
  module GFG # Open this namespace to avoid module qualifier prefixes
11
11
  describe EndVertex do
12
+ subject(:a_vertex) { described_class.new(sample_nt) }
13
+
12
14
  let(:sample_nt) { Syntax::NonTerminal.new('NT') }
13
- subject { EndVertex.new(sample_nt) }
14
15
 
15
16
  context 'Initialization:' do
16
- it 'should be created with a non-terminal symbol' do
17
- expect { EndVertex.new(sample_nt) }.not_to raise_error
17
+ it 'is created with a non-terminal symbol' do
18
+ expect { described_class.new(sample_nt) }.not_to raise_error
18
19
  end
19
20
 
20
- it 'should know its label' do
21
+ it 'knows its label' do
21
22
  expect(sample_nt).to receive(:to_s).and_return('NT')
22
- expect(subject.label).to eq('NT.')
23
+ expect(a_vertex.label).to eq('NT.')
23
24
  end
24
25
  end # context
25
26
 
26
27
  context 'Provided services:' do
27
- it 'should provide human-readable representation of itself' do
28
+ it 'provides human-readable representation of itself' do
28
29
  pattern = /^#<Rley::GFG::EndVertex:\d+ label="NT\."/
29
- expect(subject.inspect).to match(pattern)
30
+ expect(a_vertex.inspect).to match(pattern)
30
31
  end
31
32
  end # context
32
33
  end # describe
@@ -10,14 +10,15 @@ require_relative '../../../lib/rley/gfg/epsilon_edge'
10
10
 
11
11
  module Rley # Open this namespace to avoid module qualifier prefixes
12
12
  module GFG # Open this namespace to avoid module qualifier prefixes
13
- describe Edge do
13
+ describe EpsilonEdge do
14
+ subject { described_class.new(vertex1, vertex2) }
15
+
14
16
  let(:vertex1) { StartVertex.new('from') }
15
17
  let(:vertex2) { StartVertex.new('to') }
16
- subject { EpsilonEdge.new(vertex1, vertex2) }
17
18
 
18
19
  context 'Initialization:' do
19
- it 'should be created with two vertice arguments' do
20
- expect { EpsilonEdge.new(vertex1, vertex2) }.not_to raise_error
20
+ it 'is created with two vertice arguments' do
21
+ expect { described_class.new(vertex1, vertex2) }.not_to raise_error
21
22
  end
22
23
  end # context
23
24
  end # describe
@@ -34,6 +34,9 @@ module Rley # Open this namespace to avoid module qualifier prefixes
34
34
  end
35
35
  end
36
36
 
37
+ # Default instantiation rule
38
+ subject(:a_graph) { described_class.new(items_from_grammar) }
39
+
37
40
  # Factory method. Build a production with the given sequence
38
41
  # of symbols as its rhs.
39
42
  let(:grammar_abc) do
@@ -45,52 +48,48 @@ module Rley # Open this namespace to avoid module qualifier prefixes
45
48
  # from the abc grammar
46
49
  let(:items_from_grammar) { build_items_for_grammar(grammar_abc) }
47
50
 
48
- # Default instantiation rule
49
- subject { GrmFlowGraph.new(items_from_grammar) }
50
-
51
-
52
51
  context 'Initialization:' do
53
- it 'should be created with an array of dotted items' do
54
- expect { GrmFlowGraph.new(items_from_grammar) }.not_to raise_error
52
+ it 'is created with an array of dotted items' do
53
+ expect { described_class.new(items_from_grammar) }.not_to raise_error
55
54
  end
56
55
 
57
- it 'should know its main start vertex' do
58
- expect(subject.start_vertex).to eq(subject.vertices.first)
56
+ it 'knows its main start vertex' do
57
+ expect(a_graph.start_vertex).to eq(a_graph.vertices.first)
59
58
  end
60
59
 
61
- it 'should have the correct number of vertices' do
60
+ it 'has the correct number of vertices' do
62
61
  # Number of vertices = count of dotted items +...
63
62
  # ... 2 * count of non-terminals
64
63
  count_vertices = 2 * grammar_abc.non_terminals.size
65
64
  count_vertices += items_from_grammar.size
66
- expect(subject.vertices.size).to eq(count_vertices)
65
+ expect(a_graph.vertices.size).to eq(count_vertices)
67
66
  end
68
67
 
69
- it 'should have for each non-terminal one start and end vertex' do
68
+ it 'has for each non-terminal one start and end vertex' do
70
69
  # Iterate over all non-terminals of grammar...
71
70
  grammar_abc.non_terminals.each do |nterm|
72
71
  # ...to each non-terminal there should be a start vertex
73
- start_vertex = subject.start_vertex_for[nterm]
74
- expect(start_vertex).to be_kind_of(StartVertex)
72
+ start_vertex = a_graph.start_vertex_for[nterm]
73
+ expect(start_vertex).to be_a(StartVertex)
75
74
  expect(start_vertex.label).to eq(".#{nterm}")
76
75
 
77
76
  # ...to each non-terminal there should be an end vertex
78
- end_vertex = subject.end_vertex_for[nterm]
79
- expect(end_vertex).to be_kind_of(EndVertex)
77
+ end_vertex = a_graph.end_vertex_for[nterm]
78
+ expect(end_vertex).to be_a(EndVertex)
80
79
  expect(end_vertex.label).to eq("#{nterm}.")
81
80
  end
82
81
  end
83
82
 
84
- it 'should have one or more entry edges per start vertex' do
85
- subject.start_vertex_for.each_value do |a_start|
83
+ it 'has one or more entry edges per start vertex' do
84
+ a_graph.start_vertex_for.each_value do |a_start|
86
85
  expect(a_start.edges.size >= 1).to be_truthy
87
86
  a_start.edges.each do |edge|
88
- expect(edge.successor.dotted_item.at_start?).to be_truthy
87
+ expect(edge.successor.dotted_item).to be_at_start
89
88
  end
90
89
  end
91
90
  end
92
91
 
93
- it 'should have the correct graph structure' do
92
+ it 'has the correct graph structure' do
94
93
  # We use the abc grammar
95
94
  expected = [
96
95
  '.S --> S => . A',
@@ -108,10 +107,10 @@ module Rley # Open this namespace to avoid module qualifier prefixes
108
107
  'A => b . --> A.'
109
108
  ]
110
109
 
111
- compare_graph_expectations(subject, expected)
110
+ compare_graph_expectations(a_graph, expected)
112
111
  end
113
112
 
114
- it 'should handle empty productions' do
113
+ it 'handles empty productions' do
115
114
  builder = Rley::Syntax::BaseGrammarBuilder.new
116
115
  builder.add_terminals('a')
117
116
  builder.add_production('S' => 'A')
@@ -121,7 +120,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
121
120
  grammar = builder.grammar
122
121
  items = build_items_for_grammar(grammar)
123
122
 
124
- graph = GrmFlowGraph.new(items)
123
+ graph = described_class.new(items)
125
124
  expected = [
126
125
  '.S --> S => . A',
127
126
  '.A --> A => . a',
@@ -137,8 +136,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
137
136
  compare_graph_expectations(graph, expected)
138
137
  end
139
138
 
140
- it 'should have shortcut edges' do
141
- subject.vertices.each do |a_vertex|
139
+ it 'has shortcut edges' do
140
+ a_graph.vertices.each do |a_vertex|
142
141
  next unless a_vertex.kind_of?(ItemVertex)
143
142
 
144
143
  if a_vertex.next_symbol.kind_of?(Syntax::NonTerminal)
@@ -177,9 +176,9 @@ module Rley # Open this namespace to avoid module qualifier prefixes
177
176
  builder.grammar
178
177
  end
179
178
 
180
- it 'should provide depth-first traversal' do
179
+ it 'provides depth-first traversal' do
181
180
  result = []
182
- subject.traverse_df(subject.start_vertex) do |vertex|
181
+ a_graph.traverse_df(a_graph.start_vertex) do |vertex|
183
182
  result << vertex.label
184
183
  end
185
184
 
@@ -200,28 +199,28 @@ module Rley # Open this namespace to avoid module qualifier prefixes
200
199
  expect(result).to eq(expected)
201
200
  end
202
201
 
203
- it 'should provide human-readable representation of itself' do
202
+ it 'provides human-readable representation of itself' do
204
203
  prefix = /^#<Rley::GFG::GrmFlowGraph:\d+ @vertices=\[/
205
- expect(subject.inspect).to match(prefix)
204
+ expect(a_graph.inspect).to match(prefix)
206
205
  pattern = /@vertices=\[#<Rley::GFG::StartVertex:\d+ label="\.S"/
207
- expect(subject.inspect).to match(pattern)
206
+ expect(a_graph.inspect).to match(pattern)
208
207
  suffix = /]>$/
209
- expect(subject.inspect).to match(suffix)
208
+ expect(a_graph.inspect).to match(suffix)
210
209
  end
211
210
 
212
- it 'should perform a diagnosis of a correct grammar' do
213
- expect { subject.diagnose }.not_to raise_error
211
+ it 'performs a diagnosis of a correct grammar' do
212
+ expect { a_graph.diagnose }.not_to raise_error
214
213
  grammar_abc.non_terminals.each do |nterm|
215
214
  expect(nterm).not_to be_undefined
216
215
  expect(nterm).not_to be_unreachable
217
216
  end
218
217
  end
219
218
 
220
- it 'should detect when a non-terminal is unreachable' do
219
+ it 'detects when a non-terminal is unreachable' do
221
220
  grammar = problematic_grammar
222
221
  items = build_items_for_grammar(grammar)
223
222
 
224
- graph = GrmFlowGraph.new(items)
223
+ graph = described_class.new(items)
225
224
  expect { graph.diagnose }.not_to raise_error
226
225
  grammar.non_terminals.each do |nterm|
227
226
  expect(nterm).not_to be_undefined