rley 0.8.13 → 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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +28 -1
  3. data/CHANGELOG.md +6 -0
  4. data/examples/NLP/engtagger.rb +1 -1
  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 +1 -1
  9. data/lib/rley/gfg/grm_flow_graph.rb +0 -1
  10. data/lib/rley/parser/parse_entry_set.rb +0 -1
  11. data/lib/rley/parser/parse_walker_factory.rb +0 -1
  12. data/lib/rley/rgn/grammar_builder.rb +0 -2
  13. data/lib/rley/rgn/tokenizer.rb +6 -6
  14. data/lib/rley/syntax/base_grammar_builder.rb +0 -1
  15. data/lib/rley/syntax/grammar.rb +0 -1
  16. data/spec/rley/base/dotted_item_spec.rb +46 -46
  17. data/spec/rley/base/grm_items_builder_spec.rb +1 -1
  18. data/spec/rley/engine_spec.rb +50 -50
  19. data/spec/rley/formatter/asciitree_spec.rb +8 -8
  20. data/spec/rley/formatter/bracket_notation_spec.rb +10 -10
  21. data/spec/rley/formatter/debug_spec.rb +10 -10
  22. data/spec/rley/formatter/json_spec.rb +6 -7
  23. data/spec/rley/gfg/call_edge_spec.rb +6 -6
  24. data/spec/rley/gfg/edge_spec.rb +8 -7
  25. data/spec/rley/gfg/end_vertex_spec.rb +8 -7
  26. data/spec/rley/gfg/epsilon_edge_spec.rb +5 -4
  27. data/spec/rley/gfg/grm_flow_graph_spec.rb +33 -34
  28. data/spec/rley/gfg/item_vertex_spec.rb +34 -36
  29. data/spec/rley/gfg/non_terminal_vertex_spec.rb +12 -12
  30. data/spec/rley/gfg/return_edge_spec.rb +6 -6
  31. data/spec/rley/gfg/scan_edge_spec.rb +7 -6
  32. data/spec/rley/gfg/shortcut_edge_spec.rb +15 -15
  33. data/spec/rley/gfg/start_vertex_spec.rb +8 -8
  34. data/spec/rley/gfg/vertex_spec.rb +18 -18
  35. data/spec/rley/lexical/literal_spec.rb +5 -5
  36. data/spec/rley/lexical/token_range_spec.rb +55 -55
  37. data/spec/rley/lexical/token_spec.rb +17 -16
  38. data/spec/rley/parse_forest_visitor_spec.rb +30 -32
  39. data/spec/rley/parse_rep/ambiguous_parse_spec.rb +2 -2
  40. data/spec/rley/parse_rep/ast_builder_spec.rb +30 -30
  41. data/spec/rley/parse_rep/cst_builder_spec.rb +85 -85
  42. data/spec/rley/parse_rep/groucho_spec.rb +23 -23
  43. data/spec/rley/parse_rep/parse_forest_builder_spec.rb +42 -42
  44. data/spec/rley/parse_rep/parse_forest_factory_spec.rb +10 -12
  45. data/spec/rley/parse_rep/parse_tree_factory_spec.rb +10 -15
  46. data/spec/rley/parse_tree_visitor_spec.rb +43 -46
  47. data/spec/rley/parser/dangling_else_spec.rb +12 -12
  48. data/spec/rley/parser/error_reason_spec.rb +37 -37
  49. data/spec/rley/parser/gfg_chart_spec.rb +27 -29
  50. data/spec/rley/parser/gfg_earley_parser_spec.rb +55 -56
  51. data/spec/rley/parser/gfg_parsing_spec.rb +106 -103
  52. data/spec/rley/parser/parse_entry_set_spec.rb +63 -61
  53. data/spec/rley/parser/parse_entry_spec.rb +73 -71
  54. data/spec/rley/parser/parse_walker_factory_spec.rb +14 -15
  55. data/spec/rley/ptree/non_terminal_node_spec.rb +16 -16
  56. data/spec/rley/ptree/parse_tree_node_spec.rb +11 -11
  57. data/spec/rley/ptree/parse_tree_spec.rb +6 -8
  58. data/spec/rley/ptree/terminal_node_spec.rb +6 -6
  59. data/spec/rley/rgn/grammar_builder_spec.rb +69 -67
  60. data/spec/rley/rgn/parser_spec.rb +63 -63
  61. data/spec/rley/rgn/repetition_node_spec.rb +15 -15
  62. data/spec/rley/rgn/sequence_node_spec.rb +10 -10
  63. data/spec/rley/rgn/symbol_node_spec.rb +5 -6
  64. data/spec/rley/rgn/tokenizer_spec.rb +68 -67
  65. data/spec/rley/sppf/alternative_node_spec.rb +16 -16
  66. data/spec/rley/sppf/non_terminal_node_spec.rb +20 -20
  67. data/spec/rley/sppf/token_node_spec.rb +13 -13
  68. data/spec/rley/syntax/base_grammar_builder_spec.rb +76 -86
  69. data/spec/rley/syntax/grammar_spec.rb +40 -78
  70. data/spec/rley/syntax/grm_symbol_spec.rb +7 -7
  71. data/spec/rley/syntax/match_closest_spec.rb +8 -8
  72. data/spec/rley/syntax/non_terminal_spec.rb +25 -25
  73. data/spec/rley/syntax/production_spec.rb +33 -33
  74. data/spec/rley/syntax/symbol_seq_spec.rb +27 -27
  75. data/spec/rley/syntax/terminal_spec.rb +12 -11
  76. data/spec/support/base_tokenizer_spec.rb +9 -8
  77. metadata +2 -2
