panini 1.0.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.
@@ -0,0 +1,90 @@
1
+ require "spec_helper"
2
+
3
+
4
+ describe Panini::DerivationStrategy::RandomDampened do
5
+ it_behaves_like "basic derivation strategy"
6
+ end
7
+
8
+
9
+ describe Panini::DerivationStrategy::RandomDampened do
10
+
11
+ before (:each) do
12
+ @g = Panini::Grammar.new.tap do |grammar|
13
+ grammar.add_nonterminal.add_production([])
14
+ end
15
+ end
16
+
17
+ it "raises an exception if the damping factor is too small" do
18
+ lambda { described_class.new(@g, 1.0) }.should raise_error(ArgumentError, "The damping factor must be greater than 0.0 and less than 1.0.")
19
+ end
20
+
21
+ it "raises an exception if the damping factor is too large" do
22
+ lambda { described_class.new(@g, 0.0) }.should raise_error(ArgumentError, "The damping factor must be greater than 0.0 and less than 1.0.")
23
+ end
24
+
25
+ end
26
+
27
+ describe Panini::DerivationStrategy::RandomDampened, "sentence with an arethmetic expression grammar" do
28
+
29
+ before(:each) do
30
+ @grammar = Panini::Grammar.new
31
+
32
+ expression = @grammar.add_nonterminal
33
+ term = @grammar.add_nonterminal
34
+ factor = @grammar.add_nonterminal
35
+ identifier = @grammar.add_nonterminal
36
+ number = @grammar.add_nonterminal
37
+
38
+
39
+ # =============
40
+ # = Terminals =
41
+ # =============
42
+ expression.add_production([term, '+', term])
43
+ expression.add_production([term, '-', term])
44
+ expression.add_production([term])
45
+
46
+ term.add_production([factor, '*', term])
47
+ term.add_production([factor, '/', term])
48
+ term.add_production([factor])
49
+
50
+ factor.add_production([identifier])
51
+ factor.add_production([number])
52
+ factor.add_production(['(', expression, ')'])
53
+
54
+ ('a'..'z').each do |v|
55
+ identifier.add_production([v])
56
+ end
57
+
58
+ (0..100).each do |n|
59
+ number.add_production([n])
60
+ end
61
+
62
+ Kernel::stub(:rand).and_return(0.3)
63
+ end
64
+
65
+ context "with very little damping" do
66
+
67
+ before(:each) do
68
+ @deriver = described_class.new(@grammar, 0.999999999999)
69
+ end
70
+
71
+ it "encounters a stack error" do
72
+ lambda { @deriver.sentence }.should raise_error(SystemStackError)
73
+ end
74
+
75
+ end
76
+
77
+ context "with damping" do
78
+
79
+ before(:each) do
80
+ @deriver = described_class.new(@grammar)
81
+ end
82
+
83
+ it "returns an expected sentence" do
84
+ @deriver.sentence.should == ["h", "*", "h", "/", "h", "/", "h", "+", "h", "*", "h", "/", "h", "/", "h"]
85
+ end
86
+
87
+ end
88
+
89
+
90
+ end
@@ -0,0 +1,59 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+
4
+ describe "Grammar" do
5
+
6
+ before (:each) do
7
+ @g = Panini::Grammar.new
8
+ end
9
+
10
+ it "responds to #add_nonterminal" do
11
+ @g.should respond_to(:add_nonterminal)
12
+ end
13
+
14
+ it "responds to #nonterminals" do
15
+ @g.should respond_to(:nonterminals)
16
+ end
17
+
18
+ it "responds to #start" do
19
+ @g.should respond_to(:start)
20
+ end
21
+
22
+ end
23
+
24
+
25
+
26
+ describe "Grammar#add_nonterminal" do
27
+
28
+ before (:each) do
29
+ @g = Panini::Grammar.new
30
+ @n = @g.add_nonterminal()
31
+ end
32
+
33
+ it "returns a new Panini::Nonterminal" do
34
+ @n.should be_an_instance_of(Panini::Nonterminal)
35
+ end
36
+
37
+ it "stores the new Panini::Nonterminal" do
38
+ @g.nonterminals.should have(1).item
39
+ @g.nonterminals[0].should == @n
40
+ end
41
+
42
+ end
43
+
44
+
45
+
46
+ describe "Grammar#start" do
47
+
48
+ before (:each) do
49
+ @g = Panini::Grammar.new
50
+ @nonterminals = (0...3).to_a.map do
51
+ @g.add_nonterminal
52
+ end
53
+ end
54
+
55
+ it "returns the first nonterminal" do
56
+ @g.start.should == @nonterminals[0]
57
+ end
58
+
59
+ end
@@ -0,0 +1,79 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+
4
+ describe "Nonterminal" do
5
+
6
+ before (:each) do
7
+ @n = Panini::Nonterminal.new
8
+ end
9
+
10
+ it "responds to #add_production" do
11
+ @n.should respond_to(:add_production)
12
+ end
13
+
14
+ it "responds to #productions" do
15
+ @n.should respond_to(:productions)
16
+ end
17
+
18
+ end
19
+
20
+
21
+ describe "Nonterminal#add_production with a non-Array arument" do
22
+
23
+ before (:each) do
24
+ @n = Panini::Nonterminal.new
25
+ end
26
+
27
+ it "throws an error" do
28
+ lambda { @n.add_production('a') }.should raise_error(ArgumentError, "The production must be an Array.")
29
+ end
30
+
31
+ end
32
+
33
+
34
+ describe "Nonterminal#add_production with a single production" do
35
+
36
+ before (:each) do
37
+ @n = Panini::Nonterminal.new
38
+ @p = @n.add_production(['a', 'b', 'c'])
39
+ end
40
+
41
+ it "returns nil" do
42
+ @p.should be_nil
43
+ end
44
+
45
+ it "stores the production" do
46
+ @n.productions.should have(1).item
47
+ @n.productions[0].should == ['a', 'b', 'c']
48
+ end
49
+
50
+ end
51
+
52
+
53
+
54
+ describe "Nonterminal#add_production with two productions" do
55
+
56
+ before (:each) do
57
+ @n = Panini::Nonterminal.new
58
+ @p1 = @n.add_production(['a', 'b', 'c'])
59
+ @p2 = @n.add_production(['x', 'y', 'z'])
60
+ end
61
+
62
+ it "returns nil" do
63
+ @p1.should be_nil
64
+ @p2.should be_nil
65
+ end
66
+
67
+ it "stores the productions" do
68
+ @n.productions.should have(2).items
69
+ end
70
+
71
+ it "stores the first one added first" do
72
+ @n.productions[0].should == ['a', 'b', 'c']
73
+ end
74
+
75
+ it "stores the second one added last" do
76
+ @n.productions[1].should == ['x', 'y', 'z']
77
+ end
78
+
79
+ end
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'panini'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
@@ -0,0 +1,85 @@
1
+ require "spec_helper"
2
+
3
+ # Some basic tests to make sure that a strategy can deal with trivial
4
+ # grammars. Since these grammars can only create a single sentence, all
5
+ # strategies should work.
6
+
7
+ shared_examples_for "basic derivation strategy" do
8
+
9
+ describe "with the production S -> _epsilon_" do
10
+
11
+ before (:each) do
12
+ @g = Panini::Grammar.new
13
+ @n = @g.add_nonterminal
14
+ @n.add_production([])
15
+ end
16
+
17
+ it "generates an empty sentence" do
18
+ d = described_class.new(@g)
19
+ d.sentence.should be_empty
20
+ end
21
+
22
+ end
23
+
24
+
25
+ describe "with the production S -> 'a'" do
26
+
27
+ before (:each) do
28
+ @g = Panini::Grammar.new
29
+ @n = @g.add_nonterminal
30
+ @n.add_production(['a'])
31
+ end
32
+
33
+ it "generates the sentence ['a']" do
34
+ d = described_class.new(@g)
35
+ d.sentence.should == ['a']
36
+ end
37
+
38
+ end
39
+
40
+
41
+
42
+ describe "with the productions S -> A, A -> 'a'" do
43
+
44
+ before (:each) do
45
+ @g = Panini::Grammar.new
46
+
47
+ @n_s = @g.add_nonterminal
48
+ @n_a = @g.add_nonterminal
49
+
50
+ @n_s.add_production([@n_a])
51
+ @n_a.add_production(['a'])
52
+ end
53
+
54
+ it "generates the sentence ['a']" do
55
+ d = described_class.new(@g)
56
+ d.sentence.should == ['a']
57
+ end
58
+
59
+ end
60
+
61
+
62
+
63
+ describe "with the productions S -> AB, A -> 'a', B -> 'b'" do
64
+
65
+ before (:each) do
66
+ @g = Panini::Grammar.new
67
+
68
+ @n_s = @g.add_nonterminal
69
+ @n_a = @g.add_nonterminal
70
+ @n_b = @g.add_nonterminal
71
+
72
+ @n_s.add_production([@n_a, @n_b])
73
+ @n_a.add_production(['a'])
74
+ @n_b.add_production(['b'])
75
+ end
76
+
77
+ it "generates the sentence ['a', 'b']" do
78
+ d = described_class.new(@g)
79
+ d.sentence.should == ['a', 'b']
80
+ end
81
+
82
+ end
83
+
84
+
85
+ end
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: panini
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 0
9
+ version: 1.0.0
10
+ platform: ruby
11
+ authors:
12
+ - mjbellantoni
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-05-16 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 2
29
+ - 3
30
+ - 0
31
+ version: 2.3.0
32
+ type: :development
33
+ prerelease: false
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: bundler
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ~>
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 1
44
+ - 0
45
+ - 0
46
+ version: 1.0.0
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: jeweler
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ~>
56
+ - !ruby/object:Gem::Version
57
+ segments:
58
+ - 1
59
+ - 6
60
+ - 0
61
+ version: 1.6.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: rcov
67
+ requirement: &id004 !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: *id004
78
+ description: Panini allows you to generate sentences from a context-free grammar, also known as a CFG.
79
+ email: mjbellantoni@yahoo.com
80
+ executables: []
81
+
82
+ extensions: []
83
+
84
+ extra_rdoc_files:
85
+ - LICENSE.txt
86
+ - README.rdoc
87
+ files:
88
+ - .document
89
+ - .rspec
90
+ - Gemfile
91
+ - Gemfile.lock
92
+ - LICENSE.txt
93
+ - README.rdoc
94
+ - Rakefile
95
+ - VERSION
96
+ - examples/arithmetic_expression.rb
97
+ - lib/derivation_strategy/base.rb
98
+ - lib/derivation_strategy/leftmost.rb
99
+ - lib/derivation_strategy/random_dampened.rb
100
+ - lib/grammar.rb
101
+ - lib/hash.rb
102
+ - lib/nonterminal.rb
103
+ - lib/panini.rb
104
+ - panini.gemspec
105
+ - spec/derivation_strategy/dampened_probability_production_choice_proxy_spec.rb
106
+ - spec/derivation_strategy/leftmost_spec.rb
107
+ - spec/derivation_strategy/random_dampened_spec.rb
108
+ - spec/grammar_spec.rb
109
+ - spec/nonterminal_spec.rb
110
+ - spec/spec_helper.rb
111
+ - spec/support/basic_derivation_strategy_shared_example.rb
112
+ has_rdoc: true
113
+ homepage: http://github.com/mjbellantoni/panini
114
+ licenses:
115
+ - MIT
116
+ post_install_message:
117
+ rdoc_options: []
118
+
119
+ require_paths:
120
+ - lib
121
+ required_ruby_version: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ hash: 286269899475831067
127
+ segments:
128
+ - 0
129
+ version: "0"
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ segments:
136
+ - 0
137
+ version: "0"
138
+ requirements: []
139
+
140
+ rubyforge_project:
141
+ rubygems_version: 1.3.7
142
+ signing_key:
143
+ specification_version: 3
144
+ summary: Create sentences from a context-free grammar (CFG)
145
+ test_files: []
146
+