rley 0.8.14 → 0.9.01

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 (106) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +20 -2
  3. data/CHANGELOG.md +14 -0
  4. data/Gemfile +8 -0
  5. data/examples/general/calc_iter1/spec/calculator_spec.rb +9 -9
  6. data/examples/general/calc_iter2/spec/calculator_spec.rb +39 -39
  7. data/examples/general/recursive_right.rb +2 -2
  8. data/lib/rley/constants.rb +2 -2
  9. data/lib/rley/engine.rb +3 -1
  10. data/lib/rley/formatter/asciitree.rb +4 -1
  11. data/lib/rley/gfg/epsilon_edge.rb +0 -2
  12. data/lib/rley/gfg/grm_flow_graph.rb +7 -9
  13. data/lib/rley/gfg/item_vertex.rb +1 -1
  14. data/lib/rley/gfg/vertex.rb +11 -0
  15. data/lib/rley/lexical/token.rb +10 -3
  16. data/lib/rley/parse_forest_visitor.rb +3 -3
  17. data/lib/rley/parse_rep/ast_base_builder.rb +6 -5
  18. data/lib/rley/parse_rep/parse_forest_builder.rb +4 -2
  19. data/lib/rley/parse_rep/parse_tree_builder.rb +14 -2
  20. data/lib/rley/parse_rep/parse_tree_factory.rb +1 -1
  21. data/lib/rley/parser/error_reason.rb +2 -2
  22. data/lib/rley/parser/gfg_chart.rb +2 -2
  23. data/lib/rley/parser/gfg_earley_parser.rb +2 -2
  24. data/lib/rley/parser/gfg_parsing.rb +1 -1
  25. data/lib/rley/parser/parse_entry.rb +4 -4
  26. data/lib/rley/parser/parse_entry_set.rb +4 -2
  27. data/lib/rley/parser/parse_entry_tracker.rb +10 -7
  28. data/lib/rley/parser/parse_walker_factory.rb +9 -8
  29. data/lib/rley/ptree/parse_tree_node.rb +6 -0
  30. data/lib/rley/ptree/terminal_node.rb +1 -1
  31. data/lib/rley/rgn/ast_builder.rb +2 -2
  32. data/lib/rley/rgn/ast_node.rb +11 -1
  33. data/lib/rley/rgn/ast_visitor.rb +2 -2
  34. data/lib/rley/rgn/composite_node.rb +1 -1
  35. data/lib/rley/rgn/grammar_builder.rb +12 -14
  36. data/lib/rley/rgn/parser.rb +2 -2
  37. data/lib/rley/rgn/tokenizer.rb +1 -1
  38. data/lib/rley/rley_error.rb +0 -4
  39. data/lib/rley/sppf/composite_node.rb +6 -0
  40. data/lib/rley/sppf/parse_forest.rb +7 -7
  41. data/lib/rley/sppf/sppf_node.rb +15 -1
  42. data/lib/rley/syntax/base_grammar_builder.rb +3 -12
  43. data/lib/rley/syntax/grammar.rb +9 -4
  44. data/lib/rley/syntax/production.rb +1 -1
  45. data/spec/rley/base/dotted_item_spec.rb +46 -46
  46. data/spec/rley/base/grm_items_builder_spec.rb +1 -1
  47. data/spec/rley/engine_spec.rb +50 -50
  48. data/spec/rley/formatter/asciitree_spec.rb +8 -8
  49. data/spec/rley/formatter/bracket_notation_spec.rb +10 -10
  50. data/spec/rley/formatter/debug_spec.rb +10 -10
  51. data/spec/rley/formatter/json_spec.rb +6 -7
  52. data/spec/rley/gfg/call_edge_spec.rb +6 -6
  53. data/spec/rley/gfg/edge_spec.rb +8 -7
  54. data/spec/rley/gfg/end_vertex_spec.rb +8 -7
  55. data/spec/rley/gfg/epsilon_edge_spec.rb +5 -4
  56. data/spec/rley/gfg/grm_flow_graph_spec.rb +33 -34
  57. data/spec/rley/gfg/item_vertex_spec.rb +34 -36
  58. data/spec/rley/gfg/non_terminal_vertex_spec.rb +12 -12
  59. data/spec/rley/gfg/return_edge_spec.rb +6 -6
  60. data/spec/rley/gfg/scan_edge_spec.rb +7 -6
  61. data/spec/rley/gfg/shortcut_edge_spec.rb +15 -15
  62. data/spec/rley/gfg/start_vertex_spec.rb +8 -8
  63. data/spec/rley/gfg/vertex_spec.rb +18 -18
  64. data/spec/rley/lexical/literal_spec.rb +5 -5
  65. data/spec/rley/lexical/token_range_spec.rb +55 -55
  66. data/spec/rley/lexical/token_spec.rb +17 -16
  67. data/spec/rley/parse_forest_visitor_spec.rb +30 -32
  68. data/spec/rley/parse_rep/ambiguous_parse_spec.rb +2 -2
  69. data/spec/rley/parse_rep/ast_builder_spec.rb +30 -30
  70. data/spec/rley/parse_rep/cst_builder_spec.rb +85 -85
  71. data/spec/rley/parse_rep/groucho_spec.rb +23 -23
  72. data/spec/rley/parse_rep/parse_forest_builder_spec.rb +42 -42
  73. data/spec/rley/parse_rep/parse_forest_factory_spec.rb +10 -12
  74. data/spec/rley/parse_rep/parse_tree_factory_spec.rb +10 -15
  75. data/spec/rley/parse_tree_visitor_spec.rb +43 -46
  76. data/spec/rley/parser/dangling_else_spec.rb +12 -12
  77. data/spec/rley/parser/error_reason_spec.rb +37 -37
  78. data/spec/rley/parser/gfg_chart_spec.rb +27 -29
  79. data/spec/rley/parser/gfg_earley_parser_spec.rb +55 -56
  80. data/spec/rley/parser/gfg_parsing_spec.rb +106 -103
  81. data/spec/rley/parser/parse_entry_set_spec.rb +63 -61
  82. data/spec/rley/parser/parse_entry_spec.rb +73 -71
  83. data/spec/rley/parser/parse_walker_factory_spec.rb +14 -15
  84. data/spec/rley/ptree/non_terminal_node_spec.rb +16 -16
  85. data/spec/rley/ptree/parse_tree_node_spec.rb +11 -11
  86. data/spec/rley/ptree/parse_tree_spec.rb +6 -8
  87. data/spec/rley/ptree/terminal_node_spec.rb +6 -6
  88. data/spec/rley/rgn/grammar_builder_spec.rb +69 -67
  89. data/spec/rley/rgn/parser_spec.rb +63 -63
  90. data/spec/rley/rgn/repetition_node_spec.rb +15 -15
  91. data/spec/rley/rgn/sequence_node_spec.rb +10 -10
  92. data/spec/rley/rgn/symbol_node_spec.rb +5 -6
  93. data/spec/rley/rgn/tokenizer_spec.rb +68 -67
  94. data/spec/rley/sppf/alternative_node_spec.rb +16 -16
  95. data/spec/rley/sppf/non_terminal_node_spec.rb +20 -20
  96. data/spec/rley/sppf/token_node_spec.rb +13 -13
  97. data/spec/rley/syntax/base_grammar_builder_spec.rb +76 -86
  98. data/spec/rley/syntax/grammar_spec.rb +40 -78
  99. data/spec/rley/syntax/grm_symbol_spec.rb +7 -7
  100. data/spec/rley/syntax/match_closest_spec.rb +8 -8
  101. data/spec/rley/syntax/non_terminal_spec.rb +25 -25
  102. data/spec/rley/syntax/production_spec.rb +33 -33
  103. data/spec/rley/syntax/symbol_seq_spec.rb +27 -27
  104. data/spec/rley/syntax/terminal_spec.rb +12 -11
  105. data/spec/support/base_tokenizer_spec.rb +9 -8
  106. metadata +8 -25
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
3
  require_relative '../rley_error'
