sequitur 0.1.03 → 0.1.05
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/CHANGELOG.md +6 -0
- data/README.md +1 -0
- data/lib/sequitur.rb +5 -5
- data/lib/sequitur/constants.rb +5 -5
- data/lib/sequitur/digram.rb +13 -6
- data/lib/sequitur/dynamic_grammar.rb +32 -38
- data/lib/sequitur/formatter/base_formatter.rb +5 -1
- data/lib/sequitur/formatter/base_text.rb +37 -11
- data/lib/sequitur/formatter/debug.rb +50 -1
- data/lib/sequitur/grammar_visitor.rb +41 -23
- data/lib/sequitur/production.rb +55 -30
- data/lib/sequitur/production_ref.rb +45 -21
- data/lib/sequitur/sequitur_grammar.rb +22 -17
- data/spec/sequitur/dynamic_grammar_spec.rb +6 -15
- data/spec/sequitur/production_spec.rb +10 -10
- data/spec/sequitur/sequitur_grammar_spec.rb +30 -14
- metadata +2 -2
@@ -26,8 +26,8 @@ describe DynamicGrammar do
|
|
26
26
|
expect { DynamicGrammar.new }.not_to raise_error
|
27
27
|
end
|
28
28
|
|
29
|
-
it 'should have an empty
|
30
|
-
expect(subject.
|
29
|
+
it 'should have an empty start/start production' do
|
30
|
+
expect(subject.start).to be_empty
|
31
31
|
expect(subject.productions.size).to eq(1)
|
32
32
|
expect(subject.productions.first).to be_empty
|
33
33
|
end
|
@@ -60,15 +60,6 @@ describe DynamicGrammar do
|
|
60
60
|
expect(subject.productions.last).to eq(p_bc)
|
61
61
|
end
|
62
62
|
|
63
|
-
it 'should complain when rhs refers to unknown production' do
|
64
|
-
subject.add_production(p_a)
|
65
|
-
subject.add_production(p_b)
|
66
|
-
# Test fails because of Production#references
|
67
|
-
msg = "Production #{p_bc.object_id} refers to production #{p_c.object_id}"
|
68
|
-
msg << ' that is not part of the grammar.'
|
69
|
-
expect { subject.add_production(p_bc) }.to raise_error(StandardError, msg)
|
70
|
-
|
71
|
-
end
|
72
63
|
end # context
|
73
64
|
|
74
65
|
|
@@ -117,10 +108,10 @@ describe DynamicGrammar do
|
|
117
108
|
a_visitor.subscribe(fake_formatter)
|
118
109
|
|
119
110
|
expect(fake_formatter).to receive(:before_grammar).with(subject).ordered
|
120
|
-
expect(fake_formatter).to receive(:before_production).with(subject.
|
111
|
+
expect(fake_formatter).to receive(:before_production).with(subject.start)
|
121
112
|
expect(fake_formatter).to receive(:before_rhs).with([]).ordered
|
122
113
|
expect(fake_formatter).to receive(:after_rhs).with([]).ordered
|
123
|
-
expect(fake_formatter).to receive(:after_production).with(subject.
|
114
|
+
expect(fake_formatter).to receive(:after_production).with(subject.start)
|
124
115
|
expect(fake_formatter).to receive(:before_production).with(p_a)
|
125
116
|
expect(fake_formatter).to receive(:before_rhs).with(p_a.rhs)
|
126
117
|
expect(fake_formatter).to receive(:after_rhs).with(p_a.rhs)
|
@@ -146,13 +137,13 @@ describe DynamicGrammar do
|
|
146
137
|
context 'Generating a text representation of itself:' do
|
147
138
|
|
148
139
|
it 'should generate a text representation when empty' do
|
149
|
-
expectation = "#{subject.
|
140
|
+
expectation = "#{subject.start.object_id} : ."
|
150
141
|
expect(subject.to_string).to eq(expectation)
|
151
142
|
end
|
152
143
|
|
153
144
|
# it 'should generate a text representation of a simple production' do
|
154
145
|
# instance = SequiturGrammar.new([:a].to_enum)
|
155
|
-
# expectation = "#{instance.
|
146
|
+
# expectation = "#{instance.start.object_id} : a."
|
156
147
|
# expect(instance.to_string).to eq(expectation)
|
157
148
|
# end
|
158
149
|
|
@@ -229,7 +229,7 @@ describe Production do
|
|
229
229
|
context 'Replacing a digram by a production:' do
|
230
230
|
|
231
231
|
it 'should have not effect on empty production' do
|
232
|
-
subject.
|
232
|
+
subject.reduce_step(p_bc)
|
233
233
|
expect(subject.rhs).to be_empty
|
234
234
|
expect(p_bc.refcount).to eq(0)
|
235
235
|
end
|
@@ -238,7 +238,7 @@ describe Production do
|
|
238
238
|
it 'should replace two-symbol sequence' do
|
239
239
|
%w(a b c d e b c e).each { |symb| subject.append_symbol(symb) }
|
240
240
|
p_bc_before = p_bc.to_string
|
241
|
-
subject.
|
241
|
+
subject.reduce_step(p_bc)
|
242
242
|
|
243
243
|
expect(subject.rhs.size).to eq(6)
|
244
244
|
expect(subject.rhs).to eq(['a', p_bc, 'd', 'e', p_bc, 'e'])
|
@@ -249,7 +249,7 @@ describe Production do
|
|
249
249
|
|
250
250
|
it 'should replace a starting two-symbol sequence' do
|
251
251
|
%w(b c d e b c e).each { |symb| subject.append_symbol(symb) }
|
252
|
-
subject.
|
252
|
+
subject.reduce_step(p_bc)
|
253
253
|
|
254
254
|
expect(subject.rhs.size).to eq(5)
|
255
255
|
expect(subject.rhs).to eq([p_bc, 'd', 'e', p_bc, 'e'])
|
@@ -259,7 +259,7 @@ describe Production do
|
|
259
259
|
|
260
260
|
it 'should replace an ending two-symbol sequence' do
|
261
261
|
%w(a b c d e b c).each { |symb| subject.append_symbol(symb) }
|
262
|
-
subject.
|
262
|
+
subject.reduce_step(p_bc)
|
263
263
|
|
264
264
|
expect(subject.rhs.size).to eq(5)
|
265
265
|
expect(subject.rhs).to eq(['a', p_bc, 'd', 'e', p_bc])
|
@@ -268,7 +268,7 @@ describe Production do
|
|
268
268
|
|
269
269
|
it 'should replace two consecutive two-symbol sequences' do
|
270
270
|
%w(a b c b c d).each { |symb| subject.append_symbol(symb) }
|
271
|
-
subject.
|
271
|
+
subject.reduce_step(p_bc)
|
272
272
|
|
273
273
|
expect(subject.rhs.size).to eq(4)
|
274
274
|
expect(subject.rhs).to eq(['a', p_bc, p_bc, 'd'])
|
@@ -280,7 +280,7 @@ describe Production do
|
|
280
280
|
context 'Replacing a production occurrence by its rhs:' do
|
281
281
|
|
282
282
|
it 'should have not effect on empty production' do
|
283
|
-
subject.
|
283
|
+
subject.derive_step(p_bc)
|
284
284
|
expect(subject.rhs).to be_empty
|
285
285
|
end
|
286
286
|
|
@@ -288,7 +288,7 @@ describe Production do
|
|
288
288
|
[p_bc, 'd'].each { |symb| subject.append_symbol(symb) }
|
289
289
|
expect(p_bc.refcount).to eq(1)
|
290
290
|
|
291
|
-
subject.
|
291
|
+
subject.derive_step(p_bc)
|
292
292
|
expect(subject.rhs.size).to eq(3)
|
293
293
|
expect(subject.rhs).to eq(%w(b c d))
|
294
294
|
expect(p_bc.refcount).to eq(0)
|
@@ -298,7 +298,7 @@ describe Production do
|
|
298
298
|
it 'should replace a production at the end' do
|
299
299
|
['d', p_bc].each { |symb| subject.append_symbol(symb) }
|
300
300
|
expect(p_bc.refcount).to eq(1)
|
301
|
-
subject.
|
301
|
+
subject.derive_step(p_bc)
|
302
302
|
|
303
303
|
expect(subject.rhs.size).to eq(3)
|
304
304
|
expect(subject.rhs).to eq(%w(d b c))
|
@@ -307,7 +307,7 @@ describe Production do
|
|
307
307
|
|
308
308
|
it 'should replace a production as sole symbol' do
|
309
309
|
subject.append_symbol(p_bc)
|
310
|
-
subject.
|
310
|
+
subject.derive_step(p_bc)
|
311
311
|
|
312
312
|
expect(subject.rhs.size).to eq(2)
|
313
313
|
expect(subject.rhs).to eq(%w(b c))
|
@@ -315,7 +315,7 @@ describe Production do
|
|
315
315
|
|
316
316
|
it 'should replace a production in the middle' do
|
317
317
|
['a', p_bc, 'd'].each { |symb| subject.append_symbol(symb) }
|
318
|
-
subject.
|
318
|
+
subject.derive_step(p_bc)
|
319
319
|
|
320
320
|
expect(subject.rhs.size).to eq(4)
|
321
321
|
expect(subject.rhs).to eq(%w(a b c d))
|
@@ -22,8 +22,8 @@ describe SequiturGrammar do
|
|
22
22
|
|
23
23
|
# Initialization
|
24
24
|
expect(instance.productions.size).to eq(1)
|
25
|
-
expect(instance.
|
26
|
-
expect(instance.
|
25
|
+
expect(instance.start).to eq(instance.productions.first)
|
26
|
+
expect(instance.start).to be_empty
|
27
27
|
end
|
28
28
|
|
29
29
|
it 'could be created with single token' do
|
@@ -32,8 +32,8 @@ describe SequiturGrammar do
|
|
32
32
|
|
33
33
|
# Initialization
|
34
34
|
expect(instance.productions.size).to eq(1)
|
35
|
-
expect(instance.
|
36
|
-
expect(instance.
|
35
|
+
expect(instance.start).to eq(instance.productions.first)
|
36
|
+
expect(instance.start.rhs).to eq([:a])
|
37
37
|
end
|
38
38
|
|
39
39
|
it 'could be created with multiple unique tokens' do
|
@@ -42,8 +42,8 @@ describe SequiturGrammar do
|
|
42
42
|
|
43
43
|
# Initialization
|
44
44
|
expect(instance.productions.size).to eq(1)
|
45
|
-
expect(instance.
|
46
|
-
expect(instance.
|
45
|
+
expect(instance.start).to eq(instance.productions.first)
|
46
|
+
expect(instance.start.rhs).to eq([:a, :b, :c, :d])
|
47
47
|
end
|
48
48
|
|
49
49
|
it 'could be created with a repeating digram' do
|
@@ -55,7 +55,7 @@ describe SequiturGrammar do
|
|
55
55
|
expect(instance.productions.size).to eq(2)
|
56
56
|
p_a = instance.productions[1]
|
57
57
|
expect(p_a.rhs).to eq([:a, :b])
|
58
|
-
expect(instance.
|
58
|
+
expect(instance.start.rhs).to eq([p_a, p_a])
|
59
59
|
end
|
60
60
|
|
61
61
|
it 'should enforce the utility rule' do
|
@@ -72,7 +72,7 @@ describe SequiturGrammar do
|
|
72
72
|
expect(instance.productions.size).to eq(2)
|
73
73
|
p_a = instance.productions.last
|
74
74
|
expect(p_a.rhs).to eq([:a, :b, :c])
|
75
|
-
expect(instance.
|
75
|
+
expect(instance.start.rhs).to eq([p_a, p_a])
|
76
76
|
end
|
77
77
|
|
78
78
|
it 'should cope with a pattern that caused an exception' do
|
@@ -96,7 +96,7 @@ describe SequiturGrammar do
|
|
96
96
|
# P3: b P2 e
|
97
97
|
expect(instance.productions.size).to eq(4)
|
98
98
|
(p1, p2, p3) = instance.productions[1..3]
|
99
|
-
expect(instance.
|
99
|
+
expect(instance.start.rhs).to eq([p3, p2, p3])
|
100
100
|
expect(p1.rhs).to eq(%w(b e))
|
101
101
|
expect(p2.rhs).to eq([p1, p1])
|
102
102
|
expect(p3.rhs).to eq(['b', p2, 'e'])
|
@@ -113,7 +113,7 @@ describe SequiturGrammar do
|
|
113
113
|
|
114
114
|
expect(instance.productions.size).to eq(3)
|
115
115
|
(p1, p2) = instance.productions[1..2]
|
116
|
-
expect(instance.
|
116
|
+
expect(instance.start.rhs).to eq([p2, p2])
|
117
117
|
expect(p1.rhs).to eq(%w(a b))
|
118
118
|
expect(p2.rhs).to eq([p1, 'c', p1, 'd'])
|
119
119
|
end
|
@@ -129,7 +129,7 @@ describe SequiturGrammar do
|
|
129
129
|
|
130
130
|
expect(instance.productions.size).to eq(3)
|
131
131
|
(p_a, p_c) = instance.productions[1..2]
|
132
|
-
expect(instance.
|
132
|
+
expect(instance.start.rhs).to eq([p_c, p_c])
|
133
133
|
expect(p_a.rhs).to eq(%w(b c))
|
134
134
|
expect(p_c.rhs).to eq(['a', p_a, 'd', p_a])
|
135
135
|
end
|
@@ -165,7 +165,7 @@ SNIPPET
|
|
165
165
|
|
166
166
|
instance = SequiturGrammar.new(input.chars)
|
167
167
|
expect(instance.productions.size).to eq(13)
|
168
|
-
p0 = instance.
|
168
|
+
p0 = instance.start
|
169
169
|
expect(p0.rhs.size).to eq(13)
|
170
170
|
|
171
171
|
(p1, p2, p3, p4, p5, p6, p7, p8, p9) = instance.productions[1..9]
|
@@ -196,20 +196,36 @@ SNIPPET
|
|
196
196
|
].flatten
|
197
197
|
expect(p12.rhs).to eq(p12_expectation) # Rule 5 above
|
198
198
|
end
|
199
|
+
|
200
|
+
it 'should work with a sequence of Ruby Symbols' do
|
201
|
+
input = 'abcabdabcabd'.chars.map(&:to_sym)
|
202
|
+
instance = SequiturGrammar.new(input.to_enum)
|
203
|
+
|
204
|
+
# Expectations:
|
205
|
+
# start : P2 P2.
|
206
|
+
# P1 : :a :b
|
207
|
+
# P2 : P1 :c P1 :d.
|
208
|
+
|
209
|
+
expect(instance.productions.size).to eq(3)
|
210
|
+
(p1, p2) = instance.productions[1..2]
|
211
|
+
expect(instance.start.rhs).to eq([p2, p2])
|
212
|
+
expect(p1.rhs).to eq([:a, :b])
|
213
|
+
expect(p2.rhs).to eq([p1, :c, p1, :d])
|
214
|
+
end
|
199
215
|
end # context
|
200
216
|
|
201
217
|
context 'Generating a text representation of itself:' do
|
202
218
|
|
203
219
|
it 'should generate a text representation when empty' do
|
204
220
|
instance = SequiturGrammar.new(empty_enum)
|
205
|
-
expectation = "#{instance.
|
221
|
+
expectation = "#{instance.start.object_id} : ."
|
206
222
|
|
207
223
|
expect(instance.to_string).to eq(expectation)
|
208
224
|
end
|
209
225
|
|
210
226
|
it 'should generate a text representation of a simple production' do
|
211
227
|
instance = SequiturGrammar.new([:a].to_enum)
|
212
|
-
expectation = "#{instance.
|
228
|
+
expectation = "#{instance.start.object_id} : a."
|
213
229
|
expect(instance.to_string).to eq(expectation)
|
214
230
|
end
|
215
231
|
end # context
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequitur
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.05
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitri Geshef
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-09-
|
11
|
+
date: 2014-09-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|