raabro 0.9.0 → 1.0.0

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.
@@ -10,31 +10,42 @@ require 'spec_helper'
10
10
 
11
11
  describe Raabro do
12
12
 
13
- before :each do
14
-
15
- @input = Raabro::Input.new('toto')
16
- end
17
-
18
13
  describe '.rex' do
19
14
 
20
- it 'returns a tree with result == 0 in case of failure' do
15
+ it 'hits' do
21
16
 
22
- t = Raabro.rex(nil, @input, /t[ua]/)
17
+ i = Raabro::Input.new('toto')
18
+
19
+ t = Raabro.rex(nil, i, /t[ua]/)
23
20
 
24
21
  expect(t.to_a).to eq(
25
22
  [ nil, 0, 0, 0, nil, :rex, [] ]
26
23
  )
27
- expect(@input.offset).to eq(0)
24
+ expect(i.offset).to eq(0)
28
25
  end
29
26
 
30
- it "returns a tree with result == 1 in case of success" do
27
+ it 'misses' do
28
+
29
+ i = Raabro::Input.new('toto')
31
30
 
32
- t = Raabro.rex(nil, @input, /(to)+/)
31
+ t = Raabro.rex(nil, i, /(to)+/)
33
32
 
34
33
  expect(t.to_a(:leaves => true)).to eq(
35
34
  [ nil, 1, 0, 4, nil, :rex, 'toto' ]
36
35
  )
37
- expect(@input.offset).to eq(4)
36
+ expect(i.offset).to eq(4)
37
+ end
38
+
39
+ it 'misses if the match is not at the current input offset' do
40
+
41
+ i = Raabro::Input.new('tato')
42
+
43
+ t = Raabro.rex(:biga, i, /(to)+/)
44
+
45
+ expect(t.to_a(:leaves => true)).to eq(
46
+ [ :biga, 0, 0, 0, nil, :rex, [] ]
47
+ )
48
+ expect(i.offset).to eq(0)
38
49
  end
39
50
  end
40
51
  end
@@ -0,0 +1,110 @@
1
+
2
+ #
3
+ # specifying raabro
4
+ #
5
+ # Mon Sep 21 16:58:01 JST 2015
6
+ #
7
+
8
+ require 'spec_helper'
9
+
10
+
11
+ module Sample::Xel include Raabro
12
+
13
+ # parser
14
+
15
+ def pa(i); str(nil, i, '('); end
16
+ def pz(i); str(nil, i, ')'); end
17
+ def com(i); str(nil, i, ','); end
18
+
19
+ def num(i); rex(:num, i, /-?[0-9]+/); end
20
+
21
+ def args(i); eseq(:args, i, :pa, :exp, :com, :pz); end
22
+ def funame(i); rex(:funame, i, /[A-Z][A-Z0-9]*/); end
23
+ def fun(i); seq(:fun, i, :funame, :args); end
24
+
25
+ def exp(i); alt(:exp, i, :fun, :num); end
26
+
27
+ # entry point .parse
28
+
29
+ def rewrite(tree)
30
+
31
+ case tree.name
32
+ when :exp
33
+ rewrite tree.children.first
34
+ when :num
35
+ tree.string.to_i
36
+ when :fun
37
+ [ tree.children[0].string ] +
38
+ tree.children[1].children.collect { |e| rewrite(e) }
39
+ else
40
+ fail ArgumentError.new("cannot rewrite #{tree.to_a.inspect}")
41
+ end
42
+ end
43
+
44
+ def parse(input)
45
+
46
+ t = all(nil, Raabro::Input.new(input, :prune => true), :exp)
47
+
48
+ return nil if t.result != 1
49
+
50
+ rewrite(t.children.first.shrink!)
51
+ end
52
+ end
53
+
54
+
55
+ describe Raabro do
56
+
57
+ describe Sample::Xel do
58
+
59
+ describe '.funame' do
60
+
61
+ it 'hits' do
62
+
63
+ i = Raabro::Input.new('NADA')
64
+
65
+ t = Sample::Xel.funame(i)
66
+
67
+ expect(t.to_a(:leaves => true)).to eq(
68
+ [ :funame, 1, 0, 4, nil, :rex, 'NADA' ]
69
+ )
70
+ end
71
+ end
72
+
73
+ describe '.fun' do
74
+
75
+ it 'parses a function call' do
76
+
77
+ i = Raabro::Input.new('SUM(1,MUL(4,5))', :prune => true)
78
+
79
+ t = Sample::Xel.fun(i)
80
+
81
+ expect(t.result).to eq(1)
82
+
83
+ expect(
84
+ Sample::Xel.rewrite(t.shrink!)
85
+ ).to eq(
86
+ [ 'SUM', 1, [ 'MUL', 4, 5 ] ]
87
+ )
88
+ end
89
+ end
90
+
91
+ describe '.parse' do
92
+
93
+ it 'parses (success)' do
94
+
95
+ expect(
96
+ Sample::Xel.parse('MUL(7,-3)')
97
+ ).to eq(
98
+ [ 'MUL', 7, -3 ]
99
+ )
100
+ end
101
+
102
+ it 'parses (miss)' do
103
+
104
+ expect(Sample::Xel.parse('MUL(7,3) ')).to eq(nil)
105
+ expect(Sample::Xel.parse('MUL(7,3')).to eq(nil)
106
+ end
107
+ end
108
+ end
109
+ end
110
+
@@ -12,26 +12,25 @@ describe Raabro do
12
12
 
13
13
  describe '.seq' do
14
14
 
15
- before :each do
16
-
17
- @input = Raabro::Input.new('tato')
18
- end
19
-
20
15
  it "returns a tree with result == 0 in case of failure" do
21
16
 
22
- t = Raabro.seq(nil, @input, :to, :ta)
17
+ i = Raabro::Input.new('tato')
18
+
19
+ t = Raabro.seq(nil, i, :to, :ta)
23
20
 
24
21
  expect(t.to_a).to eq(
25
22
  [ nil, 0, 0, 0, nil, :seq, [
26
23
  [ nil, 0, 0, 0, nil, :str, [] ]
27
24
  ] ]
28
25
  )
29
- expect(@input.offset).to eq(0)
26
+ expect(i.offset).to eq(0)
30
27
  end
31
28
 
32
29
  it "returns a tree with result == 0 in case of failure (at 2nd step)" do
33
30
 
34
- t = Raabro.seq(nil, @input, :ta, :ta)
31
+ i = Raabro::Input.new('tato')
32
+
33
+ t = Raabro.seq(nil, i, :ta, :ta)
35
34
 
36
35
  expect(
37
36
  t.to_a(:leaves => true)
@@ -41,12 +40,14 @@ describe Raabro do
41
40
  [ nil, 0, 2, 0, nil, :str, [] ]
42
41
  ] ]
43
42
  )
44
- expect(@input.offset).to eq(0)
43
+ expect(i.offset).to eq(0)
45
44
  end
46
45
 
47
46
  it "returns a tree with result == 1 in case of success" do
48
47
 
49
- t = Raabro.seq(nil, @input, :ta, :to)
48
+ i = Raabro::Input.new('tato')
49
+
50
+ t = Raabro.seq(nil, i, :ta, :to)
50
51
 
51
52
  expect(
52
53
  t.to_a(:leaves => true)
@@ -56,12 +57,14 @@ describe Raabro do
56
57
  [ nil, 1, 2, 2, nil, :str, 'to' ]
57
58
  ] ]
58
59
  )
59
- expect(@input.offset).to eq(4)
60
+ expect(i.offset).to eq(4)
60
61
  end
61
62
 
62
63
  it "names the result if there is a name" do
63
64
 
64
- t = Raabro.seq(:x, @input, :ta, :to)
65
+ i = Raabro::Input.new('tato')
66
+
67
+ t = Raabro.seq(:x, i, :ta, :to)
65
68
 
66
69
  expect(
67
70
  t.to_a(:leaves => true)
@@ -71,12 +74,14 @@ describe Raabro do
71
74
  [ nil, 1, 2, 2, nil, :str, 'to' ]
72
75
  ] ]
73
76
  )
74
- expect(@input.offset).to eq(4)
77
+ expect(i.offset).to eq(4)
75
78
  end
76
79
 
77
80
  it "names in case of failure as well" do
78
81
 
