rsec 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|