@@ -8,113 +8,115 @@ require_relative '../../../lib/rley/rgn/grammar_builder'
8
8
  module Rley # Open this namespace to avoid module qualifier prefixes
9
9
  module RGN # Open this namespace to avoid module qualifier prefixes
10
10
  describe GrammarBuilder do
11
+ subject(:a_builder) { described_class.new }
12
+
11
13
  context 'Initialization without argument:' do
12
- it 'could be created without argument' do
13
- expect { GrammarBuilder.new }.not_to raise_error
14
+ it 'is created without argument' do
15
+ expect { described_class.new }.not_to raise_error
14
16
  end
15
17
 
16
- it 'should have no grammar symbols at start' do
17
- expect(subject.symbols).to be_empty
18
+ it 'has no grammar symbols at start' do
19
+ expect(a_builder.symbols).to be_empty
18
20
  end
19
21
 
20
- it 'should have no productions at start' do
21
- expect(subject.productions).to be_empty
22
+ it 'has no productions at start' do
23
+ expect(a_builder.productions).to be_empty
22
24
  end
23
25
  end # context
24
26
 
25
27
  context 'Initialization with argument:' do
26
- it 'could be created with a block argument' do
28
+ it 'is created with a block argument' do
27
29
  expect do
28
- GrammarBuilder.new { nil }
30
+ described_class.new { nil }
29
31
  end.not_to raise_error
30
32
  end
31
33
 
32
34
  it 'could have grammar symbols from block argument' do
33
- instance = GrammarBuilder.new do
35
+ instance = described_class.new do
34
36
  add_terminals('a', 'b', 'c')
35
37
  end
36
38
  expect(instance.symbols.size).to eq(3)
37
39
  end
38
40
 
39
- it 'should have no productions at start' do
40
- expect(subject.productions).to be_empty
41
+ it 'has no productions at start' do
42
+ expect(a_builder.productions).to be_empty
41
43
  end
42
44
  end # context
43
45
 
44
46
  context 'Adding symbols:' do
45
- it 'should build terminals from their names' do
46
- subject.add_terminals('a', 'b', 'c')
47
- expect(subject.symbols.size).to eq(3)
48
- expect(subject.symbols['a']).to be_kind_of(Syntax::Terminal)
49
- expect(subject.symbols['a'].name).to eq('a')
50
- expect(subject.symbols['b']).to be_kind_of(Syntax::Terminal)
51
- expect(subject.symbols['b'].name).to eq('b')
52
- expect(subject.symbols['c']).to be_kind_of(Syntax::Terminal)
53
- expect(subject.symbols['c'].name).to eq('c')
47
+ it 'builds terminals from their names' do
48
+ a_builder.add_terminals('a', 'b', 'c')
49
+ expect(a_builder.symbols.size).to eq(3)
50
+ expect(a_builder.symbols['a']).to be_a(Syntax::Terminal)
51
+ expect(a_builder.symbols['a'].name).to eq('a')
52
+ expect(a_builder.symbols['b']).to be_a(Syntax::Terminal)
53
+ expect(a_builder.symbols['b'].name).to eq('b')
54
+ expect(a_builder.symbols['c']).to be_a(Syntax::Terminal)
55
+ expect(a_builder.symbols['c'].name).to eq('c')
54
56
  end
55
57
 
56
- it 'should accept already built terminals' do
58
+ it 'accepts already built terminals' do
57
59
  a = Syntax::Terminal.new('a')
58
60
  b = Syntax::Terminal.new('b')
59
61
  c = Syntax::Terminal.new('c')
60
62
 
61
- subject.add_terminals(a, b, c)
62
- expect(subject.symbols.size).to eq(3)
63
- expect(subject.symbols['a']).to eq(a)
64
- expect(subject.symbols['b']).to eq(b)
65
- expect(subject.symbols['c']).to eq(c)
63
+ a_builder.add_terminals(a, b, c)
64
+ expect(a_builder.symbols.size).to eq(3)
65
+ expect(a_builder.symbols['a']).to eq(a)
66
+ expect(a_builder.symbols['b']).to eq(b)
67
+ expect(a_builder.symbols['c']).to eq(c)
66
68
  end