5
4
 
6
5
  module Rley # This module is used as a namespace
@@ -49,7 +48,7 @@ module Rley # This module is used as a namespace
49
48
 
50
49
  # @return [Array] The list of non-terminals in the grammar.
51
50
  def non_terminals
52
- @non_terminals ||= symbols.select { |s| s.kind_of?(NonTerminal) }
51
+ @non_terminals ||= symbols.select { |s| s.is_a?(NonTerminal) }
53
52
  end
54
53
 
55
54
  # @return [Production] The start production of the grammar (i.e.
@@ -74,6 +73,7 @@ module Rley # This module is used as a namespace
74
73
  add_symbol(the_lhs)
75
74
 
76
75
  aProduction.rhs.each { |symb| add_symbol(symb) }
76
+ aProduction
77
77
  end
78
78
 
79
79
  # If the production is anonymous, then assign it
@@ -82,12 +82,15 @@ module Rley # This module is used as a namespace
82
82
  return unless aProduction.name.nil?
83
83
 
84
84
  index = rules.find_index(aProduction)
85
+ # @type var index : Integer
86
+
85
87
  prefix = aProduction.lhs.name.dup
86
88
  previous = index.zero? ? nil : rules[index - 1]
87
89
  if previous.nil? || previous.lhs != aProduction.lhs
