rsec 0.3.2
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/bench/bench.rb +60 -0
- data/bench/little.rb +328 -0
- data/bench/profile.rb +14 -0
- data/examples/arithmetic.rb +28 -0
- data/examples/bnf.rb +31 -0
- data/examples/c_minus.rb +175 -0
- data/examples/hello.scm +18 -0
- data/examples/s_exp.rb +17 -0
- data/examples/scheme.rb +84 -0
- data/examples/slow_json.rb +68 -0
- data/lib/rsec.rb +40 -0
- data/lib/rsec/helpers.rb +447 -0
- data/lib/rsec/parser.rb +64 -0
- data/lib/rsec/parsers/join.rb +86 -0
- data/lib/rsec/parsers/misc.rb +201 -0
- data/lib/rsec/parsers/prim.rb +102 -0
- data/lib/rsec/parsers/repeat.rb +90 -0
- data/lib/rsec/parsers/seq.rb +94 -0
- data/lib/rsec/utils.rb +116 -0
- data/license.txt +1 -0
- data/readme.rdoc +30 -0
- data/test/helpers.rb +24 -0
- data/test/test_branch.rb +14 -0
- data/test/test_examples.rb +36 -0
- data/test/test_join.rb +52 -0
- data/test/test_lookahead.rb +16 -0
- data/test/test_misc.rb +56 -0
- data/test/test_one_of.rb +39 -0
- data/test/test_pattern.rb +53 -0
- data/test/test_prim.rb +59 -0
- data/test/test_repeat.rb +50 -0
- data/test/test_rsec.rb +10 -0
- data/test/test_seq.rb +51 -0
- metadata +80 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/helpers.rb"
|
2
|
+
|
3
|
+
class TestLookAhead < TC
|
4
|
+
def test_lookahead
|
5
|
+
p1 = 'a'.r & 'b'
|
6
|
+
p2 = /\w/.r
|
7
|
+
p = seq(p1, p2)
|
8
|
+
ase ['a', 'b'], p.parse('ab')
|
9
|
+
ase INVALID, p.parse('ac')
|
10
|
+
|
11
|
+
p1 = 'a'.r ^ 'b'
|
12
|
+
p = seq(p1, p2)
|
13
|
+
ase ['a', 'c'], p.parse('ac')
|
14
|
+
ase INVALID, p.parse('ab')
|
15
|
+
end
|
16
|
+
end
|
data/test/test_misc.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/helpers.rb"
|
2
|
+
|
3
|
+
class TestMisc < TC
|
4
|
+
def test_lazy
|
5
|
+
p1 = nil
|
6
|
+
p2 = lazy{p1}
|
7
|
+
|
8
|
+
p1 = '3'.r
|
9
|
+
asp '3', p2
|
10
|
+
|
11
|
+
p1 = '4'.r
|
12
|
+
asp '3', p2
|
13
|
+
|
14
|
+
p2 = lazy{p7} # don't have to define p7 before lazy
|
15
|
+
p7 = '5'.r
|
16
|
+
asp '5',p2
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_eof
|
20
|
+
p = ''.r.eof
|
21
|
+
asp '', p
|
22
|
+
ase INVALID, p.parse('a')
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_cache
|
26
|
+
p1 = seq('a', seq('b', 'c'))
|
27
|
+
p = seq(p1.cached, 'd')
|
28
|
+
ase [['a',['b','c']],'d'], p.parse('abcd')
|
29
|
+
|
30
|
+
# with map block
|
31
|
+
p = seq(p1.cached{ 'mapped' }, 'd')
|
32
|
+
ase ['mapped', 'd'], p.parse('abcd')
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_map
|
36
|
+
p = /\w/.r.map{|n| n*2}
|
37
|
+
ase 'bb', p.parse('b')
|
38
|
+
ase INVALID, p.parse('.')
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_fail
|
42
|
+
p = 'v'.r.fail 'omg!'
|
43
|
+
p.eof.parse! 'u'
|
44
|
+
assert false, "should raise syntax error"
|
45
|
+
rescue Rsec::SyntaxError => e
|
46
|
+
assert e.to_s.index 'omg!'
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_fail_with_block
|
50
|
+
p = 'v'.r.fail('omg!'){ 'should fail' }
|
51
|
+
p.eof.parse! 'u'
|
52
|
+
assert false, "should raise syntax error"
|
53
|
+
rescue Rsec::SyntaxError => e
|
54
|
+
assert e.to_s.index 'omg!'
|
55
|
+
end
|
56
|
+
end
|
data/test/test_one_of.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/helpers.rb"
|
2
|
+
|
3
|
+
class TestOneOf < TC
|
4
|
+
def test_one_of
|
5
|
+
p = one_of('abcd')
|
6
|
+
ase 'c', p.parse('c')
|
7
|
+
ase INVALID, p.parse('e')
|
8
|
+
p = one_of('+=')
|
9
|
+
ase '=', p.parse('=')
|
10
|
+
|
11
|
+
begin
|
12
|
+
p = one_of('')
|
13
|
+
assert false, "should raise exception for empty string"
|
14
|
+
rescue
|
15
|
+
end
|
16
|
+
|
17
|
+
# with map block
|
18
|
+
p = one_of('x+'){|v| v * 2}
|
19
|
+
ase '++', p.parse('+')
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_one_of_
|
23
|
+
p = one_of_('abcd')
|
24
|
+
ase 'a', p.parse('a')
|
25
|
+
ase INVALID, p.parse('e')
|
26
|
+
ase 'd', p.parse(' d ')
|
27
|
+
ase 'a', p.parse(' a')
|
28
|
+
ase 'c', p.parse('c ')
|
29
|
+
|
30
|
+
assert_raise(ArgumentError) {
|
31
|
+
p = one_of_('')
|
32
|
+
}
|
33
|
+
|
34
|
+
# with map block
|
35
|
+
p = one_of_('w'){'v'}
|
36
|
+
ase 'v', p.parse('w')
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/helpers.rb"
|
2
|
+
|
3
|
+
class TestPattern < TC
|
4
|
+
def test_create
|
5
|
+
p1 = 'x'.r
|
6
|
+
asp 'x', p1
|
7
|
+
p1 = 'abc'.r
|
8
|
+
asp 'abc', p1
|
9
|
+
|
10
|
+
asr do
|
11
|
+
p1.eof.parse! 'abcd'
|
12
|
+
end
|
13
|
+
ase INVALID, p1.eof.parse('abcd')
|
14
|
+
|
15
|
+
asr do
|
16
|
+
p1.eof.parse! 'xabc'
|
17
|
+
end
|
18
|
+
ase INVALID, p1.eof.parse('xabc')
|
19
|
+
|
20
|
+
# with map block
|
21
|
+
p = 'x'.r{ 'y' }
|
22
|
+
ase INVALID, p.parse('y')
|
23
|
+
ase 'y', p.parse('x')
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_until
|
27
|
+
p = 'ef'.r.until
|
28
|
+
asp 'xef', p
|
29
|
+
asp "x\nef", p
|
30
|
+
|
31
|
+
p = 'e'.r.until
|
32
|
+
asp 'xe', p
|
33
|
+
asp "x\ne", p
|
34
|
+
|
35
|
+
# with map block
|
36
|
+
p = 'e'.r.until{|s| s*2}
|
37
|
+
ase 'xexe', p.parse('xe')
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_word
|
41
|
+
p = word('abc')
|
42
|
+
ase INVALID, p.parse('abcd')
|
43
|
+
ase INVALID, seq_(p, 'd').parse('abcd')
|
44
|
+
ase 'abc', p.parse('abc')
|
45
|
+
ase ['abc', 'd'], seq_(p, 'd').parse('abc d')
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_symbol
|
49
|
+
p = symbol('*')
|
50
|
+
ase '*', p.parse(' * ')
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/test/test_prim.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/helpers.rb"
|
2
|
+
|
3
|
+
class TestPrim < TC
|
4
|
+
def test_floating
|
5
|
+
[:double].each do |ty|
|
6
|
+
p = prim ty
|
7
|
+
ase INVALID, p.parse('d')
|
8
|
+
ase 3.2e5.round, p.parse('+3.2e5').round
|
9
|
+
ase INVALID, p.parse(' 4.8')
|
10
|
+
|
11
|
+
p = prim ty, allowed_sign: ''
|
12
|
+
ase 1.5e-3.round(4), p.parse('1.5E-3').round(4)
|
13
|
+
ase INVALID, p.parse('+3.0')
|
14
|
+
|
15
|
+
p = prim ty, allowed_sign: '-'
|
16
|
+
ase (-5.0).round, p.parse('-5').round
|
17
|
+
ase INVALID, p.parse('-')
|
18
|
+
ase INVALID, p.parse('+5')
|
19
|
+
ase 5.0.round, p.parse('5').round
|
20
|
+
|
21
|
+
# with map block
|
22
|
+
p = prim(ty){|x| x * 2 }
|
23
|
+
ase 100.0.round, p.parse('50').round
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_hex_floating
|
28
|
+
[:hex_double].each do |ty|
|
29
|
+
p = prim ty
|
30
|
+
ase Float('0x3.2').round(4), p.parse('0x3.2').round(4)
|
31
|
+
|
32
|
+
# with map block
|
33
|
+
p = prim(ty){|x| x - 0.1 }
|
34
|
+
ase (Float('0x3.2') - 0.1).round(4), p.parse('0x3.2').round(4)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_integer
|
39
|
+
[:int32, :unsigned_int32, :int64, :unsigned_int64].each do |ty|
|
40
|
+
p = prim ty
|
41
|
+
ase 432, p.parse('432')
|
42
|
+
p = prim ty, base: 4
|
43
|
+
ase '120'.to_i(4), p.parse('120')
|
44
|
+
p = prim ty, base: 35
|
45
|
+
ase '1ax'.to_i(35), p.parse('1ax')
|
46
|
+
end
|
47
|
+
|
48
|
+
p = prim :int32, allowed_signs: '-'
|
49
|
+
ase INVALID, p.parse('+12')
|
50
|
+
ase INVALID, p.parse('123333333333333333333333333333333333')
|
51
|
+
ase INVALID, p.parse('-')
|
52
|
+
ase -49, p.parse('-49')
|
53
|
+
|
54
|
+
assert_raise RuntimeError do
|
55
|
+
prim :unsigned_int32, allowed_signs: '+-'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
data/test/test_repeat.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/helpers.rb"
|
2
|
+
|
3
|
+
class TestRepeat < TC
|
4
|
+
def test_maybe
|
5
|
+
[:_?, :maybe].each do |m|
|
6
|
+
p = seq('v', 'q').send m
|
7
|
+
ase [], p.parse('')
|
8
|
+
ase INVALID, p.eof.parse('v')
|
9
|
+
ase [['v', 'q']], p.parse('vq')
|
10
|
+
|
11
|
+
# with map block
|
12
|
+
p = seq('v', 'q').maybe {|x| x.empty? ? 'bad' : 'good' }
|
13
|
+
ase 'good', p.parse('vq')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_multiply
|
18
|
+
p = ('ce'.r * 3).eof
|
19
|
+
ase ['ce','ce','ce'], (p.parse 'cecece')
|
20
|
+
ase INVALID, (p.parse 'cece')
|
21
|
+
ase INVALID, (p.parse 'cececece')
|
22
|
+
|
23
|
+
p = ('ce'.r * 0).eof
|
24
|
+
ase [], (p.parse '')
|
25
|
+
ase INVALID, (p.parse 'ce')
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_range
|
29
|
+
p = ('ce'.r * (2..3)).eof
|
30
|
+
ase INVALID, (p.parse 'ce')
|
31
|
+
ase ['ce','ce'], (p.parse 'cece')
|
32
|
+
ase INVALID, (p.parse 'cececece')
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_inf
|
36
|
+
p = ('ce'.r * (3..-1)).eof
|
37
|
+
ase INVALID,
|
38
|
+
(p.parse 'cece')
|
39
|
+
ase ['ce','ce','ce'],
|
40
|
+
(p.parse 'cecece')
|
41
|
+
ase ['ce','ce','ce','ce','ce'],
|
42
|
+
(p.parse 'cecececece')
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_star
|
46
|
+
p = '*'.r.star
|
47
|
+
ase [], p.parse('')
|
48
|
+
ase %w[* * *], p.parse('***')
|
49
|
+
end
|
50
|
+
end
|
data/test/test_rsec.rb
ADDED
data/test/test_seq.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/helpers.rb"
|
2
|
+
|
3
|
+
class TestSeq < TC
|
4
|
+
def test_seq
|
5
|
+
p = seq('a', 'b', 'c')
|
6
|
+
ase ['a','b','c'], p.parse('abc')
|
7
|
+
ase INVALID, p.parse('a')
|
8
|
+
ase INVALID, p.parse('b')
|
9
|
+
ase INVALID, p.parse('c')
|
10
|
+
ase INVALID, p.parse('bc')
|
11
|
+
ase INVALID, p.parse('ab')
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_seq_
|
15
|
+
p = seq_('abc', 'ef', 'vv')
|
16
|
+
ase %w[abc ef vv], p.parse("abc ef vv")
|
17
|
+
p = seq_('abc', 'ef', 'vv', skip: /\s+/)
|
18
|
+
ase %w[abc ef vv], p.parse("abc ef vv")
|
19
|
+
ase INVALID, p.parse("abcef vv")
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_seq_mix
|
23
|
+
p = seq('e', seq_('a','b','c'), 'd')
|
24
|
+
ase ['e', ['a','b','c'], 'd'], p.parse('eabcd')
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_seq_one
|
28
|
+
p = seq('a', 'b', 'c')[1]
|
29
|
+
ase 'b', p.parse('abc')
|
30
|
+
p = seq('abc', /\s*/, 'd')[2]
|
31
|
+
ase 'd', p.parse('abc d')
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_seq_one_
|
35
|
+
p = seq_('a', 'b', 'c')[1]
|
36
|
+
ase 'b', p.parse('a bc')
|
37
|
+
p = seq_('abc', /\s*/, 'd')[2]
|
38
|
+
ase 'd', p.parse('abc d')
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_fall
|
42
|
+
p = 'a'.r >> 'b'
|
43
|
+
ase 'b', p.parse!('ab')
|
44
|
+
p = p << 'c'
|
45
|
+
ase 'b', p.parse!('abc')
|
46
|
+
|
47
|
+
p = p._?
|
48
|
+
ase ['b'], p.eof.parse!('abc')
|
49
|
+
ase [], p.eof.parse!('')
|
50
|
+
end
|
51
|
+
end
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rsec
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- NS
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-02-24 00:00:00.000000000 +08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
description: Easy and extreme fast dynamic PEG parser combinator.
|
16
|
+
email:
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files:
|
20
|
+
- readme.rdoc
|
21
|
+
files:
|
22
|
+
- license.txt
|
23
|
+
- readme.rdoc
|
24
|
+
- lib/rsec/helpers.rb
|
25
|
+
- lib/rsec/parser.rb
|
26
|
+
- lib/rsec/parsers/join.rb
|
27
|
+
- lib/rsec/parsers/misc.rb
|
28
|
+
- lib/rsec/parsers/prim.rb
|
29
|
+
- lib/rsec/parsers/repeat.rb
|
30
|
+
- lib/rsec/parsers/seq.rb
|
31
|
+
- lib/rsec/utils.rb
|
32
|
+
- lib/rsec.rb
|
33
|
+
- examples/arithmetic.rb
|
34
|
+
- examples/bnf.rb
|
35
|
+
- examples/c_minus.rb
|
36
|
+
- examples/scheme.rb
|
37
|
+
- examples/slow_json.rb
|
38
|
+
- examples/s_exp.rb
|
39
|
+
- examples/hello.scm
|
40
|
+
- test/helpers.rb
|
41
|
+
- test/test_branch.rb
|
42
|
+
- test/test_examples.rb
|
43
|
+
- test/test_join.rb
|
44
|
+
- test/test_lookahead.rb
|
45
|
+
- test/test_misc.rb
|
46
|
+
- test/test_one_of.rb
|
47
|
+
- test/test_pattern.rb
|
48
|
+
- test/test_prim.rb
|
49
|
+
- test/test_repeat.rb
|
50
|
+
- test/test_rsec.rb
|
51
|
+
- test/test_seq.rb
|
52
|
+
- bench/bench.rb
|
53
|
+
- bench/little.rb
|
54
|
+
- bench/profile.rb
|
55
|
+
has_rdoc: true
|
56
|
+
homepage: http://rsec.heroku.com
|
57
|
+
licenses: []
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 1.9.1
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ! '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
requirements: []
|
75
|
+
rubyforge_project:
|
76
|
+
rubygems_version: 1.5.2
|
77
|
+
signing_key:
|
78
|
+
specification_version: 3
|
79
|
+
summary: Extreme Fast Parser Combinator for Ruby
|
80
|
+
test_files: []
|