67
69
  end # context
68
70
 
69
71
  context 'Adding productions:' do
70
- subject do
71
- instance = GrammarBuilder.new
72
+ subject(:a_builder) do
73
+ instance = described_class.new
72
74
  instance.add_terminals('a', 'b', 'c')
73
75
  instance
74
76
  end
75
77
 
76
- it 'should add a valid production' do
78
+ it 'adds a valid production' do
77
79
  # Case of a rhs representation that consists of one name only
78
- expect { subject.add_production('S' => 'A') }.not_to raise_error
79
- expect(subject.productions.size).to eq(1)
80
- new_prod = subject.productions[0]
81
- expect(new_prod.lhs).to eq(subject['S'])
80
+ expect { a_builder.add_production('S' => 'A') }.not_to raise_error
81
+ expect(a_builder.productions.size).to eq(1)
82
+ new_prod = a_builder.productions[0]
83
+ expect(new_prod.lhs).to eq(a_builder['S'])
82
84
  expect(new_prod.rhs[0]).not_to be_nil
83
- expect(new_prod.rhs[0]).to eq(subject['A'])
85
+ expect(new_prod.rhs[0]).to eq(a_builder['A'])
84
86
 
85
87
  # Case of rhs with multiple symbols
86
- subject.add_production('A' => 'a A c')
87
- expect(subject.productions.size).to eq(2)
88
- new_prod = subject.productions.last
89
- expect(new_prod.lhs).to eq(subject['A'])
90
- expect_rhs = [subject['a'], subject['A'], subject['c']]
88
+ a_builder.add_production('A' => 'a A c')
89
+ expect(a_builder.productions.size).to eq(2)
90
+ new_prod = a_builder.productions.last
91
+ expect(new_prod.lhs).to eq(a_builder['A'])
92
+ expect_rhs = [a_builder['a'], a_builder['A'], a_builder['c']]
91
93
  expect(new_prod.rhs.members).to eq(expect_rhs)
92
94
 
93
95
  # GrammarBuilder#rule is an alias of add_production
94
- subject.rule('A' => 'b')
95
- expect(subject.productions.size).to eq(3)
96
- new_prod = subject.productions.last
97
- expect(new_prod.lhs).to eq(subject['A'])
98
- expect(new_prod.rhs[0]).to eq(subject['b'])
96
+ a_builder.rule('A' => 'b')
97
+ expect(a_builder.productions.size).to eq(3)
98
+ new_prod = a_builder.productions.last
99
+ expect(new_prod.lhs).to eq(a_builder['A'])
100
+ expect(new_prod.rhs[0]).to eq(a_builder['b'])
99
101
  end
100
102
 
101
- it 'should accept annotated terminals' do
102
- subject.rule('A' => "a b {match_closest: 'IF' } c")
103
- expect(subject.productions.size).to eq(1)
104
- new_prod = subject.productions.last
105
- expect(new_prod.lhs).to eq(subject['A'])
103
+ it 'accepts annotated terminals' do
104
+ a_builder.rule('A' => "a b {match_closest: 'IF' } c")
105
+ expect(a_builder.productions.size).to eq(1)
106
+ new_prod = a_builder.productions.last
107
+ expect(new_prod.lhs).to eq(a_builder['A'])
106
108
  expect(new_prod.rhs[0].name).to eq('a')
107
- expect(new_prod.rhs[0]).to eq(subject['a'])
109
+ expect(new_prod.rhs[0]).to eq(a_builder['a'])
108
110
  expect(new_prod.rhs[1].name).to eq('b')
109
111
  expect(new_prod.rhs[2].name).to eq('c')
110
112
  expect(new_prod.constraints.size).to eq(1)
111
- expect(new_prod.constraints[0]).to be_kind_of(Syntax::MatchClosest)
113
+ expect(new_prod.constraints[0]).to be_a(Syntax::MatchClosest)
112
114
  expect(new_prod.constraints[0].idx_symbol).to eq(1) # b is on position 1
113
115
  expect(new_prod.constraints[0].closest_symb).to eq('IF')
114
116
  end
115
117
 
116
- it 'should support optional symbol' do
117
- instance = GrammarBuilder.new
118
+ it 'supports optional symbol' do
119
+ instance = described_class.new
118
120
  instance.add_terminals('LPAREN', 'RPAREN')
119
121
 
120
122
  instance.rule 'argument_list' => 'LPAREN arguments? RPAREN'
@@ -131,8 +133,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
131
133
  expect(instance.productions.last.rhs.members).to be_empty
132
134
  end
133
135
 
134
- it "should support Kleene's star" do
135
- instance = GrammarBuilder.new
136
+ it "supports Kleene's star" do
137
+ instance = described_class.new
136
138
  instance.add_terminals('EOF')
137
139
 
138
140
  instance.rule 'program' => 'declaration* EOF'
@@ -148,8 +150,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
148
150
  expect(first_prod.rhs.members[0].name).to eq('rep_declaration_star')
