raabro 0.9.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.
- data/LICENSE.txt +21 -0
- data/README.md +11 -0
- data/Rakefile +68 -0
- data/lib/raabro.rb +194 -0
- data/raabro.gemspec +36 -0
- data/spec/alt_spec.rb +61 -0
- data/spec/rep_spec.rb +82 -0
- data/spec/rex_spec.rb +41 -0
- data/spec/seq_spec.rb +314 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/str_spec.rb +73 -0
- metadata +89 -0
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
Copyright (c) 2015-2015, John Mettraux, jmettraux@gmail.com
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
of this software and associated documentation files (the "Software"), to deal
|
6
|
+
in the Software without restriction, including without limitation the rights
|
7
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the Software is
|
9
|
+
furnished to do so, subject to the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be included in
|
12
|
+
all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
THE SOFTWARE.
|
21
|
+
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
|
2
|
+
require 'rubygems'
|
3
|
+
|
4
|
+
require 'rake'
|
5
|
+
require 'rake/clean'
|
6
|
+
require 'rdoc/task'
|
7
|
+
|
8
|
+
|
9
|
+
#
|
10
|
+
# clean
|
11
|
+
|
12
|
+
CLEAN.include('pkg', 'rdoc')
|
13
|
+
|
14
|
+
|
15
|
+
#
|
16
|
+
# test / spec
|
17
|
+
|
18
|
+
#task :spec => :check_dependencies do
|
19
|
+
task :spec do
|
20
|
+
exec 'rspec spec/'
|
21
|
+
end
|
22
|
+
task :test => :spec
|
23
|
+
|
24
|
+
task :default => :spec
|
25
|
+
|
26
|
+
|
27
|
+
#
|
28
|
+
# gem
|
29
|
+
|
30
|
+
GEMSPEC_FILE = Dir['*.gemspec'].first
|
31
|
+
GEMSPEC = eval(File.read(GEMSPEC_FILE))
|
32
|
+
GEMSPEC.validate
|
33
|
+
|
34
|
+
|
35
|
+
desc %{
|
36
|
+
builds the gem and places it in pkg/
|
37
|
+
}
|
38
|
+
task :build do
|
39
|
+
|
40
|
+
sh "gem build #{GEMSPEC_FILE}"
|
41
|
+
sh "mkdir -p pkg"
|
42
|
+
sh "mv #{GEMSPEC.name}-#{GEMSPEC.version}.gem pkg/"
|
43
|
+
end
|
44
|
+
|
45
|
+
desc %{
|
46
|
+
builds the gem and pushes it to rubygems.org
|
47
|
+
}
|
48
|
+
task :push => :build do
|
49
|
+
|
50
|
+
sh "gem push pkg/#{GEMSPEC.name}-#{GEMSPEC.version}.gem"
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
#
|
55
|
+
# rdoc
|
56
|
+
#
|
57
|
+
# make sure to have rdoc 2.5.x to run that
|
58
|
+
|
59
|
+
Rake::RDocTask.new do |rd|
|
60
|
+
|
61
|
+
rd.main = 'README.txt'
|
62
|
+
rd.rdoc_dir = "rdoc/#{GEMSPEC.name}"
|
63
|
+
|
64
|
+
rd.rdoc_files.include('README.rdoc', 'CHANGELOG.txt', 'lib/**/*.rb')
|
65
|
+
|
66
|
+
rd.title = "#{GEMSPEC.name} #{GEMSPEC.version}"
|
67
|
+
end
|
68
|
+
|
data/lib/raabro.rb
ADDED
@@ -0,0 +1,194 @@
|
|
1
|
+
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2015-2015, John Mettraux, jmettraux@gmail.com
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
#
|
23
|
+
# Made in Japan.
|
24
|
+
#++
|
25
|
+
|
26
|
+
|
27
|
+
module Raabro
|
28
|
+
|
29
|
+
VERSION = '0.9.0'
|
30
|
+
|
31
|
+
class Input
|
32
|
+
|
33
|
+
attr_accessor :string, :offset
|
34
|
+
attr_reader :options
|
35
|
+
|
36
|
+
def initialize(string, options={})
|
37
|
+
|
38
|
+
@string = string
|
39
|
+
@offset = 0
|
40
|
+
@options = options
|
41
|
+
end
|
42
|
+
|
43
|
+
def match(str_or_regex)
|
44
|
+
|
45
|
+
if str_or_regex.is_a?(Regexp)
|
46
|
+
m = @string[@offset..-1].match(str_or_regex)
|
47
|
+
m ? m[0].length : false
|
48
|
+
else # String or whatever responds to #to_s
|
49
|
+
s = str_or_regex.to_s
|
50
|
+
l = s.length
|
51
|
+
@string[@offset, l] == s ? l : false
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class Tree
|
57
|
+
|
58
|
+
attr_accessor :name, :input
|
59
|
+
attr_accessor :result # ((-1 error,)) 0 nomatch, 1 success
|
60
|
+
attr_accessor :offset, :length
|
61
|
+
attr_accessor :parter, :children
|
62
|
+
|
63
|
+
def initialize(name, parter, input)
|
64
|
+
|
65
|
+
@result = 0
|
66
|
+
@name = name
|
67
|
+
@parter = parter
|
68
|
+
@input = input
|
69
|
+
@offset = input.offset
|
70
|
+
@length = 0
|
71
|
+
@children = []
|
72
|
+
end
|
73
|
+
|
74
|
+
def to_a(opts={})
|
75
|
+
|
76
|
+
cn =
|
77
|
+
opts[:leaves] && (@result == 1) && @children.empty? ?
|
78
|
+
@input.string[@offset, @length] :
|
79
|
+
@children.collect { |e| e.to_a(opts) }
|
80
|
+
|
81
|
+
[ @name, @result, @offset, @length, @note, @parter, cn ]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.match(name, input, parter, regex_or_string)
|
86
|
+
|
87
|
+
r = Tree.new(name, parter, input)
|
88
|
+
|
89
|
+
if l = input.match(regex_or_string)
|
90
|
+
r.result = 1
|
91
|
+
r.length = l
|
92
|
+
input.offset += l
|
93
|
+
end
|
94
|
+
|
95
|
+
r
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.str(name, input, string)
|
99
|
+
|
100
|
+
match(name, input, :str, string)
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.rex(name, input, regex_or_string)
|
104
|
+
|
105
|
+
match(name, input, :rex, Regexp.new(regex_or_string))
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.narrow(parser)
|
109
|
+
|
110
|
+
return parser if parser.is_a?(Method)
|
111
|
+
return method(parser) if parser.is_a?(Symbol)
|
112
|
+
|
113
|
+
k, m = parser.to_s.split('.')
|
114
|
+
k, m = [ Object, k ] unless m
|
115
|
+
|
116
|
+
Kernel.const_get(k).method(m)
|
117
|
+
end
|
118
|
+
|
119
|
+
def self.parse(parser, input)
|
120
|
+
|
121
|
+
narrow(parser).call(input)
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.seq(name, input, *parsers)
|
125
|
+
|
126
|
+
r = Tree.new(name, :seq, input)
|
127
|
+
|
128
|
+
start = input.offset
|
129
|
+
c = nil
|
130
|
+
|
131
|
+
parsers.each do |pa|
|
132
|
+
c = parse(pa, input)
|
133
|
+
r.children << c
|
134
|
+
break if c.result != 1
|
135
|
+
end
|
136
|
+
|
137
|
+
if c && c.result == 1
|
138
|
+
r.result = 1
|
139
|
+
r.length = input.offset - start
|
140
|
+
else
|
141
|
+
input.offset = start
|
142
|
+
end
|
143
|
+
|
144
|
+
r
|
145
|
+
end
|
146
|
+
|
147
|
+
def self.alt(name, input, *parsers)
|
148
|
+
|
149
|
+
r = Tree.new(name, :alt, input)
|
150
|
+
|
151
|
+
c = nil
|
152
|
+
|
153
|
+
parsers.each do |pa|
|
154
|
+
c = parse(pa, input)
|
155
|
+
r.children << c
|
156
|
+
break if c.result == 1
|
157
|
+
end
|
158
|
+
|
159
|
+
if c && c.result == 1
|
160
|
+
r.result = 1
|
161
|
+
r.length = c.length
|
162
|
+
end
|
163
|
+
|
164
|
+
r
|
165
|
+
end
|
166
|
+
|
167
|
+
def self.rep(name, input, parser, min, max=0)
|
168
|
+
|
169
|
+
min = 0 if min == nil || min < 0
|
170
|
+
max = nil if max.nil? || max < 1
|
171
|
+
|
172
|
+
r = Tree.new(name, :rep, input)
|
173
|
+
start = input.offset
|
174
|
+
count = 0
|
175
|
+
|
176
|
+
loop do
|
177
|
+
c = parse(parser, input)
|
178
|
+
r.children << c
|
179
|
+
break if c.result != 1
|
180
|
+
count += 1
|
181
|
+
break if max && count == max
|
182
|
+
end
|
183
|
+
|
184
|
+
if count >= min && (max == nil || count <= max)
|
185
|
+
r.result = 1
|
186
|
+
r.length = input.offset - start
|
187
|
+
else
|
188
|
+
input.offset = start
|
189
|
+
end
|
190
|
+
|
191
|
+
r
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
data/raabro.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
|
2
|
+
Gem::Specification.new do |s|
|
3
|
+
|
4
|
+
s.name = 'raabro'
|
5
|
+
|
6
|
+
s.version = File.read(
|
7
|
+
File.expand_path('../lib/raabro.rb', __FILE__)
|
8
|
+
).match(/ VERSION *= *['"]([^'"]+)/)[1]
|
9
|
+
|
10
|
+
s.platform = Gem::Platform::RUBY
|
11
|
+
s.authors = [ 'John Mettraux' ]
|
12
|
+
s.email = [ 'jmettraux@gmail.com' ]
|
13
|
+
s.homepage = 'http://github.com/jmettraux/rufus-scheduler'
|
14
|
+
s.rubyforge_project = 'rufus'
|
15
|
+
s.license = 'MIT'
|
16
|
+
s.summary = 'a very dumb PEG parser library'
|
17
|
+
|
18
|
+
s.description = %{
|
19
|
+
a very dumb PEG parser library
|
20
|
+
}.strip
|
21
|
+
|
22
|
+
#s.files = `git ls-files`.split("\n")
|
23
|
+
s.files = Dir[
|
24
|
+
'Rakefile',
|
25
|
+
'lib/**/*.rb', 'spec/**/*.rb', 'test/**/*.rb',
|
26
|
+
'*.gemspec', '*.txt', '*.rdoc', '*.md'
|
27
|
+
]
|
28
|
+
|
29
|
+
#s.add_runtime_dependency 'tzinfo'
|
30
|
+
|
31
|
+
s.add_development_dependency 'rake'
|
32
|
+
s.add_development_dependency 'rspec', '>= 2.13.0'
|
33
|
+
|
34
|
+
s.require_path = 'lib'
|
35
|
+
end
|
36
|
+
|
data/spec/alt_spec.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# specifying raabro
|
4
|
+
#
|
5
|
+
# Sun Sep 20 07:31:53 JST 2015
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'spec_helper'
|
9
|
+
|
10
|
+
|
11
|
+
describe Raabro do
|
12
|
+
|
13
|
+
describe '.alt' do
|
14
|
+
|
15
|
+
before :each do
|
16
|
+
|
17
|
+
@input = Raabro::Input.new('tato')
|
18
|
+
end
|
19
|
+
|
20
|
+
it "returns a tree with result == 0 in case of failure" do
|
21
|
+
|
22
|
+
@input.string = 'tutu'
|
23
|
+
|
24
|
+
t = Raabro.alt(nil, @input, :ta, :to)
|
25
|
+
|
26
|
+
expect(t.to_a(:leaves => true)).to eq(
|
27
|
+
[ nil, 0, 0, 0, nil, :alt, [
|
28
|
+
[ nil, 0, 0, 0, nil, :str, [] ],
|
29
|
+
[ nil, 0, 0, 0, nil, :str, [] ]
|
30
|
+
] ]
|
31
|
+
)
|
32
|
+
expect(@input.offset).to eq(0)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "succeeds (1st alternative)" do
|
36
|
+
|
37
|
+
t = Raabro.alt(nil, @input, :ta, :to)
|
38
|
+
|
39
|
+
expect(t.to_a(:leaves => true)).to eq(
|
40
|
+
[ nil, 1, 0, 2, nil, :alt, [
|
41
|
+
[ nil, 1, 0, 2, nil, :str, 'ta' ]
|
42
|
+
] ]
|
43
|
+
)
|
44
|
+
expect(@input.offset).to eq(2)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "succeeds (2nd alternative)" do
|
48
|
+
|
49
|
+
t = Raabro.alt(nil, @input, :to, :ta)
|
50
|
+
|
51
|
+
expect(t.to_a(:leaves => true)).to eq(
|
52
|
+
[ nil, 1, 0, 2, nil, :alt, [
|
53
|
+
[ nil, 0, 0, 0, nil, :str, [] ],
|
54
|
+
[ nil, 1, 0, 2, nil, :str, 'ta' ]
|
55
|
+
] ]
|
56
|
+
)
|
57
|
+
expect(@input.offset).to eq(2)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
data/spec/rep_spec.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# specifying raabro
|
4
|
+
#
|
5
|
+
# Sun Sep 20 09:36:16 JST 2015
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'spec_helper'
|
9
|
+
|
10
|
+
|
11
|
+
describe Raabro do
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
|
15
|
+
@input = Raabro::Input.new('toto')
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '.rep' do
|
19
|
+
|
20
|
+
it 'returns a tree with result == 0 in case of failure' do
|
21
|
+
|
22
|
+
t = Raabro.rep(:x, @input, :to, 3, 4)
|
23
|
+
|
24
|
+
expect(t.to_a(:leaves => true)).to eq(
|
25
|
+
[ :x, 0, 0, 0, nil, :rep, [
|
26
|
+
[ nil, 1, 0, 2, nil, :str, 'to' ],
|
27
|
+
[ nil, 1, 2, 2, nil, :str, 'to' ],
|
28
|
+
[ nil, 0, 4, 0, nil, :str, [] ]
|
29
|
+
] ]
|
30
|
+
)
|
31
|
+
expect(@input.offset).to eq(0)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "fails (min not reached)" do
|
35
|
+
|
36
|
+
@input.string = 'toto'
|
37
|
+
|
38
|
+
t = Raabro.rep(:x, @input, :to, 3)
|
39
|
+
|
40
|
+
expect(t.to_a(:leaves => true)).to eq(
|
41
|
+
[ :x, 0, 0, 0, nil, :rep, [
|
42
|
+
[ nil, 1, 0, 2, nil, :str, 'to' ],
|
43
|
+
[ nil, 1, 2, 2, nil, :str, 'to' ],
|
44
|
+
[ nil, 0, 4, 0, nil, :str, [] ]
|
45
|
+
] ]
|
46
|
+
)
|
47
|
+
expect(@input.offset).to eq(0)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "succeeds (max set)" do
|
51
|
+
|
52
|
+
@input.string = 'tototo'
|
53
|
+
|
54
|
+
t = Raabro.rep(:x, @input, :to, 1, 2)
|
55
|
+
|
56
|
+
expect(t.to_a(:leaves => true)).to eq(
|
57
|
+
[ :x, 1, 0, 4, nil, :rep, [
|
58
|
+
[ nil, 1, 0, 2, nil, :str, 'to' ],
|
59
|
+
[ nil, 1, 2, 2, nil, :str, 'to' ]
|
60
|
+
] ]
|
61
|
+
)
|
62
|
+
expect(@input.offset).to eq(4)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "succeeds (max not set)" do
|
66
|
+
|
67
|
+
@input.string = 'toto'
|
68
|
+
|
69
|
+
t = Raabro.rep(:x, @input, :to, 1)
|
70
|
+
|
71
|
+
expect(t.to_a(:leaves => true)).to eq(
|
72
|
+
[ :x, 1, 0, 4, nil, :rep, [
|
73
|
+
[ nil, 1, 0, 2, nil, :str, 'to' ],
|
74
|
+
[ nil, 1, 2, 2, nil, :str, 'to' ],
|
75
|
+
[ nil, 0, 4, 0, nil, :str, [] ]
|
76
|
+
] ]
|
77
|
+
)
|
78
|
+
expect(@input.offset).to eq(4)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
data/spec/rex_spec.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# specifying raabro
|
4
|
+
#
|
5
|
+
# Sun Sep 20 07:12:35 JST 2015
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'spec_helper'
|
9
|
+
|
10
|
+
|
11
|
+
describe Raabro do
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
|
15
|
+
@input = Raabro::Input.new('toto')
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '.rex' do
|
19
|
+
|
20
|
+
it 'returns a tree with result == 0 in case of failure' do
|
21
|
+
|
22
|
+
t = Raabro.rex(nil, @input, /t[ua]/)
|
23
|
+
|
24
|
+
expect(t.to_a).to eq(
|
25
|
+
[ nil, 0, 0, 0, nil, :rex, [] ]
|
26
|
+
)
|
27
|
+
expect(@input.offset).to eq(0)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns a tree with result == 1 in case of success" do
|
31
|
+
|
32
|
+
t = Raabro.rex(nil, @input, /(to)+/)
|
33
|
+
|
34
|
+
expect(t.to_a(:leaves => true)).to eq(
|
35
|
+
[ nil, 1, 0, 4, nil, :rex, 'toto' ]
|
36
|
+
)
|
37
|
+
expect(@input.offset).to eq(4)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
data/spec/seq_spec.rb
ADDED
@@ -0,0 +1,314 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# specifying raabro
|
4
|
+
#
|
5
|
+
# Sun Sep 20 06:11:54 JST 2015
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'spec_helper'
|
9
|
+
|
10
|
+
|
11
|
+
describe Raabro do
|
12
|
+
|
13
|
+
describe '.seq' do
|
14
|
+
|
15
|
+
before :each do
|
16
|
+
|
17
|
+
@input = Raabro::Input.new('tato')
|
18
|
+
end
|
19
|
+
|
20
|
+
it "returns a tree with result == 0 in case of failure" do
|
21
|
+
|
22
|
+
t = Raabro.seq(nil, @input, :to, :ta)
|
23
|
+
|
24
|
+
expect(t.to_a).to eq(
|
25
|
+
[ nil, 0, 0, 0, nil, :seq, [
|
26
|
+
[ nil, 0, 0, 0, nil, :str, [] ]
|
27
|
+
] ]
|
28
|
+
)
|
29
|
+
expect(@input.offset).to eq(0)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "returns a tree with result == 0 in case of failure (at 2nd step)" do
|
33
|
+
|
34
|
+
t = Raabro.seq(nil, @input, :ta, :ta)
|
35
|
+
|
36
|
+
expect(
|
37
|
+
t.to_a(:leaves => true)
|
38
|
+
).to eq(
|
39
|
+
[ nil, 0, 0, 0, nil, :seq, [
|
40
|
+
[ nil, 1, 0, 2, nil, :str, 'ta' ],
|
41
|
+
[ nil, 0, 2, 0, nil, :str, [] ]
|
42
|
+
] ]
|
43
|
+
)
|
44
|
+
expect(@input.offset).to eq(0)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns a tree with result == 1 in case of success" do
|
48
|
+
|
49
|
+
t = Raabro.seq(nil, @input, :ta, :to)
|
50
|
+
|
51
|
+
expect(
|
52
|
+
t.to_a(:leaves => true)
|
53
|
+
).to eq(
|
54
|
+
[ nil, 1, 0, 4, nil, :seq, [
|
55
|
+
[ nil, 1, 0, 2, nil, :str, 'ta' ],
|
56
|
+
[ nil, 1, 2, 2, nil, :str, 'to' ]
|
57
|
+
] ]
|
58
|
+
)
|
59
|
+
expect(@input.offset).to eq(4)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "names the result if there is a name" do
|
63
|
+
|
64
|
+
t = Raabro.seq(:x, @input, :ta, :to)
|
65
|
+
|
66
|
+
expect(
|
67
|
+
t.to_a(:leaves => true)
|
68
|
+
).to eq(
|
69
|
+
[ :x, 1, 0, 4, nil, :seq, [
|
70
|
+
[ nil, 1, 0, 2, nil, :str, 'ta' ],
|
71
|
+
[ nil, 1, 2, 2, nil, :str, 'to' ]
|
72
|
+
] ]
|
73
|
+
)
|
74
|
+
expect(@input.offset).to eq(4)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "names in case of failure as well" do
|
78
|
+
|
79
|
+
t = Raabro.seq(:y, @input, :ta, :ta)
|
80
|
+
|
81
|
+
expect(
|
82
|
+
t.to_a(:leaves => true)
|
83
|
+
).to eq(
|
84
|
+
[ :y, 0, 0, 0, nil, :seq, [
|
85
|
+
[ nil, 1, 0, 2, nil, :str, 'ta' ],
|
86
|
+
[ nil, 0, 2, 0, nil, :str, [] ]
|
87
|
+
] ]
|
88
|
+
)
|
89
|
+
expect(@input.offset).to eq(0)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "fails when the input string ends" do
|
93
|
+
|
94
|
+
@input.string = 'to'
|
95
|
+
|
96
|
+
t = Raabro.seq(:z, @input, :to, :ta)
|
97
|
+
|
98
|
+
expect(
|
99
|
+
t.to_a(:leaves => true)
|
100
|
+
).to eq(
|
101
|
+
[ :z, 0, 0, 0, nil, :seq, [
|
102
|
+
[ nil, 1, 0, 2, nil, :str, 'to' ],
|
103
|
+
[ nil, 0, 2, 0, nil, :str, [] ]
|
104
|
+
] ]
|
105
|
+
)
|
106
|
+
expect(@input.offset).to eq(0)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "accepts an empty input" do
|
110
|
+
|
111
|
+
@input.offset = 4
|
112
|
+
|
113
|
+
t = Raabro.seq(nil, @input, :to, :ta)
|
114
|
+
|
115
|
+
expect(t.to_a).to eq(
|
116
|
+
[ nil, 0, 4, 0, nil, :seq, [
|
117
|
+
[ nil, 0, 4, 0, nil, :str, [] ]
|
118
|
+
] ]
|
119
|
+
)
|
120
|
+
expect(@input.offset).to eq(4)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
#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
|
+
#
|
149
|
+
# context "quantifiers"
|
150
|
+
# {
|
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
|
+
# describe "fabr_qmark"
|
164
|
+
# {
|
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
|
+
# it "prunes when input->flags & FABR_F_PRUNE"
|
205
|
+
# {
|
206
|
+
# i.string = "tatota";
|
207
|
+
# i.flags = FABR_F_PRUNE;
|
208
|
+
#
|
209
|
+
# t = fabr_seq("z", &i, _ta, _to, fabr_qmark, _ta, NULL);
|
210
|
+
#
|
211
|
+
# expect(fabr_tree_to_string(t, i.string, 0) ===f ""
|
212
|
+
# "[ \"z\", 1, 0, 6, null, \"seq\", 0, [\n"
|
213
|
+
# " [ null, 1, 0, 2, null, \"str\", 2, \"ta\" ],\n"
|
214
|
+
# " [ null, 1, 2, 2, null, \"str\", 2, \"to\" ],\n"
|
215
|
+
# " [ null, 1, 4, 2, null, \"str\", 2, \"ta\" ]\n"
|
216
|
+
# "] ]");
|
217
|
+
# }
|
218
|
+
# }
|
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
|
+
# }
|
313
|
+
#}
|
314
|
+
|
data/spec/spec_helper.rb
ADDED
data/spec/str_spec.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# specifying raabro
|
4
|
+
#
|
5
|
+
# Sun Sep 20 06:11:54 JST 2015
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'spec_helper'
|
9
|
+
|
10
|
+
|
11
|
+
describe Raabro do
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
|
15
|
+
@input = Raabro::Input.new('toto')
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '.str' do
|
19
|
+
|
20
|
+
it 'returns a tree with result == 0 in case of failure' do
|
21
|
+
|
22
|
+
t = Raabro.str(nil, @input, 'nada')
|
23
|
+
|
24
|
+
expect(t.to_a).to eq(
|
25
|
+
[ nil, 0, 0, 0, nil, :str, [] ]
|
26
|
+
)
|
27
|
+
expect(@input.offset).to eq(0)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns a tree with result == 1 in case of success" do
|
31
|
+
|
32
|
+
t = Raabro.str(nil, @input, 'toto')
|
33
|
+
|
34
|
+
expect(t.to_a).to eq(
|
35
|
+
[ nil, 1, 0, 4, nil, :str, [] ]
|
36
|
+
)
|
37
|
+
expect(@input.offset).to eq(4)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "names the result if there is a name" do
|
41
|
+
|
42
|
+
t = Raabro.str(:x, @input, 'toto')
|
43
|
+
|
44
|
+
expect(t.to_a).to eq(
|
45
|
+
[ :x, 1, 0, 4, nil, :str, [] ]
|
46
|
+
)
|
47
|
+
expect(@input.offset).to eq(4)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "names in case of failure as well" do
|
51
|
+
|
52
|
+
t = Raabro.str(:y, @input, 'nada')
|
53
|
+
|
54
|
+
expect(t.to_a).to eq(
|
55
|
+
[ :y, 0, 0, 0, nil, :str, [] ]
|
56
|
+
)
|
57
|
+
expect(@input.offset).to eq(0)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "accepts an empty input" do
|
61
|
+
|
62
|
+
@input.offset = 4
|
63
|
+
|
64
|
+
t = Raabro.str(nil, @input, 'nada')
|
65
|
+
|
66
|
+
expect(t.to_a).to eq(
|
67
|
+
[ nil, 0, 4, 0, nil, :str, [] ]
|
68
|
+
)
|
69
|
+
expect(@input.offset).to eq(4)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: raabro
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- John Mettraux
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-09-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 2.13.0
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.13.0
|
46
|
+
description: a very dumb PEG parser library
|
47
|
+
email:
|
48
|
+
- jmettraux@gmail.com
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- Rakefile
|
54
|
+
- lib/raabro.rb
|
55
|
+
- spec/alt_spec.rb
|
56
|
+
- spec/rep_spec.rb
|
57
|
+
- spec/rex_spec.rb
|
58
|
+
- spec/seq_spec.rb
|
59
|
+
- spec/spec_helper.rb
|
60
|
+
- spec/str_spec.rb
|
61
|
+
- raabro.gemspec
|
62
|
+
- LICENSE.txt
|
63
|
+
- README.md
|
64
|
+
homepage: http://github.com/jmettraux/rufus-scheduler
|
65
|
+
licenses:
|
66
|
+
- MIT
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options: []
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
requirements: []
|
84
|
+
rubyforge_project: rufus
|
85
|
+
rubygems_version: 1.8.23.2
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: a very dumb PEG parser library
|
89
|
+
test_files: []
|