79
- t = Raabro.seq(:y, @input, :ta, :ta)
82
+ i = Raabro::Input.new('tato')
83
+
84
+ t = Raabro.seq(:y, i, :ta, :ta)
80
85
 
81
86
  expect(
82
87
  t.to_a(:leaves => true)
@@ -86,14 +91,14 @@ describe Raabro do
86
91
  [ nil, 0, 2, 0, nil, :str, [] ]
87
92
  ] ]
88
93
  )
89
- expect(@input.offset).to eq(0)
94
+ expect(i.offset).to eq(0)
90
95
  end
91
96
 
92
97
  it "fails when the input string ends" do
93
98
 
94
- @input.string = 'to'
99
+ i = Raabro::Input.new('to')
95
100
 
96
- t = Raabro.seq(:z, @input, :to, :ta)
101
+ t = Raabro.seq(:z, i, :to, :ta)
97
102
 
98
103
  expect(
99
104
  t.to_a(:leaves => true)
@@ -103,104 +108,170 @@ describe Raabro do
103
108
  [ nil, 0, 2, 0, nil, :str, [] ]
104
109
  ] ]
105
110
  )
106
- expect(@input.offset).to eq(0)
111
+ expect(i.offset).to eq(0)
107
112
  end
108
113
 
109
114
  it "accepts an empty input" do
110
115
 
111
- @input.offset = 4
116
+ i = Raabro::Input.new('tato', 4)
112
117
 
113
- t = Raabro.seq(nil, @input, :to, :ta)
118
+ t = Raabro.seq(nil, i, :to, :ta)
114
119
 
115
120
  expect(t.to_a).to eq(
116
121
  [ nil, 0, 4, 0, nil, :seq, [
117
122
  [ nil, 0, 4, 0, nil, :str, [] ]
118
123
  ] ]
119
124
  )