149
151
  end
150
152
 
151
- it "should support symbols decorated with Kleene's plus" do
152
- instance = GrammarBuilder.new
153
+ it "supports symbols decorated with Kleene's plus" do
154
+ instance = described_class.new
153
155
  instance.add_terminals('plus', 'minus', 'digit')
154
156
 
155
157
  instance.rule 'integer' => 'value'
@@ -171,8 +173,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
171
173
  expect(val_prod.rhs.members[0].name).to eq('rep_digit_plus')
172
174
  end
173
175
 
174
- it 'should support optional grouping' do
175
- instance = GrammarBuilder.new
176
+ it 'supports optional grouping' do
177
+ instance = described_class.new
176
178
  instance.add_terminals('EQUAL', 'IDENTIFIER', 'VAR')
177
179
 
178
180
  instance.rule 'var_decl' => 'VAR IDENTIFIER (EQUAL expression)?'
@@ -202,8 +204,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
202
204
  expect(p2.name).to eq('_qmark_none')
203
205
  end
204
206
 
205
- it 'should support grouping with star modifier' do
206
- instance = GrammarBuilder.new
207
+ it 'supports grouping with star modifier' do
208
+ instance = described_class.new
207
209
  instance.add_terminals('OR')
208
210
 
209
211
  instance.rule 'logic_or' => 'logic_and (OR logic_and)*'
@@ -233,8 +235,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
233
235
  expect(p2.name).to eq('_star_none')
234
236
  end
235
237
 
236
- it 'should support grouping with plus modifier' do
237
- instance = GrammarBuilder.new
238
+ it 'supports grouping with plus modifier' do
239
+ instance = described_class.new
238
240
  instance.add_terminals('POINT TO SEMI_COLON')
239
241
 
240
242
  instance.rule 'path' => 'POINT (TO POINT)+ SEMI_COLON'
@@ -264,8 +266,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
264
266
  expect(p2.name).to eq('_plus_one')
265
267
  end
266
268
 
267
- it 'should support grouping with nested annotation' do
268
- instance = GrammarBuilder.new
269
+ it 'supports grouping with nested annotation' do
270
+ instance = described_class.new
269
271
  instance.add_terminals('IF ELSE LPAREN RPAREN')
270
272
  st = "IF LPAREN expr RPAREN stmt (ELSE { match_closest: 'IF' } stmt)?"
271
273
  instance.rule('if_stmt' => st)
@@ -282,7 +284,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
282
284
  # expect(p0.rhs[1].name).to eq('stmt')
283
285
  # expect(p0.name).to eq('return_children')
284
286
  # expect(p0.constraints.size).to eq(1)
285
- # expect(p0.constraints[0]).to be_kind_of(Syntax::MatchClosest)
287
+ # expect(p0.constraints[0]).to be_a(Syntax::MatchClosest)
286
288
  # expect(p0.constraints[0].idx_symbol).to eq(0) # ELSE is on position 0
287
289
  # expect(p0.constraints[0].closest_symb).to eq('IF')
288
290
 
@@ -291,7 +293,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
291
293
  expect(p1.rhs[1].name).to eq('stmt')
292
294
  expect(p1.name).to eq('return_children')
293
295
  expect(p1.constraints.size).to eq(1)
294
- expect(p1.constraints[0]).to be_kind_of(Syntax::MatchClosest)
296
+ expect(p1.constraints[0]).to be_a(Syntax::MatchClosest)
295
297
  expect(p1.constraints[0].closest_symb).to eq('IF')
296
298
 
297
299
  expect(p2.lhs.name).to eq('rep_seq_ELSE_stmt_qmark')
@@ -9,7 +9,7 @@ require_relative '../../../lib/rley/rgn/parser'
9
9
  module Rley
10
10
  module RGN
11
11
  describe Parser do
12
- subject { Parser.new }
12
+ subject(:a_parser) { described_class.new }
13
13
 
14
14
  # Utility method to walk towards deeply nested node
15
15
  # @param aNTNode [Rley::PTree::NonTerminalNode]
@@ -24,44 +24,44 @@ module Rley
24
24
  end
25
25
 
26
26
  context 'Initialization:' do
27
- it 'should be initialized without argument' do
28
- expect { Parser.new }.not_to raise_error
27
+ it 'is initialized without argument' do
28
+ expect { described_class.new }.not_to raise_error
29
29
  end
30
30
 
31
- it 'should have its parse engine initialized' do
32
- expect(subject.engine).to be_kind_of(Rley::Engine)
31
+ it 'has its parse engine initialized' do
32
+ expect(a_parser.engine).to be_a(Rley::Engine)
33
33
  end
34
34
  end # context
35
35
 
36
36
  context 'Parsing into CST:' do
37
- subject do
38
- instance = Parser.new
37
+ subject(:a_parser) do
38
+ instance = described_class.new
39
39
  instance.engine.configuration.repr_builder = Rley::ParseRep::CSTBuilder
