panini 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+