88
90
  suffix = '_0'
89
91
  else
90
- prev_serial = previous.name.match(/_(\d+)$/)
92
+ # @type var previous : Production
93
+ prev_serial = previous.name&.match(/_(\d+)$/)
91
94
  if prev_serial
92
95
  suffix = "_#{prev_serial[1].to_i + 1}"
93
96
  else
@@ -145,6 +148,8 @@ module Rley # This module is used as a namespace
145
148
  end
146
149
 
147
150
  last_considered = nil
151
+ # @type var last_considered : Rley::Syntax::GrmSymbol
152
+
148
153
  a_rule.rhs.members.each do |symbol|
149
154
  last_considered = symbol
150
155
  break unless symbol.generative?
@@ -200,7 +205,7 @@ module Rley # This module is used as a namespace
200
205
  # Drop productions with one terminal in rhs or with a nullable lhs
201
206
  filtered_rules = rules.reject do |prod|
202
207
  prod.lhs.nullable? || prod.rhs.find do |symb|
203
- symb.kind_of?(Terminal)
208
+ symb.is_a?(Terminal)
204
209
  end
205
210
  end
206
211
 
@@ -92,7 +92,7 @@ module Rley # This module is used as a namespace
92
92
  # Validation method. Return the validated input argument or
93
93
  # raise an exception.
94
94
  def valid_lhs(aNonTerminal)
95
- unless aNonTerminal.kind_of?(NonTerminal)
95
+ unless aNonTerminal.is_a?(NonTerminal)
96
96
  msg_prefix = 'Left side of production must be a non-terminal symbol'
97
97
  msg_suffix = ", found a #{aNonTerminal.class} instead."
98
98
  raise StandardError, msg_prefix + msg_suffix
@@ -27,126 +27,126 @@ module Rley # Open this namespace to avoid module qualifier prefixes
27
27
  let(:empty_prod) { build_prod(nt_sentence) }
28
28
 
29
29
  # Default instantiation rule
30
- subject { DottedItem.new(sample_prod, 1) }
30
+ subject(:an_item) { described_class.new(sample_prod, 1) }
31
31
 
32
32
  context 'Initialization:' do