40
40
 
41
41
  instance
42
42
  end
43
43
 
44
- it 'should parse single symbol names' do
44
+ it 'parses single symbol names' do
45
45
  samples = %w[IF ifCondition statement]
46
46
 
47
47
  # One drawback of CSTs: they have a deeply nested structure
48
48
  samples.each do |source|
49
- ptree = subject.parse(source)
50
- expect(ptree.root).to be_kind_of(Rley::PTree::NonTerminalNode)
49
+ ptree = a_parser.parse(source)
50
+ expect(ptree.root).to be_a(Rley::PTree::NonTerminalNode)
51
51
  expect(ptree.root.symbol.name).to eq('notation')
52
- expect(ptree.root.subnodes[0]).to be_kind_of(Rley::PTree::NonTerminalNode)
52
+ expect(ptree.root.subnodes[0]).to be_a(Rley::PTree::NonTerminalNode)
53
53
  expect(ptree.root.subnodes[0].symbol.name).to eq('rhs')
54
- expect(ptree.root.subnodes[0].subnodes[0]).to be_kind_of(Rley::PTree::NonTerminalNode)
54
+ expect(ptree.root.subnodes[0].subnodes[0]).to be_a(Rley::PTree::NonTerminalNode)
55
55
  member_seq = ptree.root.subnodes[0].subnodes[0]
56
56
  expect(member_seq.symbol.name).to eq('member_seq')
57
- expect(member_seq.subnodes[0]).to be_kind_of(Rley::PTree::NonTerminalNode)
57
+ expect(member_seq.subnodes[0]).to be_a(Rley::PTree::NonTerminalNode)
58
58
  expect(member_seq.subnodes[0].symbol.name).to eq('member')
59
- expect(member_seq.subnodes[0].subnodes[0]).to be_kind_of(Rley::PTree::NonTerminalNode)
59
+ expect(member_seq.subnodes[0].subnodes[0]).to be_a(Rley::PTree::NonTerminalNode)
60
60
  expect(member_seq.subnodes[0].subnodes[0].symbol.name).to eq('strait_member')
61
61
  strait_member = member_seq.subnodes[0].subnodes[0]
62
- expect(strait_member.subnodes[0]).to be_kind_of(Rley::PTree::NonTerminalNode)
62
+ expect(strait_member.subnodes[0]).to be_a(Rley::PTree::NonTerminalNode)
63
63
  expect(strait_member.subnodes[0].symbol.name).to eq('base_member')
64
- expect(strait_member.subnodes[0].subnodes[0]).to be_kind_of(Rley::PTree::TerminalNode)
64
+ expect(strait_member.subnodes[0].subnodes[0]).to be_a(Rley::PTree::TerminalNode)
65
65
  expect(strait_member.subnodes[0].subnodes[0].token.lexeme).to eq(source)
66
66
  end
67
67
  end
@@ -69,122 +69,122 @@ module Rley
69
69
 
70
70
  context 'Parsing into AST:' do
71
71
  subject do
72
- instance = Parser.new
72
+ instance = described_class.new
73
73
  instance.engine.configuration.repr_builder = ASTBuilder
74
74
 
75
75
  instance
76
76
  end
77
77
 
78
- it 'should parse single symbol names' do
78
+ it 'parses single symbol names' do
79
79
  samples = %w[IF ifCondition statement]
80
80
 
81
81
  samples.each do |source|
82
- ptree = subject.parse(source)
83
- expect(ptree.root).to be_kind_of(SymbolNode)
82
+ ptree = a_parser.parse(source)
83
+ expect(ptree.root).to be_a(SymbolNode)
84
84
  expect(ptree.root.name).to eq(source)
85
85
  expect(ptree.root.annotation).to be_empty
86
86
  end
87
87
  end
88
88
 
89
- it 'should parse a sequence of symbols' do
89
+ it 'parses a sequence of symbols' do
90
90
  sequence = 'INT_LIT ELLIPSIS INT_LIT'
91
91
 
92
- ptree = subject.parse(sequence)
93
- expect(ptree.root).to be_kind_of(SequenceNode)
94
- expect(ptree.root.subnodes[0]).to be_kind_of(SymbolNode)
92
+ ptree = a_parser.parse(sequence)
93
+ expect(ptree.root).to be_a(SequenceNode)
94
+ expect(ptree.root.subnodes[0]).to be_a(SymbolNode)
95
95
  expect(ptree.root.subnodes[0].name).to eq('INT_LIT')
96
- expect(ptree.root.subnodes[1]).to be_kind_of(SymbolNode)
96
+ expect(ptree.root.subnodes[1]).to be_a(SymbolNode)
97
97
  expect(ptree.root.subnodes[1].name).to eq('ELLIPSIS')