120
- expect(@input.offset).to eq(4)
125
+ expect(i.offset).to eq(4)
126
+ end
127
+ end
128
+
129
+ describe 'seq and quantifiers' do
130
+
131
+ describe 'a lonely quantifier' do
132
+
133
+ it 'raises an ArgumentError' do
134
+
135
+ i = Raabro::Input.new('tato')
136
+
137
+ expect {
138
+ t = Raabro.seq(nil, i, '?')
139
+ }.to raise_error(ArgumentError, 'lone quantifier ?')
140
+ end
141
+ end
142
+
143
+ describe 'the question mark quantifier' do
144
+
145
+ it 'lets optional elements appear in sequences (miss)' do
146
+
147
+ i = Raabro::Input.new('tato')
148
+
149
+ t = Raabro.seq(nil, i, :ta, :tu, '?', :to)
150
+
151
+ expect(t.to_a(:leaves => true)).to eq(
152
+ [ nil, 1, 0, 4, nil, :seq, [
153
+ [ nil, 1, 0, 2, nil, :str, 'ta' ],
154
+ [ nil, 0, 2, 0, nil, :str, [] ],
155
+ [ nil, 1, 2, 2, nil, :str, 'to' ]
156
+ ] ]
157
+ )
158
+ expect(i.offset).to eq(4)
159
+ end
160
+
161
+ it 'lets optional elements appear in sequences (hit)' do
162
+
163
+ i = Raabro::Input.new('tatuto')
164
+
165
+ t = Raabro.seq(nil, i, :ta, :tu, '?', :to)
166
+
167
+ expect(t.to_a(:leaves => true)).to eq(
168
+ [ nil, 1, 0, 6, nil, :seq, [
169
+ [ nil, 1, 0, 2, nil, :str, 'ta' ],
170
+ [ nil, 1, 2, 2, nil, :str, 'tu' ],
171
+ [ nil, 1, 4, 2, nil, :str, 'to' ]
172
+ ] ]
173
+ )
174
+ expect(i.offset).to eq(6)
175
+ end
176
+
177
+ it 'lets optional elements appear in sequences (fail)' do
178
+
179
+ i = Raabro::Input.new('tatututo')
180
+
181
+ t = Raabro.seq(nil, i, :ta, :tu, '?', :to)
182
+
183
+ expect(t.to_a(:leaves => true)).to eq(
184
+ [ nil, 0, 0, 0, nil, :seq, [
185
+ [ nil, 1, 0, 2, nil, :str, 'ta' ],
186
+ [ nil, 1, 2, 2, nil, :str, 'tu' ],
187
+ [ nil, 0, 4, 0, nil, :str, [] ]
188
+ ] ]
189
+ )
190
+ expect(i.offset).to eq(0)
191
+ end
192
+ end
193
+
194
+ describe 'the star quantifier' do
195
+
196
+ it 'lets optional elements recur in sequences (hit zero)' do
197
+
198
+ i = Raabro::Input.new('tato')
199
+
200
+ t = Raabro.seq(nil, i, :ta, :tu, '*', :to)
201
+
202
+ expect(t.to_a(:leaves => true)).to eq(
203
+ [ nil, 1, 0, 4, nil, :seq, [
204
+ [ nil, 1, 0, 2, nil, :str, 'ta' ],
205
+ [ nil, 0, 2, 0, nil, :str, [] ],
206
+ [ nil, 1, 2, 2, nil, :str, 'to' ]
207
+ ] ]
208
+ )
209
+ expect(i.offset).to eq(4)
210
+ end
211
+
212
+ it 'lets optional elements recur in sequences (hit)' do
213
+
214
+ i = Raabro::Input.new('tatututo')
215
+
216
+ t = Raabro.seq(nil, i, :ta, :tu, '*', :to)
217
+
218
+ expect(t.to_a(:leaves => true)).to eq(
219
+ [ nil, 1, 0, 8, nil, :seq, [
220
+ [ nil, 1, 0, 2, nil, :str, 'ta' ],
221
+ [ nil, 1, 2, 2, nil, :str, 'tu' ],
222
+ [ nil, 1, 4, 2, nil, :str, 'tu' ],
223
+ [ nil, 0, 6, 0, nil, :str, [] ],
224
+ [ nil, 1, 6, 2, nil, :str, 'to' ]
225
+ ] ]
226
+ )
227
+ expect(i.offset).to eq(8)
228
+ end
229
+ end
230
+
231
+ describe 'the plus quantifier' do
232
+
233
+ it 'lets elements recur in sequences (hit)' do
234
+
235
+ i = Raabro::Input.new('tatututo')
236
+
237
+ t = Raabro.seq(nil, i, :ta, :tu, '+', :to)
238
+
239
+ expect(t.to_a(:leaves => true)).to eq(
240
+ [ nil, 1, 0, 8, nil, :seq, [
241
+ [ nil, 1, 0, 2, nil, :str, 'ta' ],
242
+ [ nil, 1, 2, 2, nil, :str, 'tu' ],
243
+ [ nil, 1, 4, 2, nil, :str, 'tu' ],
244
+ [ nil, 0, 6, 0, nil, :str, [] ],
245
+ [ nil, 1, 6, 2, nil, :str, 'to' ]
246
+ ] ]
247
+ )
248
+ expect(i.offset).to eq(8)
249
+ end
250
+
251
+ it 'lets elements recur in sequences (fail)' do
252
+
253
+ i = Raabro::Input.new('tato')
254
+
255
+ t = Raabro.seq(nil, i, :ta, :tu, '+', :to)
256
+
257
+ expect(t.to_a(:leaves => true)).to eq(
258
+ [ nil, 0, 0, 0, nil, :seq, [
259
+ [ nil, 1, 0, 2, nil, :str, 'ta' ],
260
+ [ nil, 0, 2, 0, nil, :str, [] ]
261
+ ] ]
262
+ )
263
+ expect(i.offset).to eq(0)
264
+ end
121
265
  end
122
266
  end
123
267
  end
124
268
 
125
269
  #describe "fabr_seq()"
126
- #{
127
- # before each
128
- # {
129
- # fabr_input i = { "tato", 0, 0 };
130
- # fabr_tree *t = NULL;
131
- # }
132
- # after each
133
- # {
134
- # fabr_tree_free(t);
135
- # }
136
- #
137
- # fabr_tree *_ta(fabr_input *i) { return fabr_str(NULL, i, "ta"); }
138
- # fabr_tree *_to(fabr_input *i) { return fabr_str(NULL, i, "to"); }
139
- #
140
- # it "returns a tree with result == 0 in case of failure"
141
- # it "returns a tree with result == 0 in case of failure (at 2nd step)"
142
- # it "returns a tree with result == 1 in case of success"
143
- # it "names the result if there is a name"
144
- # it "names in case of failure as well"
145
- # it "fails when the input string ends"
146
- # it "resets the input offset in case of failure"
147
- # it "accepts an empty input"
148
270
  #