33
- it 'should be created with a production and an index' do
34
- expect { DottedItem.new(sample_prod, 0) }.not_to raise_error
35
- expect { DottedItem.new(sample_prod, 3) }.not_to raise_error
33
+ it 'is created with a production and an index' do
34
+ expect { described_class.new(sample_prod, 0) }.not_to raise_error
35
+ expect { described_class.new(sample_prod, 3) }.not_to raise_error
36
36
  end
37
37
 
38
- it 'should complain when the index is out-of-bounds' do
38
+ it 'complains when the index is out-of-bounds' do
39
39
  err = StandardError
40
40
  msg = 'Out of bound index'
41
- expect { DottedItem.new(sample_prod, 4) }.to raise_error(err, msg)
41
+ expect { described_class.new(sample_prod, 4) }.to raise_error(err, msg)
42
42
  end
43
43
 
44
- it 'should know its production' do
45
- expect(subject.production).to eq(sample_prod)
44
+ it 'knows its production' do
45
+ expect(an_item.production).to eq(sample_prod)
46
46
  end
47
47
 
48
- it 'should know the lhs of the production' do
49
- expect(subject.lhs).to eq(sample_prod.lhs)
48
+ it 'knows the lhs of the production' do
49
+ expect(an_item.lhs).to eq(sample_prod.lhs)
50
50
  end
51
51
 
52
- it 'should know its position' do
52
+ it 'knows its position' do
53
53
  # At start position
54
- instance1 = DottedItem.new(sample_prod, 0)
54
+ instance1 = described_class.new(sample_prod, 0)
55
55
  expect(instance1.position).to eq(0)
56
56
 
57
57
  # At (before) last symbol
58
- instance2 = DottedItem.new(sample_prod, 2)
58
+ instance2 = described_class.new(sample_prod, 2)
59
59
  expect(instance2.position).to eq(2)
60
60
 
61
61
  # After all symbols in rhs
62
- instance3 = DottedItem.new(sample_prod, 3)
62
+ instance3 = described_class.new(sample_prod, 3)
63
63
  expect(instance3.position).to eq(-1)
64
64
 
65
65
  # At start/end at the same time (production is empty)
66
- instance4 = DottedItem.new(build_prod(nt_sentence), 0)
66
+ instance4 = described_class.new(build_prod(nt_sentence), 0)
67
67
  expect(instance4.position).to eq(-2)
68
68
  end
69
69
  end # context
70
70
 
71
71
  context 'Provided service:' do
72
- it 'should whether its dot is at start position' do
73
- expect(subject).not_to be_at_start
72
+ it 'knows whether its dot is at start position' do
73
+ expect(an_item).not_to be_at_start
74
74
 
75
75
  # At start position
76
- instance1 = DottedItem.new(sample_prod, 0)
76
+ instance1 = described_class.new(sample_prod, 0)
77
77
  expect(instance1).to be_at_start
78
78
 
79
79
  # At start/end at the same time (production is empty)
80
- instance2 = DottedItem.new(build_prod(nt_sentence), 0)
80
+ instance2 = described_class.new(build_prod(nt_sentence), 0)
81
81
  expect(instance2).to be_at_start
82
82
  end
83
83
 
84
- it 'should whether it is a reduce item' do
85
- expect(subject).not_to be_reduce_item
84
+ it 'knows whether it is a reduce item' do
85
+ expect(an_item).not_to be_reduce_item
86
86
 
87
- first_instance = DottedItem.new(sample_prod, 3)
87
+ first_instance = described_class.new(sample_prod, 3)
88
88
  expect(first_instance).to be_reduce_item
89
89
 
90
- second_instance = DottedItem.new(empty_prod, 0)
90
+ second_instance = described_class.new(empty_prod, 0)
91
91
  expect(second_instance).to be_reduce_item
92
92
  end
93
93
 
94
- it 'should know the symbol before the dot' do
95
- expect(subject.prev_symbol).to eq(t_a)
94
+ it 'knows the symbol before the dot' do
95
+ expect(an_item.prev_symbol).to eq(t_a)
96
96
 