98
- expect(ptree.root.subnodes[2]).to be_kind_of(SymbolNode)
98
+ expect(ptree.root.subnodes[2]).to be_a(SymbolNode)
99
99
  expect(ptree.root.subnodes[2].name).to eq('INT_LIT')
100
100
  end
101
101
 
102
- it 'should parse an optional symbol' do
102
+ it 'parses an optional symbol' do
103
103
  optional = 'member_seq?'
104
104
 
105
- ptree = subject.parse(optional)
106
- expect(ptree.root).to be_kind_of(RepetitionNode)
105
+ ptree = a_parser.parse(optional)
106
+ expect(ptree.root).to be_a(RepetitionNode)
107
107
  expect(ptree.root.name).to eq('rep_member_seq_qmark')
108
- expect(ptree.root.child).to be_kind_of(SymbolNode)
108
+ expect(ptree.root.child).to be_a(SymbolNode)
109
109
  expect(ptree.root.child.name).to eq('member_seq')
110
110
  expect(ptree.root.repetition).to eq(:zero_or_one)
111
111
  end
112
112
 
113
- it 'should parse a symbol with a + modifier' do
113
+ it 'parses a symbol with a + modifier' do
114
114
  one_or_more = 'member+'
115
115
 
116
- ptree = subject.parse(one_or_more)
117
- expect(ptree.root).to be_kind_of(RepetitionNode)
116
+ ptree = a_parser.parse(one_or_more)
117
+ expect(ptree.root).to be_a(RepetitionNode)
118
118
  expect(ptree.root.name).to eq('rep_member_plus')
119
- expect(ptree.root.child).to be_kind_of(SymbolNode)
119
+ expect(ptree.root.child).to be_a(SymbolNode)
120
120
  expect(ptree.root.child.name).to eq('member')
121
121
  expect(ptree.root.repetition).to eq(:one_or_more)
122
122
  end
123
123
 
124
- it 'should parse a symbol with a * modifier' do
124
+ it 'parses a symbol with a * modifier' do
125
125
  zero_or_more = 'declaration* EOF'
126
126
 
127
- ptree = subject.parse(zero_or_more)
128
- expect(ptree.root).to be_kind_of(SequenceNode)
127
+ ptree = a_parser.parse(zero_or_more)
128
+ expect(ptree.root).to be_a(SequenceNode)
129
129
  expect(ptree.root.name).to eq('seq_rep_declaration_star_EOF')
130
- expect(ptree.root.subnodes[0]).to be_kind_of(RepetitionNode)
130
+ expect(ptree.root.subnodes[0]).to be_a(RepetitionNode)
131
131
  expect(ptree.root.subnodes[0].name).to eq('rep_declaration_star')
132
132
  expect(ptree.root.subnodes[0].repetition).to eq(:zero_or_more)
133
- expect(ptree.root.subnodes[0].child).to be_kind_of(SymbolNode)
133
+ expect(ptree.root.subnodes[0].child).to be_a(SymbolNode)
134
134
  expect(ptree.root.subnodes[0].child.name).to eq('declaration')
135
- expect(ptree.root.subnodes[1]).to be_kind_of(SymbolNode)
135
+ expect(ptree.root.subnodes[1]).to be_a(SymbolNode)
136
136
  expect(ptree.root.subnodes[1].name).to eq('EOF')
137
137
  end
138
138
 
139
- it 'should parse a grouping with a modifier' do
139
+ it 'parses a grouping with a modifier' do
140
140
  input = 'IF ifCondition statement (ELSE statement)?'
141
141
 
142
- ptree = subject.parse(input)
143
- expect(ptree.root).to be_kind_of(SequenceNode)
144
- expect(ptree.root.subnodes[0]).to be_kind_of(SymbolNode)
142
+ ptree = a_parser.parse(input)
143
+ expect(ptree.root).to be_a(SequenceNode)
144
+ expect(ptree.root.subnodes[0]).to be_a(SymbolNode)
145
145
  expect(ptree.root.subnodes[0].name).to eq('IF')
146
- expect(ptree.root.subnodes[1]).to be_kind_of(SymbolNode)
146
+ expect(ptree.root.subnodes[1]).to be_a(SymbolNode)
147
147
  expect(ptree.root.subnodes[1].name).to eq('ifCondition')
148
- expect(ptree.root.subnodes[2]).to be_kind_of(SymbolNode)
148
+ expect(ptree.root.subnodes[2]).to be_a(SymbolNode)
149
149
  expect(ptree.root.subnodes[2].name).to eq('statement')
150
- expect(ptree.root.subnodes[3]).to be_kind_of(RepetitionNode)
150
+ expect(ptree.root.subnodes[3]).to be_a(RepetitionNode)
151
151
  expect(ptree.root.subnodes[3].name).to eq('rep_seq_ELSE_statement_qmark')
152
152
  expect(ptree.root.subnodes[3].repetition).to eq(:zero_or_one)