149
271
  # context "quantifiers"
150
272
  # {
151
- # describe "a lonely quantifier"
152
- # {
153
- # it "triggers an error"
154
- # {
155
- # i.string = "tatota";
156
- # t = fabr_seq("y", &i, fabr_qmark, NULL);
157
- #
158
- # expect(fabr_tree_to_string(t, i.string, 0) ===f ""
159
- # "[ \"y\", -1, 0, 0, \"bad position for fabr_qmark, _star or _plus\", \"seq\", 0, [] ]");
160
- # }
161
- # }
162
- #
163
273
  # describe "fabr_qmark"
164
274
  # {
165
- # it "fails"
166
- # {
167
- # i.string = "tatotota";
168
- # t = fabr_seq("x", &i, _ta, _to, fabr_qmark, _ta, NULL);
169
- #
170
- # expect(fabr_tree_to_string(t, i.string, 0) ===f ""
171
- # "[ \"x\", 0, 0, 0, null, \"seq\", 0, [\n"
172
- # " [ null, 1, 0, 2, null, \"str\", 2, \"ta\" ],\n"
173
- # " [ null, 1, 2, 2, null, \"str\", 2, \"to\" ],\n"
174
- # " [ null, 0, 4, 0, null, \"str\", 2, [] ]\n"
175
- # "] ]");
176
- # }
177
- #
178
- # it "succeeds"
179
- # {
180
- # i.string = "tata";
181
- # t = fabr_seq("y", &i, _ta, _to, fabr_qmark, _ta, NULL);
182
- #
183
- # expect(fabr_tree_to_string(t, i.string, 0) ===f ""
184
- # "[ \"y\", 1, 0, 4, null, \"seq\", 0, [\n"
185
- # " [ null, 1, 0, 2, null, \"str\", 2, \"ta\" ],\n"
186
- # " [ null, 0, 2, 0, null, \"str\", 2, [] ],\n"
187
- # " [ null, 1, 2, 2, null, \"str\", 2, \"ta\" ]\n"
188
- # "] ]");
189
- # }
190
- #
191
- # it "succeeds (2)"
192
- # {
193
- # i.string = "tatota";
194
- # t = fabr_seq("z", &i, _ta, _to, fabr_qmark, _ta, NULL);
195
- #
196
- # expect(fabr_tree_to_string(t, i.string, 0) ===f ""
197
- # "[ \"z\", 1, 0, 6, null, \"seq\", 0, [\n"
198
- # " [ null, 1, 0, 2, null, \"str\", 2, \"ta\" ],\n"
199
- # " [ null, 1, 2, 2, null, \"str\", 2, \"to\" ],\n"
200
- # " [ null, 1, 4, 2, null, \"str\", 2, \"ta\" ]\n"
201
- # "] ]");
202
- # }
203
- #
204
275
  # it "prunes when input->flags & FABR_F_PRUNE"
205
276
  # {
206
277
  # i.string = "tatota";
@@ -216,99 +287,6 @@ end
216
287
  # "] ]");
217
288
  # }
218
289
  # }