97
97
  # Case of an empty production
98
- instance = DottedItem.new(empty_prod, 0)
98
+ instance = described_class.new(empty_prod, 0)
99
99
  expect(instance.prev_symbol).to be_nil
100
100
 
101
101
  # Case of a dot at start position
102
- instance = DottedItem.new(sample_prod, 0)
102
+ instance = described_class.new(sample_prod, 0)
103
103
  expect(instance.prev_symbol).to be_nil
104
104
  end
105
105
 
106
- it 'should know the symbol after the dot' do
107
- expect(subject.next_symbol).to eq(t_b)
106
+ it 'knows the symbol after the dot' do
107
+ expect(an_item.next_symbol).to eq(t_b)
108
108
  end
109
109
 
110
- it 'should calculate the previous position of the dot' do
111
- expect(subject.prev_position).to eq(0)
110
+ it 'calculates the previous position of the dot' do
111
+ expect(an_item.prev_position).to eq(0)
112
112
 
113
113
  # Case of an empty production
114
- instance = DottedItem.new(empty_prod, 0)
114
+ instance = described_class.new(empty_prod, 0)
115
115
  expect(instance.prev_position).to be_nil
116
116
 
117
117
  # Case of a dot at start position
118
- instance = DottedItem.new(sample_prod, 0)
118
+ instance = described_class.new(sample_prod, 0)
119
119
  expect(instance.prev_position).to be_nil
120
120
 
121
121
  # Case of single symbol production
122
- instance = DottedItem.new(other_prod, 1)
122
+ instance = described_class.new(other_prod, 1)
123
123
  expect(instance.prev_position).to eq(0)
124
124
  end
125
125
 
126
- it 'should determine if it is a successor of another dotted item' do
127
- expect(subject).not_to be_successor_of(subject)
126
+ it 'determines if it is a successor of another dotted item' do
127
+ expect(an_item).not_to be_successor_of(an_item)
128
128
 
129
129
  # Case: different productions
130
- instance = DottedItem.new(empty_prod, 0)
131
- expect(subject).not_to be_successor_of(instance)
130
+ instance = described_class.new(empty_prod, 0)
131
+ expect(an_item).not_to be_successor_of(instance)
132
132
 
133
133
  # Case: one position difference
134
- instance = DottedItem.new(sample_prod, 0)
135
- expect(subject).to be_successor_of(instance)
136
- expect(instance).not_to be_successor_of(subject)
134
+ instance = described_class.new(sample_prod, 0)
135
+ expect(an_item).to be_successor_of(instance)
136
+ expect(instance).not_to be_successor_of(an_item)
137
137
 
138
138
  # Case: more than one position difference
139
- instance2 = DottedItem.new(sample_prod, 2)
139
+ instance2 = described_class.new(sample_prod, 2)
140
140
  expect(instance).not_to be_successor_of(instance2)
141
- expect(subject).not_to be_successor_of(instance2)
142
- expect(instance2).to be_successor_of(subject)
141
+ expect(an_item).not_to be_successor_of(instance2)
142
+ expect(instance2).to be_successor_of(an_item)
143
143
  end
144
144
 
145
145
 
146
146
 
147
- it 'should give its text representation' do
147
+ it 'gives its text representation' do
148
148
  expectation = 'sentence => A . B C'
149
- expect(subject.to_s).to eq(expectation)
149
+ expect(an_item.to_s).to eq(expectation)
150
150
  end
151
151
  end
152
152
  end # describe
@@ -21,7 +21,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
21
21
  end
22
22
 
23
23
  context 'Builder pattern behaviour' do
24
- it 'should create dotted items for a grammar' do
24
+ it 'creates dotted items for a grammar' do
25
25
  # Next line calls method from mixin module under test
26
26
  items = build_dotted_items(grammar_abc)
27
27
  expect(items.size).to eq(8)
@@ -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