153
- expect(ptree.root.subnodes[3].child).to be_kind_of(SequenceNode)
154
- expect(ptree.root.subnodes[3].child.subnodes[0]).to be_kind_of(SymbolNode)
153
+ expect(ptree.root.subnodes[3].child).to be_a(SequenceNode)
154
+ expect(ptree.root.subnodes[3].child.subnodes[0]).to be_a(SymbolNode)
155
155
  expect(ptree.root.subnodes[3].child.subnodes[0].name).to eq('ELSE')
156
- expect(ptree.root.subnodes[3].child.subnodes[1]).to be_kind_of(SymbolNode)
156
+ expect(ptree.root.subnodes[3].child.subnodes[1]).to be_a(SymbolNode)
157
157
  expect(ptree.root.subnodes[3].child.subnodes[1].name).to eq('statement')
158
158
  end
159
159
 
160
- it 'should parse an annotated symbol' do
160
+ it 'parses an annotated symbol' do
161
161
  optional = 'member_seq{repeat: 0..1}'
162
162
 
163
- ptree = subject.parse(optional)
164
- expect(ptree.root).to be_kind_of(RepetitionNode)
163
+ ptree = a_parser.parse(optional)
164
+ expect(ptree.root).to be_a(RepetitionNode)
165
165
  expect(ptree.root.name).to eq('rep_member_seq_qmark')
166
166
  expect(ptree.root.repetition).to eq(:zero_or_one)
167
- expect(ptree.root.child).to be_kind_of(SymbolNode)
167
+ expect(ptree.root.child).to be_a(SymbolNode)
168
168
  expect(ptree.root.child.name).to eq('member_seq')
169
169
  end
170
170
 
171
- it 'should parse a grouping with embedded annotation' do
171
+ it 'parses a grouping with embedded annotation' do
172
172
  if_stmt = "IF ifCondition statement ( ELSE { match_closest: 'IF' } statement )?"
173
173
 
174
- ptree = subject.parse(if_stmt)
175
- expect(ptree.root).to be_kind_of(SequenceNode)
176
- expect(ptree.root.subnodes[0]).to be_kind_of(SymbolNode)
174
+ ptree = a_parser.parse(if_stmt)
175
+ expect(ptree.root).to be_a(SequenceNode)
176
+ expect(ptree.root.subnodes[0]).to be_a(SymbolNode)
177
177
  expect(ptree.root.subnodes[0].name).to eq('IF')
178
- expect(ptree.root.subnodes[1]).to be_kind_of(SymbolNode)
178
+ expect(ptree.root.subnodes[1]).to be_a(SymbolNode)
179
179
  expect(ptree.root.subnodes[1].name).to eq('ifCondition')
180
- expect(ptree.root.subnodes[2]).to be_kind_of(SymbolNode)
180
+ expect(ptree.root.subnodes[2]).to be_a(SymbolNode)
181
181
  expect(ptree.root.subnodes[2].name).to eq('statement')
182
182
  optional = ptree.root.subnodes[3]
183
- expect(optional).to be_kind_of(RepetitionNode)
183
+ expect(optional).to be_a(RepetitionNode)
184
184
  expect(optional.name).to eq('rep_seq_ELSE_statement_qmark')
185
185
  expect(optional.repetition).to eq(:zero_or_one)
186
- expect(optional.child).to be_kind_of(SequenceNode)
187
- expect(optional.child.subnodes[0]).to be_kind_of(SymbolNode)
186
+ expect(optional.child).to be_a(SequenceNode)
187
+ expect(optional.child.subnodes[0]).to be_a(SymbolNode)
188
188
  expect(optional.child.subnodes[0].name).to eq('ELSE')
189
189
  expect(optional.child.subnodes[0].annotation).to eq({ 'match_closest' => 'IF' })
190
190
  expect(optional.child.subnodes[1].name).to eq('statement')
@@ -11,41 +11,41 @@ require_relative '../../../lib/rley/rgn/repetition_node'
11
11
  module Rley # Open this namespace to avoid module qualifier prefixes
12
12
  module RGN # Open this namespace to avoid module qualifier prefixes
13
13
  describe RepetitionNode do
14
+ # Default instantiation rule
15
+ subject(:rep_node) { described_class.new(a_child, star) }
16
+
14
17
  let(:a_name) { 'arguments' }
15
18
  let(:a_pos) { Lexical::Position.new(3, 4) }
16
19
  let(:a_child) { SymbolNode.new(a_pos, a_name) }
17
20
  let(:star) { :zero_or_more }
18
21
 
19
- # Default instantiation rule
20
- subject { RepetitionNode.new(a_child, star) }
21
-
22
22
  context 'Initialization:' do
23
- it 'should be created with a child node and a symbol' do
24
- expect { RepetitionNode.new(a_child, star) }.not_to raise_error
23
+ it 'is created with a child node and a symbol' do
24
+ expect { described_class.new(a_child, star) }.not_to raise_error
25
25
  end
26
26
 
27
- it 'should know its child' do
28
- expect(subject.subnodes.size).to eq(1)
29
- expect(subject.subnodes.first).to eq(a_child)
30
- expect(subject.child).to eq(a_child)
27
+ it 'knows its child' do
28
+ expect(rep_node.subnodes.size).to eq(1)
29
+ expect(rep_node.subnodes.first).to eq(a_child)
30
+ expect(rep_node.child).to eq(a_child)
31
31
  end
32
32
 
33
- it 'should know its repetition' do
34
- expect(subject.repetition).to eq(star)
33
+ it 'knows its repetition' do
34
+ expect(rep_node.repetition).to eq(star)
35
35
  end
36
36
  end # context
37
37
 
38
38
  context 'Provided services:' do
39
- it 'should know its name' do
39
+ it 'knows its name' do
40
40
  # Case repetition == :zero_or_one
41
- instance = RepetitionNode.new(a_child, :zero_or_one)
41
+ instance = described_class.new(a_child, :zero_or_one)
42
42
  expect(instance.name).to eq('rep_arguments_qmark')
43
43
 
44
44
  # Case repetition == :zero_or_more
45
- expect(subject.name).to eq('rep_arguments_star')
45
+ expect(rep_node.name).to eq('rep_arguments_star')
46
46
 
47
47
  # Case repetition == :one_or_more
48
- instance = RepetitionNode.new(a_child, :one_or_more)
48
+ instance = described_class.new(a_child, :one_or_more)
49
49
  expect(instance.name).to eq('rep_arguments_plus')
50
50
  end
51
51
  end # context
@@ -11,6 +11,9 @@ require_relative '../../../lib/rley/rgn/sequence_node'
11
11
  module Rley # Open this namespace to avoid module qualifier prefixes
12
12
  module RGN # Open this namespace to avoid module qualifier prefixes
13
13
  describe SequenceNode do
14
+ # Default instantiation rule
15
+ subject(:seq_node) { described_class.new([child1, child2, child3]) }
16
+
14
17
  let(:name1) { 'LPAR' }
15
18
  let(:name2) { 'arguments' }
16
19
  let(:name3) { 'RPAR' }
@@ -21,24 +24,21 @@ module Rley # Open this namespace to avoid module qualifier prefixes
21
24
  let(:child2) { SymbolNode.new(pos2, name2) }
22
25
  let(:child3) { SymbolNode.new(pos3, name3) }
23
26
 
24
- # Default instantiation rule
25
- subject { SequenceNode.new([child1, child2, child3]) }
26
-
27
27
  context 'Initialization:' do
28
- it 'should be created with an array of child nodes' do
28
+ it 'is created with an array of child nodes' do
29
29
  children = [child1, child2, child3]
30
- expect { SequenceNode.new(children) }.not_to raise_error
30
+ expect { described_class.new(children) }.not_to raise_error
31
31
  end
32
32
 
33
- it 'should know its subnodes' do
34
- expect(subject.subnodes.size).to eq(3)
35
- expect(subject.subnodes).to eq([child1, child2, child3])
33
+ it 'knows its subnodes' do
34
+ expect(seq_node.subnodes.size).to eq(3)
35
+ expect(seq_node.subnodes).to eq([child1, child2, child3])
36
36
  end
37
37
  end # context
38
38
 
39
39
  context 'Provided services:' do
40
- it 'should know its name' do
41
- expect(subject.name).to eq('seq_LPAR_arguments_RPAR')
40
+ it 'knows its name' do
41
+ expect(seq_node.name).to eq('seq_LPAR_arguments_RPAR')
42
42
  end
43
43
  end # context
44
44
  end # describe
@@ -7,7 +7,6 @@ require_relative '../../../lib/rley/lexical/token'
7
7
  # Load the class under test
8
8
  require_relative '../../../lib/rley/rgn/symbol_node'
9
9
 
10
-
11
10
  module Rley # Open this namespace to avoid module qualifier prefixes
12
11
  module RGN # Open this namespace to avoid module qualifier prefixes
13
12
  describe SymbolNode do
@@ -16,14 +15,14 @@ module Rley # Open this namespace to avoid module qualifier prefixes
16
15
 
17
16
  context 'Initialization:' do
18
17
  # Default instantiation rule
19
- subject { SymbolNode.new(a_pos, a_name) }
18
+ subject(:a_node) { described_class.new(a_pos, a_name) }
20
19
 
21
- it 'should be created with a name and position' do
22
- expect { SymbolNode.new(a_pos, a_name) }.not_to raise_error
20
+ it 'is created with a name and position' do
21
+ expect { described_class.new(a_pos, a_name) }.not_to raise_error
23
22
  end
24
23
 
25
- it 'should know its name' do
26
- expect(subject.name).to eq(a_name)
24
+ it 'knows its name' do
25
+ expect(a_node.name).to eq(a_name)
27
26
  end
28
27
  end # context
29
28
  end # describe