rley 0.0.12 → 0.0.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/CHANGELOG.md +6 -0
- data/lib/rley/constants.rb +1 -1
- data/lib/rley/syntax/grammar.rb +40 -11
- data/spec/rley/syntax/grammar_spec.rb +31 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NTdmZDFiY2U1OTE3NDVkOTQ5NDU5OTY4YjAyZWY5MTZhNmE4ZmU5OQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZDdjZTA5ZjEwMGNhM2ZlZjIyYjg1ZDliM2E5NjNmZWIzYmU0YjRmZA==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YmNlNWU1Y2NkOGE1NmI4Y2YyYzkzMzRiYjY1NGNhNDNiMDQyMzMzNTI3ZWY2
|
10
|
+
ZjdjZGRlZjY4ZTI2NDdkNTViYTA5ZDUxOGE3YTY3NzZkMDQ5YjFjNzlmMTU1
|
11
|
+
YmRlMGVjNmU3ODMzN2MxMzRlYTU0YTVhMzhiYWY4NzcwZmQyYTQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MzA2ODE1MWZjN2I3ZDAxNTAzZmQ4YzNhYzJlZGU4NmU0OGEzYjI0MzEzZjBh
|
14
|
+
ZmI4NzMyYzEyMDlkZDcwNDRkMzk1YzM2NTc4YjhmNzUzZDEwYmRmNDQxMmIw
|
15
|
+
OTI4N2NmZmVjNzM1OGVhNDY4MzFmMWJhNWE3NWZjZDM3Y2QxZjQ=
|
data/CHANGELOG.md
CHANGED
@@ -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
|
data/lib/rley/constants.rb
CHANGED
data/lib/rley/syntax/grammar.rb
CHANGED
@@ -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
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
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
|
-
|
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
|
-
|
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.
|
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-
|
11
|
+
date: 2014-11-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|