abnf 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +16 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +194 -0
- data/Rakefile +18 -0
- data/abnf.gemspec +24 -0
- data/lib/abnf.rb +57 -0
- data/lib/abnf/abnf.rb +136 -0
- data/lib/abnf/corerules.rb +28 -0
- data/lib/abnf/grammar.rb +183 -0
- data/lib/abnf/parser.output +348 -0
- data/lib/abnf/parser.rb +821 -0
- data/lib/abnf/parser.y +156 -0
- data/lib/abnf/regexp.rb +394 -0
- data/lib/abnf/version.rb +3 -0
- data/lib/natset.rb +411 -0
- data/lib/regexptree.rb +530 -0
- data/sample/in-place.rb +26 -0
- data/sample/ipv6.rb +42 -0
- data/sample/multiples-of-3.rb +19 -0
- data/sample/uri.rb +75 -0
- data/test/abnf_test.rb +82 -0
- data/test/regexptree_test.rb +12 -0
- data/test/test_helper.rb +3 -0
- metadata +115 -0
data/sample/in-place.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'abnf'
|
2
|
+
|
3
|
+
p /\A#{ABNF.regexp <<'End'}\z/o =~ "::13.1.68.3"
|
4
|
+
IPv6address = "::" /
|
5
|
+
7( hex4 ":" ) hex4 /
|
6
|
+
1*8( hex4 ":" ) ":" /
|
7
|
+
7( hex4 ":" ) ( ":" hex4 ) /
|
8
|
+
6( hex4 ":" ) 1*2( ":" hex4 ) /
|
9
|
+
5( hex4 ":" ) 1*3( ":" hex4 ) /
|
10
|
+
4( hex4 ":" ) 1*4( ":" hex4 ) /
|
11
|
+
3( hex4 ":" ) 1*5( ":" hex4 ) /
|
12
|
+
2( hex4 ":" ) 1*6( ":" hex4 ) /
|
13
|
+
( hex4 ":" ) 1*7( ":" hex4 ) /
|
14
|
+
":" 1*8( ":" hex4 ) /
|
15
|
+
6( hex4 ":" ) IPv4address /
|
16
|
+
6( hex4 ":" ) ":" IPv4address /
|
17
|
+
5( hex4 ":" ) ":" 0*1( hex4 ":" ) IPv4address /
|
18
|
+
4( hex4 ":" ) ":" 0*2( hex4 ":" ) IPv4address /
|
19
|
+
3( hex4 ":" ) ":" 0*3( hex4 ":" ) IPv4address /
|
20
|
+
2( hex4 ":" ) ":" 0*4( hex4 ":" ) IPv4address /
|
21
|
+
( hex4 ":" ) ":" 0*5( hex4 ":" ) IPv4address /
|
22
|
+
"::" 0*6( hex4 ":" ) IPv4address
|
23
|
+
IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
|
24
|
+
hex4 = 1*4HEXDIG
|
25
|
+
End
|
26
|
+
|
data/sample/ipv6.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'abnf'
|
2
|
+
require 'pp'
|
3
|
+
|
4
|
+
# IPv6 [RFC2373]
|
5
|
+
# Note that this ABNF description is wrong: e.g. it doesn't match to "::13.1.68.3".
|
6
|
+
wrong = ABNF.regexp_tree(<<-'End')
|
7
|
+
IPv6address = hexpart [ ":" IPv4address ]
|
8
|
+
IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
|
9
|
+
hexpart = hexseq | hexseq "::" [ hexseq ] | "::" [ hexseq ]
|
10
|
+
hexseq = hex4 *( ":" hex4)
|
11
|
+
hex4 = 1*4HEXDIG
|
12
|
+
End
|
13
|
+
|
14
|
+
corrected = ABNF.regexp_tree(<<-'End')
|
15
|
+
IPv6address = "::" /
|
16
|
+
7( hex4 ":" ) hex4 /
|
17
|
+
1*8( hex4 ":" ) ":" /
|
18
|
+
7( hex4 ":" ) ( ":" hex4 ) /
|
19
|
+
6( hex4 ":" ) 1*2( ":" hex4 ) /
|
20
|
+
5( hex4 ":" ) 1*3( ":" hex4 ) /
|
21
|
+
4( hex4 ":" ) 1*4( ":" hex4 ) /
|
22
|
+
3( hex4 ":" ) 1*5( ":" hex4 ) /
|
23
|
+
2( hex4 ":" ) 1*6( ":" hex4 ) /
|
24
|
+
( hex4 ":" ) 1*7( ":" hex4 ) /
|
25
|
+
":" 1*8( ":" hex4 ) /
|
26
|
+
6( hex4 ":" ) IPv4address /
|
27
|
+
6( hex4 ":" ) ":" IPv4address /
|
28
|
+
5( hex4 ":" ) ":" 0*1( hex4 ":" ) IPv4address /
|
29
|
+
4( hex4 ":" ) ":" 0*2( hex4 ":" ) IPv4address /
|
30
|
+
3( hex4 ":" ) ":" 0*3( hex4 ":" ) IPv4address /
|
31
|
+
2( hex4 ":" ) ":" 0*4( hex4 ":" ) IPv4address /
|
32
|
+
( hex4 ":" ) ":" 0*5( hex4 ":" ) IPv4address /
|
33
|
+
"::" 0*6( hex4 ":" ) IPv4address
|
34
|
+
IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
|
35
|
+
hex4 = 1*4HEXDIG
|
36
|
+
End
|
37
|
+
|
38
|
+
pp wrong
|
39
|
+
pp corrected
|
40
|
+
|
41
|
+
p /\A#{wrong}\z/o =~ "::13.1.68.3"
|
42
|
+
p /\A#{corrected}\z/o =~ "::13.1.68.3"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'abnf'
|
2
|
+
require 'pp'
|
3
|
+
|
4
|
+
rt = ABNF.regexp_tree(<<'End')
|
5
|
+
s0 = n0 s0 / n1 s2 / n2 s1 / ""
|
6
|
+
s1 = n0 s1 / n1 s0 / n2 s2
|
7
|
+
s2 = n0 s2 / n1 s1 / n2 s0
|
8
|
+
n0 = "0" / "3" / "6" / "9"
|
9
|
+
n1 = "1" / "4" / "7"
|
10
|
+
n2 = "2" / "5" / "8"
|
11
|
+
End
|
12
|
+
|
13
|
+
pp rt
|
14
|
+
|
15
|
+
r = rt.regexp(true)
|
16
|
+
|
17
|
+
1000.times {|i|
|
18
|
+
print "error: #{i}\n" unless (r !~ i.to_s) == (i%3 != 0)
|
19
|
+
}
|
data/sample/uri.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'pp'
|
2
|
+
require 'abnf'
|
3
|
+
|
4
|
+
# URI-reference [RFC2396]
|
5
|
+
pp ABNF.regexp_tree(<<-'End')
|
6
|
+
URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
|
7
|
+
absoluteURI = scheme ":" ( hier_part | opaque_part )
|
8
|
+
relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
|
9
|
+
|
10
|
+
hier_part = ( net_path | abs_path ) [ "?" query ]
|
11
|
+
opaque_part = uric_no_slash *uric
|
12
|
+
|
13
|
+
uric_no_slash = escaped | unreserved | ";" | "?" | ":" | "@" |
|
14
|
+
"&" | "=" | "+" | "$" | ","
|
15
|
+
|
16
|
+
net_path = "//" authority [ abs_path ]
|
17
|
+
abs_path = "/" path_segments
|
18
|
+
rel_path = rel_segment [ abs_path ]
|
19
|
+
|
20
|
+
rel_segment = 1*( escaped | unreserved |
|
21
|
+
";" | "@" | "&" | "=" | "+" | "$" | "," )
|
22
|
+
|
23
|
+
scheme = alpha *( alpha | digit | "+" | "-" | "." )
|
24
|
+
|
25
|
+
authority = server | reg_name
|
26
|
+
|
27
|
+
reg_name = 1*( escaped | unreserved | "$" | "," |
|
28
|
+
";" | ":" | "@" | "&" | "=" | "+" )
|
29
|
+
|
30
|
+
server = [ [ userinfo "@" ] hostport ]
|
31
|
+
userinfo = *( escaped | unreserved |
|
32
|
+
";" | ":" | "&" | "=" | "+" | "$" | "," )
|
33
|
+
|
34
|
+
hostport = host [ ":" port ]
|
35
|
+
host = hostname | IPv4address
|
36
|
+
hostname = *( domainlabel "." ) toplabel [ "." ]
|
37
|
+
domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
|
38
|
+
toplabel = alpha | alpha *( alphanum | "-" ) alphanum
|
39
|
+
IPv4address = 1*digit "." 1*digit "." 1*digit "." 1*digit
|
40
|
+
port = *digit
|
41
|
+
|
42
|
+
path = [ abs_path | opaque_part ]
|
43
|
+
path_segments = segment *( "/" segment )
|
44
|
+
segment = *pchar *( ";" param )
|
45
|
+
param = *pchar
|
46
|
+
pchar = escaped | unreserved |
|
47
|
+
":" | "@" | "&" | "=" | "+" | "$" | ","
|
48
|
+
|
49
|
+
query = *uric
|
50
|
+
|
51
|
+
fragment = *uric
|
52
|
+
|
53
|
+
uric = reserved | unreserved | escaped
|
54
|
+
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
|
55
|
+
"$" | ","
|
56
|
+
unreserved = alphanum | mark
|
57
|
+
mark = "-" | "_" | "." | "!" | "~" | "*" | "'" |
|
58
|
+
"(" | ")"
|
59
|
+
|
60
|
+
escaped = "%" hex hex
|
61
|
+
hex = digit | "A" | "B" | "C" | "D" | "E" | "F" |
|
62
|
+
"a" | "b" | "c" | "d" | "e" | "f"
|
63
|
+
|
64
|
+
alphanum = alpha | digit
|
65
|
+
alpha = lowalpha | upalpha
|
66
|
+
|
67
|
+
lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" |
|
68
|
+
"j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" |
|
69
|
+
"s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
|
70
|
+
upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" |
|
71
|
+
"J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" |
|
72
|
+
"S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"
|
73
|
+
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
|
74
|
+
"8" | "9"
|
75
|
+
End
|
data/test/abnf_test.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'abnf'
|
2
|
+
|
3
|
+
class TestABNF < Test::Unit::TestCase
|
4
|
+
def test_non_recursion_1
|
5
|
+
assert_equal(/a/i, ABNF.regexp(<<-'End'))
|
6
|
+
n = "a"
|
7
|
+
End
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_left_recursion_1
|
11
|
+
assert_equal(/ab*/i, ABNF.regexp(<<-'End'))
|
12
|
+
n = "a" | n "b"
|
13
|
+
End
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_left_recursion_2
|
17
|
+
assert_equal(/ab*/i, ABNF.regexp(<<-'End'))
|
18
|
+
n = "a" | n2 "b"
|
19
|
+
n2 = n
|
20
|
+
End
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_left_recursion_3
|
24
|
+
assert_equal(/ac(?:bc)*/i, ABNF.regexp(<<-'End'))
|
25
|
+
n = ("a" | n "b") "c"
|
26
|
+
End
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_right_recursion_1
|
30
|
+
assert_equal(/b*a/i, ABNF.regexp(<<-'End'))
|
31
|
+
n = "a" | "b" n
|
32
|
+
End
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_both_recursion_1
|
36
|
+
assert_equal(/a*bc*/i, ABNF.regexp(<<-'End'))
|
37
|
+
n = "a" n | "b" | n "c"
|
38
|
+
End
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_both_recursion_2
|
42
|
+
assert_equal(/a*bc*/i, ABNF.regexp(<<-'End'))
|
43
|
+
n = "a" n | "b" | n "c" | n
|
44
|
+
End
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_unreachable_1
|
48
|
+
assert_equal([:s, :n], ABNF.parse(<<-'End').delete_unreachable!([:s]).names)
|
49
|
+
s = "a" | n
|
50
|
+
n = "b"
|
51
|
+
m = "c"
|
52
|
+
End
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_useless_1
|
56
|
+
assert_equal([:s, :n], ABNF.parse(<<-'End').delete_useless!(:s).names)
|
57
|
+
s = "a" | n
|
58
|
+
n = "b"
|
59
|
+
m = "c"
|
60
|
+
End
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_useless_2
|
64
|
+
assert_equal([:s, :n], ABNF.parse(<<-'End').delete_useless!(:s).names)
|
65
|
+
s = "a" | n | x
|
66
|
+
n = "b"
|
67
|
+
x = y
|
68
|
+
y = x
|
69
|
+
m = "c"
|
70
|
+
End
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_too_complex
|
74
|
+
assert_raises(ABNF::TooComplex) { ABNF.regexp_tree(<<-End) }
|
75
|
+
s = "" | "a" s "b"
|
76
|
+
End
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_case_insensitive_inspect
|
80
|
+
assert_equal("%r/a/", ABNF.regexp_tree("A = %d97").inspect)
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'regexptree'
|
2
|
+
|
3
|
+
class TestRegexpTree < Test::Unit::TestCase
|
4
|
+
def test_whitespace
|
5
|
+
assert_equal('(?i-m:\x20\t\n\x23)', RegexpTree.str("\s\t\n#").to_s)
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_case_insensitive
|
9
|
+
assert_equal(true, (RegexpTree.str("a")|RegexpTree.str("A")).case_insensitive?)
|
10
|
+
assert_equal(false, (RegexpTree.str("a")|RegexpTree.str("b")).case_insensitive?)
|
11
|
+
end
|
12
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: abnf
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Steve Klabnik
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-05-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: racc
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: An Augmented Backus Naur form parser in Ruby.
|
56
|
+
email:
|
57
|
+
- steve@steveklabnik.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- .gitignore
|
63
|
+
- .travis.yml
|
64
|
+
- Gemfile
|
65
|
+
- LICENSE.txt
|
66
|
+
- README.md
|
67
|
+
- Rakefile
|
68
|
+
- abnf.gemspec
|
69
|
+
- lib/abnf.rb
|
70
|
+
- lib/abnf/abnf.rb
|
71
|
+
- lib/abnf/corerules.rb
|
72
|
+
- lib/abnf/grammar.rb
|
73
|
+
- lib/abnf/parser.output
|
74
|
+
- lib/abnf/parser.rb
|
75
|
+
- lib/abnf/parser.y
|
76
|
+
- lib/abnf/regexp.rb
|
77
|
+
- lib/abnf/version.rb
|
78
|
+
- lib/natset.rb
|
79
|
+
- lib/regexptree.rb
|
80
|
+
- sample/in-place.rb
|
81
|
+
- sample/ipv6.rb
|
82
|
+
- sample/multiples-of-3.rb
|
83
|
+
- sample/uri.rb
|
84
|
+
- test/abnf_test.rb
|
85
|
+
- test/regexptree_test.rb
|
86
|
+
- test/test_helper.rb
|
87
|
+
homepage: https://github.com/steveklabnik/abnf
|
88
|
+
licenses:
|
89
|
+
- MIT
|
90
|
+
metadata: {}
|
91
|
+
post_install_message:
|
92
|
+
rdoc_options: []
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - '>='
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - '>='
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
requirements: []
|
106
|
+
rubyforge_project:
|
107
|
+
rubygems_version: 2.0.0
|
108
|
+
signing_key:
|
109
|
+
specification_version: 4
|
110
|
+
summary: An Augmented Backus Naur form parser in Ruby.
|
111
|
+
test_files:
|
112
|
+
- test/abnf_test.rb
|
113
|
+
- test/regexptree_test.rb
|
114
|
+
- test/test_helper.rb
|
115
|
+
has_rdoc:
|