rbnf 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2012 Feivel Jellyfish
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,41 @@
1
+ RBNF
2
+ ----
3
+ RBNF is an Extended Backus-Naur Form implementation for Ruby.
4
+
5
+ Installation
6
+ ============
7
+ ```shell
8
+ gem install rbnf
9
+ ```
10
+
11
+ Usage
12
+ =====
13
+ ```ruby
14
+ form = RBNF[?a] / ?b / ?c #=> '"a" | "b" | "c"'
15
+ form2 = RBNF[?a].cat('b').alt('c') #=> '( "a" , "b" ) | "c"'
16
+ ```
17
+ RBNF objects can be used to perform regex-like matches on strings. The first form will match the same strings as /[abc]/ :
18
+ ```ruby
19
+ form =~ 'a' #=> true
20
+ form =~ 'b' #=> true
21
+ form =~ 'd' #=> false
22
+ form =~ 'ab' #=> false
23
+ ```
24
+ RBNFs can also accomplish matches that regexes can't:
25
+
26
+ ```ruby
27
+ RBNF.define :parens do
28
+ RBNF[?(] + RBNF.parens.opt + ?)
29
+ end
30
+
31
+ RBNF.parens =~ '()' #=> true
32
+ RBNF.parens =~ '(())' #=> true
33
+ RBNF.parens =~ '(()))' #=> false
34
+
35
+ ```
36
+ RBNF objects memoize matches, but otherwise make no attempt at optimizing for performance.
37
+
38
+ License
39
+ =======
40
+ X11. See LICENSE for details.
41
+
data/Rakefile CHANGED
@@ -1,7 +1,8 @@
1
1
  $LOAD_PATH << File.expand_path('../lib', __FILE__)
2
2
  require 'rake'
3
- require 'graham/rake_task'
3
+ require 'lax'
4
+ require 'rbnf'
4
5
 
5
- Graham::RakeTask.new
6
+ Lax::RakeTask.new
6
7
  task default: :test
7
8
 
@@ -1,36 +1,45 @@
1
1
  require 'rbnf/version'
2
2
  require 'rbnf/nodes'
3
3
  module RBNF
4
+ # Namespace for defined forms.
4
5
  DEFS = {}
5
6
 
7
+ # [ "a" ]
6
8
  def opt
7
9
  Opt.new self
8
10
  end
9
11
 
12
+ # "a" , "b"
10
13
  def cat(f)
11
14
  Cat.new self, ebnify(f)
12
15
  end
13
16
 
17
+ # "a" | "b"
14
18
  def alt(f)
15
19
  Alt.new self, ebnify(f)
16
20
  end
17
21
 
22
+ # a - "b"
18
23
  def except(f)
19
24
  Except.new self, ebnify(f)
20
25
  end
21
26
 
27
+ # { "a" }
22
28
  def rep
23
29
  Rep.new self
24
30
  end
25
31
 
32
+ # b * "a"
26
33
  def rep_n(n)
27
34
  RepN.new self, n
28
35
  end
29
36
 
37
+ # ( "a" )
30
38
  def group
31
39
  Group.new self
32
40
  end
33
41
 
42
+ # String match with memoization.
34
43
  def =~(s)
35
44
  @memo.has_key?(s) ? @memo[s] : (@memo[s] = match s)
36
45
  end
@@ -66,7 +75,7 @@ module RBNF
66
75
  # the contents of the block. Note that this method can't handle recursive
67
76
  # form definition; use ::define for that instead.
68
77
  def def(name)
69
- DEFS[name] = Def.new(name, yield)
78
+ DEFS[name] = Def.new name, yield
70
79
  end
71
80
 
72
81
  # Takes a symbol <name> and a block and defines a new form <name> to be
@@ -1,5 +1,6 @@
1
1
  module RBNF
2
2
 
3
+ # Unary AST node
3
4
  class Unary
4
5
  include RBNF
5
6
  attr_reader :a
@@ -8,6 +9,7 @@ module RBNF
8
9
  end
9
10
  end
10
11
 
12
+ # Binary AST node
11
13
  class Binary
12
14
  include RBNF
13
15
  attr_reader :a,:b
@@ -16,6 +18,7 @@ module RBNF
16
18
  end
17
19
  end
18
20
 
21
+ # Alternation node
19
22
  class Alt < Binary
20
23
  def to_s
21
24
  "#{a} | #{b}"
@@ -29,6 +32,7 @@ module RBNF
29
32
  end
30
33
  end
31
34
 
35
+ # Node that encapsulates a defined (with RBNF::def or ::define) form.
32
36
  class Def < Binary
33
37
  def to_s
34
38
  "#{a}"
