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.
- checksums.yaml +4 -4
- data/.rubocop.yml +20 -2
- data/CHANGELOG.md +3 -0
- data/examples/general/calc_iter1/spec/calculator_spec.rb +9 -9
- data/examples/general/calc_iter2/spec/calculator_spec.rb +39 -39
- data/examples/general/recursive_right.rb +2 -2
- data/lib/rley/constants.rb +1 -1
- data/lib/rley/gfg/grm_flow_graph.rb +0 -1
- data/lib/rley/parser/parse_entry_set.rb +0 -1
- data/lib/rley/parser/parse_walker_factory.rb +0 -1
- data/lib/rley/rgn/grammar_builder.rb +0 -2
- data/lib/rley/rgn/tokenizer.rb +1 -1
- data/lib/rley/syntax/base_grammar_builder.rb +0 -1
- data/lib/rley/syntax/grammar.rb +0 -1
- data/spec/rley/base/dotted_item_spec.rb +46 -46
- data/spec/rley/base/grm_items_builder_spec.rb +1 -1
- data/spec/rley/engine_spec.rb +50 -50
- data/spec/rley/formatter/asciitree_spec.rb +8 -8
- data/spec/rley/formatter/bracket_notation_spec.rb +10 -10
- data/spec/rley/formatter/debug_spec.rb +10 -10
- data/spec/rley/formatter/json_spec.rb +6 -7
- data/spec/rley/gfg/call_edge_spec.rb +6 -6
- data/spec/rley/gfg/edge_spec.rb +8 -7
- data/spec/rley/gfg/end_vertex_spec.rb +8 -7
- data/spec/rley/gfg/epsilon_edge_spec.rb +5 -4
- data/spec/rley/gfg/grm_flow_graph_spec.rb +33 -34
- data/spec/rley/gfg/item_vertex_spec.rb +34 -36
- data/spec/rley/gfg/non_terminal_vertex_spec.rb +12 -12
- data/spec/rley/gfg/return_edge_spec.rb +6 -6
- data/spec/rley/gfg/scan_edge_spec.rb +7 -6
- data/spec/rley/gfg/shortcut_edge_spec.rb +15 -15
- data/spec/rley/gfg/start_vertex_spec.rb +8 -8
- data/spec/rley/gfg/vertex_spec.rb +18 -18
- data/spec/rley/lexical/literal_spec.rb +5 -5
- data/spec/rley/lexical/token_range_spec.rb +55 -55
- data/spec/rley/lexical/token_spec.rb +17 -16
- data/spec/rley/parse_forest_visitor_spec.rb +30 -32
- data/spec/rley/parse_rep/ambiguous_parse_spec.rb +2 -2
- data/spec/rley/parse_rep/ast_builder_spec.rb +30 -30
- data/spec/rley/parse_rep/cst_builder_spec.rb +85 -85
- data/spec/rley/parse_rep/groucho_spec.rb +23 -23
- data/spec/rley/parse_rep/parse_forest_builder_spec.rb +42 -42
- data/spec/rley/parse_rep/parse_forest_factory_spec.rb +10 -12
- data/spec/rley/parse_rep/parse_tree_factory_spec.rb +10 -15
- data/spec/rley/parse_tree_visitor_spec.rb +43 -46
- data/spec/rley/parser/dangling_else_spec.rb +12 -12
- data/spec/rley/parser/error_reason_spec.rb +37 -37
- data/spec/rley/parser/gfg_chart_spec.rb +27 -29
- data/spec/rley/parser/gfg_earley_parser_spec.rb +55 -56
- data/spec/rley/parser/gfg_parsing_spec.rb +106 -103
- data/spec/rley/parser/parse_entry_set_spec.rb +63 -61
- data/spec/rley/parser/parse_entry_spec.rb +73 -71
- data/spec/rley/parser/parse_walker_factory_spec.rb +14 -15
- data/spec/rley/ptree/non_terminal_node_spec.rb +16 -16
- data/spec/rley/ptree/parse_tree_node_spec.rb +11 -11
- data/spec/rley/ptree/parse_tree_spec.rb +6 -8
- data/spec/rley/ptree/terminal_node_spec.rb +6 -6
- data/spec/rley/rgn/grammar_builder_spec.rb +69 -67
- data/spec/rley/rgn/parser_spec.rb +63 -63
- data/spec/rley/rgn/repetition_node_spec.rb +15 -15
- data/spec/rley/rgn/sequence_node_spec.rb +10 -10
- data/spec/rley/rgn/symbol_node_spec.rb +5 -6
- data/spec/rley/rgn/tokenizer_spec.rb +68 -67
- data/spec/rley/sppf/alternative_node_spec.rb +16 -16
- data/spec/rley/sppf/non_terminal_node_spec.rb +20 -20
- data/spec/rley/sppf/token_node_spec.rb +13 -13
- data/spec/rley/syntax/base_grammar_builder_spec.rb +76 -86
- data/spec/rley/syntax/grammar_spec.rb +40 -78
- data/spec/rley/syntax/grm_symbol_spec.rb +7 -7
- data/spec/rley/syntax/match_closest_spec.rb +8 -8
- data/spec/rley/syntax/non_terminal_spec.rb +25 -25
- data/spec/rley/syntax/production_spec.rb +33 -33
- data/spec/rley/syntax/symbol_seq_spec.rb +27 -27
- data/spec/rley/syntax/terminal_spec.rb +12 -11
- data/spec/support/base_tokenizer_spec.rb +9 -8
- metadata +2 -2
@@ -20,27 +20,28 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
+
subject(:a_tokenizer) { described_class.new }
|
24
|
+
|
23
25
|
context 'Initialization:' do
|
24
26
|
let(:sample_text) { 'begin-object member-list end-object' }
|
25
|
-
subject { Tokenizer.new }
|
26
27
|
|
27
|
-
it '
|
28
|
-
expect {
|
28
|
+
it 'is initialized with a text to tokenize or...' do
|
29
|
+
expect { described_class.new(sample_text) }.not_to raise_error
|
29
30
|
end
|
30
31
|
|
31
|
-
it '
|
32
|
-
expect {
|
32
|
+
it 'is initialized without argument...' do
|
33
|
+
expect { described_class.new }.not_to raise_error
|
33
34
|
end
|
34
35
|
|
35
|
-
it '
|
36
|
-
expect(
|
36
|
+
it 'has its scanner initialized' do
|
37
|
+
expect(a_tokenizer.scanner).to be_a(StringScanner)
|
37
38
|
end
|
38
39
|
end # context
|
39
40
|
|
40
41
|
context 'Input tokenization:' do
|
41
|
-
it '
|
42
|
+
it 'recognizes single special character token' do
|
42
43
|
input = '(){}?*+,'
|
43
|
-
|
44
|
+
a_tokenizer.start_with(input)
|
44
45
|
expectations = [
|
45
46
|
# [token lexeme]
|
46
47
|
%w[LEFT_PAREN (],
|
@@ -52,22 +53,22 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
52
53
|
%w[PLUS +],
|
53
54
|
%w[COMMA ,]
|
54
55
|
]
|
55
|
-
match_expectations(
|
56
|
+
match_expectations(a_tokenizer, expectations)
|
56
57
|
end
|
57
58
|
|
58
|
-
it '
|
59
|
+
it 'recognizes one or two special character tokens' do
|
59
60
|
input = '..'
|
60
|
-
|
61
|
+
a_tokenizer.start_with(input)
|
61
62
|
expectations = [
|
62
63
|
# [token lexeme]
|
63
64
|
%w[ELLIPSIS ..]
|
64
65
|
]
|
65
|
-
match_expectations(
|
66
|
+
match_expectations(a_tokenizer, expectations)
|
66
67
|
end
|
67
68
|
|
68
|
-
it '
|
69
|
+
it 'treats ? * + as symbols if they occur as suffix' do
|
69
70
|
input = 'a+ + b* * 3 ?'
|
70
|
-
|
71
|
+
a_tokenizer.start_with(input)
|
71
72
|
expectations = [
|
72
73
|
# [token lexeme]
|
73
74
|
%w[SYMBOL a],
|
@@ -79,21 +80,21 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
79
80
|
%w[INT_LIT 3],
|
80
81
|
%w[SYMBOL ?]
|
81
82
|
]
|
82
|
-
match_expectations(
|
83
|
+
match_expectations(a_tokenizer, expectations)
|
83
84
|
end
|
84
85
|
|
85
|
-
it '
|
86
|
+
it 'recognizes annotation keywords' do
|
86
87
|
keywords = 'match_closest: repeat:'
|
87
|
-
|
88
|
+
a_tokenizer.start_with(keywords)
|
88
89
|
expectations = [
|
89
90
|
# [token lexeme]
|
90
91
|
%w[KEY match_closest],
|
91
92
|
%w[KEY repeat]
|
92
93
|
]
|
93
|
-
match_expectations(
|
94
|
+
match_expectations(a_tokenizer, expectations)
|
94
95
|
end
|
95
96
|
|
96
|
-
it '
|
97
|
+
it 'recognizes ordinal integer values' do
|
97
98
|
input = <<-RLEY_END
|
98
99
|
3 123
|
99
100
|
987654 0
|
@@ -106,16 +107,16 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
106
107
|
['0', 0]
|
107
108
|
]
|
108
109
|
|
109
|
-
|
110
|
-
|
111
|
-
expect(tok).to
|
110
|
+
a_tokenizer.start_with(input)
|
111
|
+
a_tokenizer.tokens[0..-2].each_with_index do |tok, i|
|
112
|
+
expect(tok).to be_a(Rley::Lexical::Token)
|
112
113
|
expect(tok.terminal).to eq('INT_LIT')
|
113
114
|
(lexeme,) = expectations[i]
|
114
115
|
expect(tok.lexeme).to eq(lexeme)
|
115
116
|
end
|
116
117
|
end
|
117
118
|
|
118
|
-
it '
|
119
|
+
it 'recognizes string literals' do
|
119
120
|
input = <<-RLEY_END
|
120
121
|
""
|
121
122
|
"string"
|
@@ -131,29 +132,29 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
131
132
|
'123'
|
132
133
|
] * 2
|
133
134
|
|
134
|
-
|
135
|
-
|
136
|
-
expect(str).to
|
135
|
+
a_tokenizer.start_with(input)
|
136
|
+
a_tokenizer.tokens.each_with_index do |str, i|
|
137
|
+
expect(str).to be_a(Rley::Lexical::Token)
|
137
138
|
expect(str.terminal).to eq('STR_LIT')
|
138
139
|
(lexeme,) = expectations[i]
|
139
140
|
expect(str.lexeme).to eq(lexeme)
|
140
141
|
end
|
141
142
|
end
|
142
143
|
|
143
|
-
it '
|
144
|
+
it 'recognizes a sequence of symbols' do
|
144
145
|
input = 'IF ifCondition statement ELSE statement'
|
145
146
|
expectations = %w[IF ifCondition statement ELSE statement]
|
146
147
|
|
147
|
-
|
148
|
-
|
149
|
-
expect(str).to
|
148
|
+
a_tokenizer.start_with(input)
|
149
|
+
a_tokenizer.tokens.each_with_index do |str, i|
|
150
|
+
expect(str).to be_a(Rley::Lexical::Token)
|
150
151
|
expect(str.terminal).to eq('SYMBOL')
|
151
152
|
(lexeme,) = expectations[i]
|
152
153
|
expect(str.lexeme).to eq(lexeme)
|
153
154
|
end
|
154
155
|
end
|
155
156
|
|
156
|
-
it '
|
157
|
+
it 'recognizes an optional symbol' do
|
157
158
|
input = 'RETURN expression? SEMICOLON'
|
158
159
|
expectations = [
|
159
160
|
%w[RETURN SYMBOL],
|
@@ -162,16 +163,16 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
162
163
|
%w[SEMICOLON SYMBOL]
|
163
164
|
]
|
164
165
|
|
165
|
-
|
166
|
-
|
167
|
-
expect(str).to
|
166
|
+
a_tokenizer.start_with(input)
|
167
|
+
a_tokenizer.tokens.each_with_index do |str, i|
|
168
|
+
expect(str).to be_a(Rley::Lexical::Token)
|
168
169
|
(lexeme, token) = expectations[i]
|
169
170
|
expect(str.lexeme).to eq(lexeme)
|
170
171
|
expect(str.terminal).to eq(token)
|
171
172
|
end
|
172
173
|
end
|
173
174
|
|
174
|
-
it '
|
175
|
+
it 'recognizes a symbol with a star quantifier' do
|
175
176
|
input = 'declaration* EOF'
|
176
177
|
expectations = [
|
177
178
|
%w[declaration SYMBOL],
|
@@ -179,16 +180,16 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
179
180
|
%w[EOF SYMBOL]
|
180
181
|
]
|
181
182
|
|
182
|
-
|
183
|
-
|
184
|
-
expect(str).to
|
183
|
+
a_tokenizer.start_with(input)
|
184
|
+
a_tokenizer.tokens.each_with_index do |str, i|
|
185
|
+
expect(str).to be_a(Rley::Lexical::Token)
|
185
186
|
(lexeme, token) = expectations[i]
|
186
187
|
expect(str.lexeme).to eq(lexeme)
|
187
188
|
expect(str.terminal).to eq(token)
|
188
189
|
end
|
189
190
|
end
|
190
191
|
|
191
|
-
it '
|
192
|
+
it 'recognizes a symbol with a plus quantifier' do
|
192
193
|
input = 'declaration+ EOF'
|
193
194
|
expectations = [
|
194
195
|
%w[declaration SYMBOL],
|
@@ -196,16 +197,16 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
196
197
|
%w[EOF SYMBOL]
|
197
198
|
]
|
198
199
|
|
199
|
-
|
200
|
-
|
201
|
-
expect(str).to
|
200
|
+
a_tokenizer.start_with(input)
|
201
|
+
a_tokenizer.tokens.each_with_index do |str, i|
|
202
|
+
expect(str).to be_a(Rley::Lexical::Token)
|
202
203
|
(lexeme, token) = expectations[i]
|
203
204
|
expect(str.lexeme).to eq(lexeme)
|
204
205
|
expect(str.terminal).to eq(token)
|
205
206
|
end
|
206
207
|
end
|
207
208
|
|
208
|
-
it '
|
209
|
+
it 'recognizes a grouping with a quantifier' do
|
209
210
|
input = 'IF ifCondition statement (ELSE statement)?'
|
210
211
|
expectations = [
|
211
212
|
%w[IF SYMBOL],
|
@@ -218,16 +219,16 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
218
219
|
%w[? QUESTION_MARK]
|
219
220
|
]
|
220
221
|
|
221
|
-
|
222
|
-
|
223
|
-
expect(str).to
|
222
|
+
a_tokenizer.start_with(input)
|
223
|
+
a_tokenizer.tokens.each_with_index do |str, i|
|
224
|
+
expect(str).to be_a(Rley::Lexical::Token)
|
224
225
|
(lexeme, token) = expectations[i]
|
225
226
|
expect(str.lexeme).to eq(lexeme)
|
226
227
|
expect(str.terminal).to eq(token)
|
227
228
|
end
|
228
229
|
end
|
229
230
|
|
230
|
-
it '
|
231
|
+
it 'recognizes a match closest constraint' do
|
231
232
|
input = "IF ifCondition statement ELSE { match_closest: 'IF' } statement"
|
232
233
|
expectations = [
|
233
234
|
%w[IF SYMBOL],
|
@@ -241,16 +242,16 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
241
242
|
%w[statement SYMBOL]
|
242
243
|
]
|
243
244
|
|
244
|
-
|
245
|
-
|
246
|
-
expect(str).to
|
245
|
+
a_tokenizer.start_with(input)
|
246
|
+
a_tokenizer.tokens.each_with_index do |str, i|
|
247
|
+
expect(str).to be_a(Rley::Lexical::Token)
|
247
248
|
(lexeme, token) = expectations[i]
|
248
249
|
expect(str.lexeme).to eq(lexeme)
|
249
250
|
expect(str.terminal).to eq(token)
|
250
251
|
end
|
251
252
|
end
|
252
253
|
|
253
|
-
it '
|
254
|
+
it 'recognizes a repeat constraint' do
|
254
255
|
input = 'IF ifCondition statement { repeat: 1 } ELSE statement'
|
255
256
|
expectations = [
|
256
257
|
%w[IF SYMBOL],
|
@@ -264,16 +265,16 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
264
265
|
%w[statement SYMBOL]
|
265
266
|
]
|
266
267
|
|
267
|
-
|
268
|
-
|
269
|
-
expect(str).to
|
268
|
+
a_tokenizer.start_with(input)
|
269
|
+
a_tokenizer.tokens.each_with_index do |str, i|
|
270
|
+
expect(str).to be_a(Rley::Lexical::Token)
|
270
271
|
(lexeme, token) = expectations[i]
|
271
272
|
expect(str.lexeme).to eq(lexeme)
|
272
273
|
expect(str.terminal).to eq(token)
|
273
274
|
end
|
274
275
|
end
|
275
276
|
|
276
|
-
it '
|
277
|
+
it 'recognizes a grouping with a repeat constraint' do
|
277
278
|
input = 'IF ifCondition statement ( ELSE statement ){ repeat: 0..1 }'
|
278
279
|
expectations = [
|
279
280
|
%w[IF SYMBOL],
|
@@ -291,16 +292,16 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
291
292
|
%w[} RIGHT_BRACE]
|
292
293
|
]
|
293
294
|
|
294
|
-
|
295
|
-
|
296
|
-
expect(str).to
|
295
|
+
a_tokenizer.start_with(input)
|
296
|
+
a_tokenizer.tokens.each_with_index do |str, i|
|
297
|
+
expect(str).to be_a(Rley::Lexical::Token)
|
297
298
|
(lexeme, token) = expectations[i]
|
298
299
|
expect(str.lexeme).to eq(lexeme)
|
299
300
|
expect(str.terminal).to eq(token)
|
300
301
|
end
|
301
302
|
end
|
302
303
|
|
303
|
-
it '
|
304
|
+
it 'recognizes a combination of constraints' do
|
304
305
|
input = "IF ifCondition statement ELSE { repeat: 1, match_closest: 'IF' } statement"
|
305
306
|
expectations = [
|
306
307
|
%w[IF SYMBOL],
|
@@ -317,16 +318,16 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
317
318
|
%w[statement SYMBOL]
|
318
319
|
]
|
319
320
|
|
320
|
-
|
321
|
-
|
322
|
-
expect(str).to
|
321
|
+
a_tokenizer.start_with(input)
|
322
|
+
a_tokenizer.tokens.each_with_index do |str, i|
|
323
|
+
expect(str).to be_a(Rley::Lexical::Token)
|
323
324
|
(lexeme, token) = expectations[i]
|
324
325
|
expect(str.lexeme).to eq(lexeme)
|
325
326
|
expect(str.terminal).to eq(token)
|
326
327
|
end
|
327
328
|
end
|
328
329
|
|
329
|
-
it '
|
330
|
+
it 'recognizes a grouping with a nested constraint' do
|
330
331
|
input = "IF ifCondition statement ( ELSE { match_closest: 'IF' } statement ){ repeat: 0..1 }"
|
331
332
|
expectations = [
|
332
333
|
%w[IF SYMBOL],
|
@@ -348,9 +349,9 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
348
349
|
%w[} RIGHT_BRACE]
|
349
350
|
]
|
350
351
|
|
351
|
-
|
352
|
-
|
353
|
-
expect(str).to
|
352
|
+
a_tokenizer.start_with(input)
|
353
|
+
a_tokenizer.tokens.each_with_index do |str, i|
|
354
|
+
expect(str).to be_a(Rley::Lexical::Token)
|
354
355
|
(lexeme, token) = expectations[i]
|
355
356
|
expect(str.lexeme).to eq(lexeme)
|
356
357
|
expect(str.terminal).to eq(token)
|
@@ -20,6 +20,8 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
20
20
|
return Lexical::TokenRange.new(low: low, high: high)
|
21
21
|
end
|
22
22
|
|
23
|
+
subject(:alt_node) { described_class.new(sample_vertex, sample_range) }
|
24
|
+
|
23
25
|
let(:t_a) { Syntax::Terminal.new('A') }
|
24
26
|
let(:t_b) { Syntax::Terminal.new('B') }
|
25
27
|
let(:t_c) { Syntax::Terminal.new('C') }
|
@@ -31,40 +33,38 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
31
33
|
let(:sample_vertex) { GFG::ItemVertex.new(sample_item) }
|
32
34
|
let(:sample_range) { range(0, 3) }
|
33
35
|
|
34
|
-
subject { AlternativeNode.new(sample_vertex, sample_range) }
|
35
|
-
|
36
36
|
context 'Construction:' do
|
37
|
-
it '
|
38
|
-
expect {
|
37
|
+
it 'is created with a item vertex and a token range' do
|
38
|
+
expect { described_class.new(sample_vertex, sample_range) }
|
39
39
|
.not_to raise_error
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
43
|
context 'Initialization:' do
|
44
|
-
it '
|
45
|
-
expect(
|
46
|
-
expect(
|
44
|
+
it 'knows its token range' do
|
45
|
+
expect(alt_node.range).to eq(sample_range)
|
46
|
+
expect(alt_node.origin).to eq(sample_range.low)
|
47
47
|
end
|
48
48
|
|
49
|
-
it "
|
50
|
-
expect(
|
49
|
+
it "doesn't have children yet" do
|
50
|
+
expect(alt_node.subnodes).to be_empty
|
51
51
|
end
|
52
52
|
end # context
|
53
53
|
|
54
54
|
context 'Provided services:' do
|
55
|
-
it '
|
55
|
+
it 'accepts the addition of subnodes' do
|
56
56
|
subnode1 = double('first_subnode')
|
57
57
|
subnode2 = double('second_subnode')
|
58
58
|
subnode3 = double('third_subnode')
|
59
|
-
expect {
|
60
|
-
|
61
|
-
|
62
|
-
expect(
|
59
|
+
expect { alt_node.add_subnode(subnode1) }.not_to raise_error
|
60
|
+
alt_node.add_subnode(subnode2)
|
61
|
+
alt_node.add_subnode(subnode3)
|
62
|
+
expect(alt_node.subnodes).to eq([subnode3, subnode2, subnode1])
|
63
63
|
end
|
64
64
|
|
65
65
|
|
66
|
-
it '
|
67
|
-
expect(
|
66
|
+
it 'has a string representation' do
|
67
|
+
expect(alt_node.to_string(0)).to eq('Alt(sentence => A B C .)[0, 3]')
|
68
68
|
end
|
69
69
|
end # context
|
70
70
|
end # describe
|
@@ -17,49 +17,49 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
17
17
|
return Lexical::TokenRange.new(low: low, high: high)
|
18
18
|
end
|
19
19
|
|
20
|
+
subject(:a_node) { described_class.new(sample_symbol, sample_range) }
|
21
|
+
|
20
22
|
let(:sample_symbol) do
|
21
23
|
Syntax::NonTerminal.new('VP')
|
22
24
|
end
|
23
25
|
let(:sample_range) { range(0, 3) }
|
24
26
|
|
25
|
-
subject { NonTerminalNode.new(sample_symbol, sample_range) }
|
26
|
-
|
27
27
|
context 'Initialization:' do
|
28
|
-
it '
|
29
|
-
expect(
|
28
|
+
it 'knows its non-terminal symbol' do
|
29
|
+
expect(a_node.symbol).to eq(sample_symbol)
|
30
30
|
end
|
31
31
|
|
32
|
-
it '
|
33
|
-
expect(
|
34
|
-
expect(
|
32
|
+
it 'knows its token range' do
|
33
|
+
expect(a_node.range).to eq(sample_range)
|
34
|
+
expect(a_node.origin).to eq(sample_range.low)
|
35
35
|
end
|
36
36
|
|
37
|
-
it "
|
38
|
-
expect(
|
37
|
+
it "doesn't have children yet" do
|
38
|
+
expect(a_node.subnodes).to be_empty
|
39
39
|
end
|
40
40
|
|
41
|
-
it '
|
42
|
-
expect(
|
41
|
+
it 'has :and refinement' do
|
42
|
+
expect(a_node.refinement).to eq(:and)
|
43
43
|
end
|
44
44
|
end # context
|
45
45
|
|
46
46
|
context 'Provided services:' do
|
47
|
-
it '
|
47
|
+
it 'accepts the addition of subnodes' do
|
48
48
|
subnode1 = double('first_subnode')
|
49
49
|
subnode2 = double('second_subnode')
|
50
50
|
subnode3 = double('third_subnode')
|
51
|
-
expect {
|
52
|
-
|
53
|
-
|
54
|
-
expect(
|
51
|
+
expect { a_node.add_subnode(subnode1) }.not_to raise_error
|
52
|
+
a_node.add_subnode(subnode2)
|
53
|
+
a_node.add_subnode(subnode3)
|
54
|
+
expect(a_node.subnodes).to eq([subnode3, subnode2, subnode1])
|
55
55
|
end
|
56
56
|
|
57
|
-
it '
|
58
|
-
expect(
|
57
|
+
it 'has a string representation' do
|
58
|
+
expect(a_node.to_string(0)).to eq('VP[0, 3]')
|
59
59
|
end
|
60
60
|
|
61
|
-
it '
|
62
|
-
expect(
|
61
|
+
it 'returns a key value of itself' do
|
62
|
+
expect(a_node.key).to eq('VP[0, 3]')
|
63
63
|
end
|
64
64
|
end # context
|
65
65
|
end # describe
|
@@ -13,6 +13,8 @@ require_relative '../../../lib/rley/sppf/token_node'
|
|
13
13
|
module Rley # Open this namespace to avoid module qualifier prefixes
|
14
14
|
module SPPF # Open this namespace to avoid module qualifier prefixes
|
15
15
|
describe TokenNode do
|
16
|
+
subject(:a_node) { described_class.new(sample_token, sample_rank) }
|
17
|
+
|
16
18
|
let(:sample_symbol) { Syntax::Terminal.new('Noun') }
|
17
19
|
let(:sample_position) { Lexical::Position.new(3, 4) }
|
18
20
|
let(:sample_token) do
|
@@ -20,28 +22,26 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
20
22
|
end
|
21
23
|
let(:sample_rank) { 3 }
|
22
24
|
|
23
|
-
subject { TokenNode.new(sample_token, sample_rank) }
|
24
|
-
|
25
25
|
context 'Initialization:' do
|
26
|
-
it '
|
27
|
-
expect(
|
26
|
+
it 'knows its token' do
|
27
|
+
expect(a_node.token).to eq(sample_token)
|
28
28
|
end
|
29
29
|
|
30
|
-
it '
|
31
|
-
expect(
|
32
|
-
expect(
|
33
|
-
expect(
|
30
|
+
it 'knows its token range' do
|
31
|
+
expect(a_node.origin).to eq(sample_rank)
|
32
|
+
expect(a_node.range.low).to eq(sample_rank)
|
33
|
+
expect(a_node.range.high).to eq(sample_rank + 1)
|
34
34
|
end
|
35
35
|
end # context
|
36
36
|
|
37
37
|
context 'Provided services:' do
|
38
|
-
it '
|
39
|
-
expect(
|
40
|
-
expect(
|
38
|
+
it 'knows its string representation' do
|
39
|
+
expect(a_node.to_string(0)).to eq('Noun[3, 4]')
|
40
|
+
expect(a_node.inspect).to eq('Noun[3, 4]')
|
41
41
|
end
|
42
42
|
|
43
|
-
it '
|
44
|
-
expect(
|
43
|
+
it 'returns a key value of itself' do
|
44
|
+
expect(a_node.key).to eq('Noun[3, 4]')
|
45
45
|
end
|
46
46
|
end # context
|
47
47
|
end # describe
|