219
- #
220
- # describe "fabr_star"
221
- # {
222
- # it "succeeds"
223
- # {
224
- # i.string = "tata";
225
- # t = fabr_seq("x", &i, _ta, _to, fabr_star, _ta, NULL);
226
- #
227
- # expect(fabr_tree_to_string(t, i.string, 0) ===f ""
228
- # "[ \"x\", 1, 0, 4, null, \"seq\", 0, [\n"
229
- # " [ null, 1, 0, 2, null, \"str\", 2, \"ta\" ],\n"
230
- # " [ null, 0, 2, 0, null, \"str\", 2, [] ],\n"
231
- # " [ null, 1, 2, 2, null, \"str\", 2, \"ta\" ]\n"
232
- # "] ]");
233
- # }
234
- #
235
- # it "succeeds (2)"
236
- # {
237
- # i.string = "tatotota";
238
- # t = fabr_seq("x", &i, _ta, _to, fabr_star, _ta, NULL);
239
- #
240
- # expect(fabr_tree_to_string(t, i.string, 0) ===f ""
241
- # "[ \"x\", 1, 0, 8, null, \"seq\", 0, [\n"
242
- # " [ null, 1, 0, 2, null, \"str\", 2, \"ta\" ],\n"
243
- # " [ null, 1, 2, 2, null, \"str\", 2, \"to\" ],\n"
244
- # " [ null, 1, 4, 2, null, \"str\", 2, \"to\" ],\n"
245
- # " [ null, 0, 6, 0, null, \"str\", 2, [] ],\n"
246
- # " [ null, 1, 6, 2, null, \"str\", 2, \"ta\" ]\n"
247
- # "] ]");
248
- # }
249
- #
250
- # it "prunes when input->flags & FABR_F_PRUNE"
251
- # {
252
- # i.string = "tatotota";
253
- # i.flags = FABR_F_PRUNE;
254
- #
255
- # t = fabr_seq("x", &i, _ta, _to, fabr_star, _ta, NULL);
256
- #
257
- # expect(fabr_tree_to_string(t, i.string, 0) ===f ""
258
- # "[ \"x\", 1, 0, 8, null, \"seq\", 0, [\n"
259
- # " [ null, 1, 0, 2, null, \"str\", 2, \"ta\" ],\n"
260
- # " [ null, 1, 2, 2, null, \"str\", 2, \"to\" ],\n"
261
- # " [ null, 1, 4, 2, null, \"str\", 2, \"to\" ],\n"
262
- # " [ null, 1, 6, 2, null, \"str\", 2, \"ta\" ]\n"
263
- # "] ]");
264
- # }
265
- # }
266
- #
267
- # describe "fabr_plus"
268
- # {
269
- # it "fails"
270
- # {
271
- # i.string = "tata";
272
- # t = fabr_seq("x", &i, _ta, _to, fabr_plus, _ta, NULL);
273
- #
274
- # expect(fabr_tree_to_string(t, i.string, 0) ===f ""
275
- # "[ \"x\", 0, 0, 0, null, \"seq\", 0, [\n"
276
- # " [ null, 1, 0, 2, null, \"str\", 2, \"ta\" ],\n"
277
- # " [ null, 0, 2, 0, null, \"str\", 2, [] ]\n"
278
- # "] ]");
279
- # }
280
- #
281
- # it "succeeds"
282
- # {
283
- # i.string = "tatotota";
284
- # t = fabr_seq("x", &i, _ta, _to, fabr_plus, _ta, NULL);
285
- #
286
- # expect(fabr_tree_to_string(t, i.string, 0) ===f ""
287
- # "[ \"x\", 1, 0, 8, null, \"seq\", 0, [\n"
288
- # " [ null, 1, 0, 2, null, \"str\", 2, \"ta\" ],\n"
289
- # " [ null, 1, 2, 2, null, \"str\", 2, \"to\" ],\n"
290
- # " [ null, 1, 4, 2, null, \"str\", 2, \"to\" ],\n"
291
- # " [ null, 0, 6, 0, null, \"str\", 2, [] ],\n"
292
- # " [ null, 1, 6, 2, null, \"str\", 2, \"ta\" ]\n"
293
- # "] ]");
294
- # }
295
- #
296
- # it "prunes when input->flags & FABR_F_PRUNE"
297
- # {
298
- # i.string = "tatotota";
299
- # i.flags = FABR_F_PRUNE;
300
- #
301
- # t = fabr_seq("x", &i, _ta, _to, fabr_plus, _ta, NULL);
302
- #
303
- # expect(fabr_tree_to_string(t, i.string, 0) ===f ""
304
- # "[ \"x\", 1, 0, 8, null, \"seq\", 0, [\n"
305
- # " [ null, 1, 0, 2, null, \"str\", 2, \"ta\" ],\n"
306
- # " [ null, 1, 2, 2, null, \"str\", 2, \"to\" ],\n"
307
- # " [ null, 1, 4, 2, null, \"str\", 2, \"to\" ],\n"
308
- # " [ null, 1, 6, 2, null, \"str\", 2, \"ta\" ]\n"
309
- # "] ]");
310
- # }
311
- # }
312
290
  # }
313
291
  #}
314
292