@@ -38,6 +42,7 @@ module RBNF
38
42
  end
39
43
  end
40
44
 
45
+ # Catenation node
41
46
  class Cat < Binary
42
47
  def to_s
43
48
  "#{a} , #{b}"
@@ -47,6 +52,7 @@ module RBNF
47
52
  end
48
53
  end
49
54
 
55
+ # Optation node
50
56
  class Opt < Unary
51
57
  def to_s
52
58
  "[ #{a} ]"
@@ -56,6 +62,8 @@ module RBNF
56
62
  end
57
63
  end
58
64
 
65
+ # Grouping node. Semantically identical to its child, but greatly simplifies
66
+ # stringification.
59
67
  class Group < Unary
60
68
  def to_s
61
69
  "( #{a} )"
@@ -65,6 +73,7 @@ module RBNF
65
73
  end
66
74
  end
67
75
 
76
+ # Exception node
68
77
  class Except < Binary
69
78
  def to_s
70
79
  "( #{a} - #{b} )"
@@ -74,6 +83,7 @@ module RBNF
74
83
  end
75
84
  end
76
85
 
86
+ # Repetition (0 or more times) node
77
87
  class Rep < Unary
78
88
  def to_s
79
89
  "{ #{a} }"
@@ -83,6 +93,7 @@ module RBNF
83
93
  end
84
94
  end
85
95
 
96
+ # Repetition (n times) node
86
97
  class RepN < Binary
87
98
  def to_s
88
99
  "#{b} * #{a}"
@@ -98,6 +109,7 @@ module RBNF
98
109
  end
99
110
  end
100
111
 
112
+ # Terminal node
101
113
  class Term < Unary
102
114
  def to_s
103
115
  "\"#{a}\""
@@ -1,3 +1,3 @@
1
1
  module RBNF
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
@@ -7,11 +7,12 @@ Gem::Specification.new do |spec|
7
7
  spec.version = RBNF::VERSION
8
8
  spec.author = 'feivel jellyfish'
9
9
  spec.email = 'feivel@sdf.org'
10
- spec.files = FileList['rbnf.gemspec','lib/**/*.rb']
10
+ spec.files = FileList['rbnf.gemspec','lib/**/*.rb','README.md','LICENSE']
11
11
  spec.test_files = FileList['Rakefile','test/**/*.rb']
12
- spec.homepage = 'http://github.com/gwentacle/ebnf'
12
+ spec.homepage = 'http://github.com/gwentacle/rbnf'
13
13
  spec.summary = 'Extended Backus-Naur Form implementation for Ruby'
14
14
  spec.description = 'Extended Backus-Naur Form implementation for Ruby'
15
- spec.add_development_dependency 'graham', '>=0.0.3'
15
+ spec.license = 'MIT/X11'
16
+ spec.add_development_dependency 'lax', '>=0.0.1'
16
17
  end
17
18
 
@@ -1,5 +1,3 @@
1
- require 'rbnf'
2
-
3
1
  class DefTests
4
2
  def simple_definition
5
3
  RBNF.def :abc do
@@ -14,18 +12,20 @@ class DefTests
14
12
  RBNF.parens
15
13
  end
16
14
  end
17
- Graham.pp(DefTests.new) do |that|
18
- that.recursive_definition.is_such_that {
19
- %w{() (())}.all? {|s| match s} and
20
- %w{( ) (()}.none? {|s| match s}}
21
15
 
22
- that.simple_definition.is_such_that {
16
+ Lax.test(DefTests.new) {|assert|
17
+ assert.calling(:recursive_definition).satisfies {|defn|
18
+ %w{() (())}.all? {|s| defn=~s} and
19
+ %w{( ) (()}.none? {|s| defn=~s}
20
+ }
21
+ assert.calling(:simple_definition).satisfies {|defn|
23
22
  (0..5).all? do |n|
24
23
  %w{a b c}.permutation(n).all? do |p|
25
24
  s = p.join
26
- !!(s=~/[abc]*/) == match(s)
25
+ !!(s=~/[abc]*/) == defn.match(s)
27
26
  end
28
27
  end
29
28
  }
30
- end
29
+
30
+ }
31
31
 
@@ -1,9 +1,3 @@
1
- class MatchTests
2
- def a_long_match
3
- +(RBNF[?a]*3)+?g =~ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag'
4
- end
5
- end
6
-
7
- Graham.pp(MatchTests.new) do |that|
8
- that.a_long_match.is true
9
- end
1
+ Lax.test(+(RBNF[?a]*3)+?g =~ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag') {|that|
2
+ that.it.returns true
3
+ }
@@ -1,4 +1,3 @@
1
- require 'rbnf'
2
1
  class Repetition
3
2
  def a_binary_repetition
4
3
  RBNF[?A]*3+?G
@@ -17,19 +16,17 @@ class Repetition
17
16
  end
18
17
  end
19
18
 
20
- Graham.pp(Repetition.new) do |that|
21
- that.a_binary_repetition.is_such_that {
22
- match('AAAG') and
23
- [?g,'AG','AAAAAAG'].none? {|s| match s}}
19
+ Lax.test(Repetition.new) {|that|
20
+ that.calling(:a_binary_repetition).satisfies {|rep|
21
+ rep =~ 'AAAG' and
22
+ [?g,'AG','AAAAAAG'].none? {|s| rep=~s}
23
+ }
24
+ that.calling(:a_unary_repetition).satisfies {|rep|
25
+ ['','xyz','xyzxyz'].all? {|s| rep.match s} and
26
+ [?x,?y,?z,'zyx'].none? {|s| rep.match s}
27
+ }
28
+ that.calling(:binary_repetition_zero_times).satisfies {|rep|
29
+ rep=~'' and !rep.match('q')
30
+ }
31
+ }
24
32
 
25
- that.a_unary_repetition.is_such_that {
26
- ['','xyz','xyzxyz'].all? {|s| match s} and
27
- [?x,?y,?z,'zyx'].none? {|s| match s}}
28
-
29
- that.binary_repetition_one_time.is_such_that {
30
- match('q') and !match('') and !match('qq')}
31
-
32
- that.binary_repetition_zero_times.is_such_that {
33
- match('') and !match('q') }
34
-
35
- end
@@ -54,17 +54,18 @@ class StringTests
54
54
 
55
55
  end
56
56
 
57
- Graham.pp(StringTests.new) do |that|
58
- that.a_definition.returns 'symbol'
59
- that.terminal_string.is '"string"'
60
- that.optation.returns '[ "string" ]'
61
- that.unary_repetition.returns '{ "string" }'
62
- that.binary_repetition.returns '3 * "string"'
63
- that.nested_repetition.returns '3 * { "string" }'
64
- that.alternation_and_catenation.returns '"string" | "opt" , "string" | "cat"'
65
- that.multiple_catenation.returns '"string" , "char" , "list"'
66
- that.multiple_alternation.returns '"string" | "char" | "list"'
67
- that.exception.returns '( "string" | "integer" - "float" )'
68
- that.grouping.returns '( "string" | "string" )'
69
- that.implicit_grouping.returns '( "string" , "string" ) | "string"'
70
- end
57
+ Lax.test(StringTests.new) {|_|
58
+ _.calling(:a_definition).returns 'symbol'
59
+ _.calling(:terminal_string).returns '"string"'
60
+ _.calling(:optation).returns '[ "string" ]'
61
+ _.calling(:unary_repetition).returns '{ "string" }'
62
+ _.calling(:binary_repetition).returns '3 * "string"'
63
+ _.calling(:nested_repetition).returns '3 * { "string" }'
64
+ _.calling(:alternation_and_catenation).returns '"string" | "opt" , "string" | "cat"'
65
+ _.calling(:multiple_catenation).returns '"string" , "char" , "list"'
66
+ _.calling(:multiple_alternation).returns '"string" | "char" | "list"'
67
+ _.calling(:exception).returns '( "string" | "integer" - "float" )'
68
+ _.calling(:grouping).returns '( "string" | "string" )'
69
+ _.calling(:implicit_grouping).returns '( "string" , "string" ) | "string"'
70
+ }
71
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbnf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,16 +9,16 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-29 00:00:00.000000000 Z
12
+ date: 2012-12-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: graham
15
+ name: lax
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: 0.0.3
21
+ version: 0.0.1
22
22
  type: :development
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
- version: 0.0.3
29
+ version: 0.0.1
30
30
  description: Extended Backus-Naur Form implementation for Ruby
31
31
  email: feivel@sdf.org
32
32
  executables: []
@@ -37,13 +37,16 @@ files:
37
37
  - lib/rbnf.rb
38
38
  - lib/rbnf/version.rb
39
39
  - lib/rbnf/nodes.rb
40
+ - README.md
41
+ - LICENSE
40
42
  - Rakefile
41
43
  - test/case/defs.rb
42
44
  - test/case/matches.rb
43
45
  - test/case/repetition.rb
44
46
  - test/case/stringification.rb
45
- homepage: http://github.com/gwentacle/ebnf
46
- licenses: []
47
+ homepage: http://github.com/gwentacle/rbnf
48
+ licenses:
49
+ - MIT/X11
47
50
  post_install_message:
48
51
  rdoc_options: []
49
52
  require_paths: