rley 0.0.12 → 0.0.13

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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YWJmOTI2YmJiNWQwNDY5YjM3ZTdmMzdlZmEyMDE0ODRiM2Q1N2Y4YQ==
4
+ NTdmZDFiY2U1OTE3NDVkOTQ5NDU5OTY4YjAyZWY5MTZhNmE4ZmU5OQ==
5
5
  data.tar.gz: !binary |-
6
- ZjNmODNiOWZlYTc3MzcyNGUzZDhiNWVhMTBjNDRjZmU2OTg3NTM4Yg==
6
+ ZDdjZTA5ZjEwMGNhM2ZlZjIyYjg1ZDliM2E5NjNmZWIzYmU0YjRmZA==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- OWRiMmM1NzQ3ZjdjZjAwYTZlNWFlYzgxMjliY2M2YzQ2MzZjMTNlMmE2NjI5
10
- YTAxNWNhMGMxMjY1ODU3NzI4YTFhNmNmNzkxMzAzNjUyMjZjZjBlM2U5ZDhi
11
- ZmY0MmU3ZTgxNmJjYTk3ZTc3MTg1MmFlYWNhYjhiMjJjOTljOTU=
9
+ YmNlNWU1Y2NkOGE1NmI4Y2YyYzkzMzRiYjY1NGNhNDNiMDQyMzMzNTI3ZWY2
10
+ ZjdjZGRlZjY4ZTI2NDdkNTViYTA5ZDUxOGE3YTY3NzZkMDQ5YjFjNzlmMTU1
11
+ YmRlMGVjNmU3ODMzN2MxMzRlYTU0YTVhMzhiYWY4NzcwZmQyYTQ=
12
12
  data.tar.gz: !binary |-
13
- NzQyYmYyNzc5ZmIyNTVjMWJkOTVjNzI5NzM2N2Y5N2ZkN2Y1NmRlODcwNjAz
14
- MzRiNGIyNGIxNGExMGJlNjY4ZjYxYTc5YTc4Mjg1ODEyZGEyNGExOTM3N2Iw
15
- ODFkMGU4MjIxNTZmZjczNWNiYjUzMjYwYTZhZjkxNTRmZjg2MmU=
13
+ MzA2ODE1MWZjN2I3ZDAxNTAzZmQ4YzNhYzJlZGU4NmU0OGEzYjI0MzEzZjBh
14
+ ZmI4NzMyYzEyMDlkZDcwNDRkMzk1YzM2NTc4YjhmNzUzZDEwYmRmNDQxMmIw
15
+ OTI4N2NmZmVjNzM1OGVhNDY4MzFmMWJhNWE3NWZjZDM3Y2QxZjQ=
@@ -1,5 +1,11 @@
1
+ ### 0.0.13 / 2014-11-19
2
+ * [NEW] (private) method `Grammar#compute_nullable` added.
3
+ * [CHANGE] `Grammar#initialize` constructor calls the method `Grammar#compute_nullable`
4
+
5
+
1
6
  ### 0.0.12 / 2014-11-17
2
7
  * [CHANGE] Classes `Terminal` and `NonTerminal` added new method nullable?
8
+ * [CHANGE] File `earley_parser_spec.rb`: Added spec with ambiguous grammar.
3
9
 
4
10
 
5
11
  ### 0.0.11 / 2014-11-16
@@ -3,7 +3,7 @@
3
3
 
4
4
  module Rley # Module used as a namespace
5
5
  # The version number of the gem.
6
- Version = '0.0.12'
6
+ Version = '0.0.13'
7
7
 
8
8
  # Brief description of the gem.
9
9
  Description = "Ruby implementation of the Earley's parsing algorithm"
@@ -1,3 +1,5 @@
1
+ require 'set'
2
+
1
3
  module Rley # This module is used as a namespace
2
4
  module Syntax # This module is used as a namespace
3
5
  # A grammar specifies the syntax of a language.
@@ -57,24 +59,51 @@ module Rley # This module is used as a namespace
57
59
  end
58
60
  end
59
61
 
62
+
60
63
  # For each non-terminal determine whether it is nullable or not.
64
+ # A nullable nonterminal is a nonterminal that can match an empty string.
61
65
  def compute_nullable()
62
- # Do the obvious cases
63
- rules.each do |prod|
64
- next unless prod.rhs.empty?
65
- prod.lhs.nullable = true
66
+ non_terminals.each { |nterm| nterm.nullable = false }
67
+ nullable_sets = [ direct_nullable ]
68
+
69
+ # Drop productions with one terminal in rhs or with a nullable lhs
70
+ filtered_rules = rules.reject do |prod|
71
+ prod.lhs.nullable? || prod.rhs.members.find do |symb|
72
+ symb.kind_of?(Terminal)
73
+ end
74
+ end
75
+
76
+ (1...non_terminals.size).each do |i|
77
+ new_nullables = Set.new
78
+ filtered_rules.each do |a_prod|
79
+ rhs_nullable = a_prod.rhs.members.all? do |symb|
80
+ nullable_sets[i-1].include? symb
81
+ end
82
+ if rhs_nullable
83
+ a_prod.lhs.nullable = true
84
+ new_nullables << a_prod.lhs
85
+ end
86
+ end
87
+ break if new_nullables.empty?
88
+ filtered_rules.reject! { |prod| prod.lhs.nullable? }
89
+ nullable_sets[i] = nullable_sets[i-1].merge(new_nullables)
66
90
  end
67
91
  end
68
- =begin
69
- prods4nonterm = productions.group_by { |prod| prod.lhs }
70
- prods4nonterm.each_pair do |(lhs, prods)|
71
92
 
72
93
 
73
- to_process = non_terminals.select { |nt| nt.nullable?.nil? }
94
+ # Return the set of nonterminals which have one of their
95
+ # production rules empty
96
+ def direct_nullable()
97
+ nullable = Set.new
98
+ # Direct nullable nonterminals correspond to empty productions
99
+ rules.each do |prod|
100
+ next unless prod.empty?
101
+ prod.lhs.nullable = true
102
+ nullable << prod.lhs
103
+ end
74
104
 
75
- until to_process.empty? do
76
-
77
- =end
105
+ return nullable
106
+ end
78
107
  end # class
79
108
  end # module
80
109
  end # module
@@ -143,6 +143,37 @@ module Rley # Open this namespace to avoid module qualifier prefixes
143
143
  expect(subject.non_terminals).to eq([nt_S, nt_A])
144
144
  end
145
145
  end # context
146
+
147
+ context 'Non-nullable grammar:' do
148
+ subject do
149
+ productions = [prod_S, prod_A1, prod_A2]
150
+ Grammar.new(productions)
151
+ end
152
+
153
+ it 'should mark all its nonterminals as non-nullable' do
154
+ nonterms = subject.non_terminals
155
+ nonterms.each do |nterm|
156
+ expect(nterm).not_to be_nullable
157
+ end
158
+ end
159
+ end # context
160
+
161
+ context 'Nullable grammars:' do
162
+ subject do
163
+ prod_A3 = Production.new(nt_A, [])
164
+ productions = [prod_S, prod_A1, prod_A2, prod_A3]
165
+ Grammar.new(productions)
166
+ end
167
+
168
+ it 'should mark its nullable nonterminals' do
169
+ # In the default grammar, all nonterminals are nullable
170
+ nonterms = subject.non_terminals
171
+ nonterms.each do |nterm|
172
+ expect(nterm).to be_nullable
173
+ end
174
+ end
175
+
176
+ end # context
146
177
 
147
178
  end # describe
148
179
  end # module
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rley
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.12
4
+ version: 0.0.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitri Geshef
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-17 00:00:00.000000000 Z
11
+ date: 2014-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake