rley 0.3.00 → 0.3.01
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 +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG.md +5 -0
- data/lib/rley/constants.rb +1 -1
- data/lib/rley/parser/parse_forest_builder.rb +8 -8
- data/lib/rley/parser/parse_forest_factory.rb +5 -3
- data/lib/rley/parser/parse_walker_factory.rb +9 -10
- data/spec/rley/parser/parse_forest_builder_spec.rb +8 -8
- data/spec/rley/parser/parse_forest_factory_spec.rb +6 -5
- data/spec/rley/parser/parse_walker_factory_spec.rb +8 -6
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a668b1310cdd11c57771b1c26a85418a129f4c7c
|
|
4
|
+
data.tar.gz: 81e9d24b519700e79b508e72c9f8ada5b24d04a0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0ed6712c6dcfaf69b5e445fee8694917bb50a93a0bf6fff05931146453f6c129bee9166b128227d0ddfe7798347f97989def511e379d34f185a83290d8feee38
|
|
7
|
+
data.tar.gz: e83de687d95f2622163e91265feee3d560da37f769a7b6176a4ba73b8b4874b2458a3539d96b67eb909961eee62ba180c71a37ced9e97146942f2c1a5ff87b7e
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
### 0.3.01 / 2016-10-23
|
|
2
|
+
* [CHANGED] Method `ParseWalkerFactory#build_walker`. Signature change in order prevent direct dependency on `GFGParsing` class.
|
|
3
|
+
* [CHANGED] Class `ParseForestBuilder`. Removal of `parsing` attribute, no direct dependency on `GFGParsing` class.
|
|
4
|
+
* [CHANGED] Internal changed to `ParseForestFactory` class.
|
|
5
|
+
|
|
1
6
|
### 0.3.00 / 2016-10-23
|
|
2
7
|
* [CHANGE] Many new classes. The gem bundles a second parser that copes with ambiguous grammars.
|
|
3
8
|
|
data/lib/rley/constants.rb
CHANGED
|
@@ -9,8 +9,8 @@ module Rley # This module is used as a namespace
|
|
|
9
9
|
# (say, a parse forest) from simpler objects (terminal and non-terminal
|
|
10
10
|
# nodes) and using a step by step approach.
|
|
11
11
|
class ParseForestBuilder
|
|
12
|
-
#
|
|
13
|
-
attr_reader(:
|
|
12
|
+
# The sequence of input tokens
|
|
13
|
+
attr_reader(:tokens)
|
|
14
14
|
|
|
15
15
|
# Link to forest object
|
|
16
16
|
attr_reader(:forest)
|
|
@@ -25,8 +25,8 @@ module Rley # This module is used as a namespace
|
|
|
25
25
|
# This is needed for synchronizing backtracking
|
|
26
26
|
attr_reader(:entry2path_to_alt)
|
|
27
27
|
|
|
28
|
-
def initialize(
|
|
29
|
-
@
|
|
28
|
+
def initialize(theTokens)
|
|
29
|
+
@tokens = theTokens
|
|
30
30
|
@curr_path = []
|
|
31
31
|
@entry2node = {}
|
|
32
32
|
@entry2path_to_alt = {}
|
|
@@ -66,7 +66,7 @@ private
|
|
|
66
66
|
if curr_path.empty?
|
|
67
67
|
# Build parse forest with root node derived from the
|
|
68
68
|
# accepting parse entry.
|
|
69
|
-
@forest = create_forest(anEntry)
|
|
69
|
+
@forest = create_forest(anEntry, anIndex)
|
|
70
70
|
else
|
|
71
71
|
# if current_parent node matches the lhs non-terminal of anEntry
|
|
72
72
|
# set its origin to the origin of its first child (if not yet assigned)
|
|
@@ -155,8 +155,8 @@ private
|
|
|
155
155
|
end
|
|
156
156
|
|
|
157
157
|
# Create an empty parse forest
|
|
158
|
-
def create_forest(anEntry)
|
|
159
|
-
full_range = { low: 0, high:
|
|
158
|
+
def create_forest(anEntry, anIndex)
|
|
159
|
+
full_range = { low: 0, high: anIndex }
|
|
160
160
|
root_node = create_non_terminal_node(anEntry, full_range)
|
|
161
161
|
return Rley::SPPF::ParseForest.new(root_node)
|
|
162
162
|
end
|
|
@@ -183,7 +183,7 @@ private
|
|
|
183
183
|
|
|
184
184
|
def create_token_node(anEntry, anIndex)
|
|
185
185
|
token_position = anIndex - 1
|
|
186
|
-
curr_token =
|
|
186
|
+
curr_token = tokens[token_position]
|
|
187
187
|
new_node = SPPF::TokenNode.new(curr_token, token_position)
|
|
188
188
|
candidate = add_node_to_forest(new_node)
|
|
189
189
|
entry2node[anEntry] = candidate
|
|
@@ -13,7 +13,7 @@ module Rley # This module is used as a namespace
|
|
|
13
13
|
def initialize(aParsingResult)
|
|
14
14
|
@parsing = aParsingResult
|
|
15
15
|
end
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
# Factory that produces the parse forest
|
|
18
18
|
def build_parse_forest()
|
|
19
19
|
a_walker = walker(parsing)
|
|
@@ -39,13 +39,15 @@ private
|
|
|
39
39
|
# of a GFGParsing
|
|
40
40
|
def walker(aParseResult)
|
|
41
41
|
walker_factory = ParseWalkerFactory.new
|
|
42
|
-
|
|
42
|
+
accept_entry = aParseResult.accepting_entry
|
|
43
|
+
accept_index = aParseResult.chart.last_index
|
|
44
|
+
walker = walker_factory.build_walker(accept_entry, accept_index)
|
|
43
45
|
end
|
|
44
46
|
|
|
45
47
|
# Create a Builder, that is, an object
|
|
46
48
|
# that will create piece by piece the forest
|
|
47
49
|
def builder(aParseResult)
|
|
48
|
-
ParseForestBuilder.new(aParseResult)
|
|
50
|
+
ParseForestBuilder.new(aParseResult.tokens)
|
|
49
51
|
end
|
|
50
52
|
end # class
|
|
51
53
|
end # module
|
|
@@ -35,10 +35,9 @@ module Rley # This module is used as a namespace
|
|
|
35
35
|
class ParseWalkerFactory
|
|
36
36
|
# Build an Enumerator that will yield the parse entries as it
|
|
37
37
|
# walks backwards on the parse graph
|
|
38
|
-
def build_walker(
|
|
38
|
+
def build_walker(acceptingEntry, maxIndex)
|
|
39
39
|
# Local context for the enumerator
|
|
40
|
-
|
|
41
|
-
ctx = init_context(aParseResult)
|
|
40
|
+
ctx = init_context(acceptingEntry, maxIndex)
|
|
42
41
|
|
|
43
42
|
walker = Enumerator.new do |receiver| # 'receiver' is a Yielder
|
|
44
43
|
# At this point: current entry == accepting entry
|
|
@@ -56,7 +55,7 @@ module Rley # This module is used as a namespace
|
|
|
56
55
|
end
|
|
57
56
|
end
|
|
58
57
|
|
|
59
|
-
result = jump_to_antecedent(ctx
|
|
58
|
+
result = jump_to_antecedent(ctx)
|
|
60
59
|
# Emit detection of scan edge if any...
|
|
61
60
|
receiver << result[0] if result.size > 1
|
|
62
61
|
ctx.curr_entry = result.last
|
|
@@ -68,10 +67,10 @@ module Rley # This module is used as a namespace
|
|
|
68
67
|
|
|
69
68
|
private
|
|
70
69
|
# Context factory method
|
|
71
|
-
def init_context(
|
|
70
|
+
def init_context(acceptingEntry, maxIndex)
|
|
72
71
|
context = ParseWalkerContext.new
|
|
73
|
-
context.entry_set_index =
|
|
74
|
-
context.curr_entry =
|
|
72
|
+
context.entry_set_index = maxIndex
|
|
73
|
+
context.curr_entry = acceptingEntry
|
|
75
74
|
context.visitees = Set.new
|
|
76
75
|
context.nterm2start = {}
|
|
77
76
|
context.return_stack = []
|
|
@@ -125,12 +124,12 @@ private
|
|
|
125
124
|
# Given the current entry from context object
|
|
126
125
|
# Go to the parse entry that is one of its antecedent
|
|
127
126
|
# The context object is updated
|
|
128
|
-
def jump_to_antecedent(aContext
|
|
127
|
+
def jump_to_antecedent(aContext)
|
|
129
128
|
entries = []
|
|
130
129
|
return entries if aContext.curr_entry.orphan?
|
|
131
130
|
|
|
132
131
|
if aContext.curr_entry.antecedents.size == 1
|
|
133
|
-
entries = antecedent_of(aContext
|
|
132
|
+
entries = antecedent_of(aContext)
|
|
134
133
|
else
|
|
135
134
|
entries = select_antecedent(aContext)
|
|
136
135
|
end
|
|
@@ -139,7 +138,7 @@ private
|
|
|
139
138
|
end
|
|
140
139
|
|
|
141
140
|
# Handle the case of an entry having one antecedent only
|
|
142
|
-
def antecedent_of(aContext
|
|
141
|
+
def antecedent_of(aContext)
|
|
143
142
|
new_entry = aContext.curr_entry.antecedents.first
|
|
144
143
|
events = [new_entry]
|
|
145
144
|
traversed_edge = new_entry.vertex.edges.first
|
|
@@ -45,12 +45,12 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
|
45
45
|
|
|
46
46
|
let(:walker) do
|
|
47
47
|
factory = ParseWalkerFactory.new
|
|
48
|
-
|
|
48
|
+
accept_entry = sample_result.accepting_entry
|
|
49
|
+
accept_index = sample_result.chart.last_index
|
|
50
|
+
factory.build_walker(accept_entry, accept_index)
|
|
49
51
|
end
|
|
50
52
|
|
|
51
|
-
subject
|
|
52
|
-
ParseForestBuilder.new(sample_result)
|
|
53
|
-
end
|
|
53
|
+
subject { ParseForestBuilder.new(sample_tokens) }
|
|
54
54
|
|
|
55
55
|
# Emit a text representation of the current path.
|
|
56
56
|
def path_to_s()
|
|
@@ -60,12 +60,12 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
|
60
60
|
|
|
61
61
|
|
|
62
62
|
context 'Initialization:' do
|
|
63
|
-
it 'should be created with a
|
|
64
|
-
expect { ParseForestBuilder.new(
|
|
63
|
+
it 'should be created with a sequence of tokens' do
|
|
64
|
+
expect { ParseForestBuilder.new(sample_tokens) }.not_to raise_error
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
-
it 'should know the
|
|
68
|
-
expect(subject.
|
|
67
|
+
it 'should know the input tokens' do
|
|
68
|
+
expect(subject.tokens).to eq(sample_tokens)
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
it 'should have an empty path' do
|
|
@@ -62,19 +62,20 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
|
62
62
|
expect(subject.parsing).to eq(sample_result)
|
|
63
63
|
end
|
|
64
64
|
end
|
|
65
|
-
|
|
65
|
+
|
|
66
66
|
context 'Parse forest construction' do
|
|
67
67
|
it 'should build a parse forest' do
|
|
68
68
|
forest = subject.build_parse_forest
|
|
69
|
-
|
|
69
|
+
expect(forest).to be_kind_of(SPPF::ParseForest)
|
|
70
|
+
=begin
|
|
70
71
|
require 'yaml'
|
|
71
72
|
require_relative '../sppf/forest_representation'
|
|
72
73
|
File.open("forest.yml", "w") { |f| YAML.dump(forest, f) }
|
|
73
74
|
pen = ForestRepresentation.new
|
|
74
|
-
pen.generate_graph(forest, File.open("forest.dot", "w"))
|
|
75
|
+
pen.generate_graph(forest, File.open("forest.dot", "w"))
|
|
76
|
+
=end
|
|
75
77
|
end
|
|
76
|
-
end # context
|
|
77
|
-
=end
|
|
78
|
+
end # context
|
|
78
79
|
end # describe
|
|
79
80
|
end # module
|
|
80
81
|
end # module
|
|
@@ -63,8 +63,10 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
|
63
63
|
parser = Parser::GFGEarleyParser.new(sample_grammar)
|
|
64
64
|
parser.parse(sample_tokens)
|
|
65
65
|
end
|
|
66
|
-
|
|
67
|
-
let(:
|
|
66
|
+
|
|
67
|
+
let(:accept_entry) { sample_result.accepting_entry }
|
|
68
|
+
let(:accept_index) { sample_result.chart.last_index }
|
|
69
|
+
subject { ParseWalkerFactory.new }
|
|
68
70
|
|
|
69
71
|
|
|
70
72
|
context 'Initialization:' do
|
|
@@ -75,18 +77,18 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
|
75
77
|
|
|
76
78
|
context 'Parse graph traversal:' do
|
|
77
79
|
it 'should create an Enumerator as a walker' do
|
|
78
|
-
expect(subject.build_walker(
|
|
80
|
+
expect(subject.build_walker(accept_entry, accept_index)).to be_kind_of(Enumerator)
|
|
79
81
|
end
|
|
80
82
|
|
|
81
83
|
it 'should return the accepting parse entry in the first place' do
|
|
82
|
-
walker = subject.build_walker(
|
|
84
|
+
walker = subject.build_walker(accept_entry, accept_index)
|
|
83
85
|
first_event = walker.next
|
|
84
86
|
expectations = [:visit, sample_result.accepting_entry, 4]
|
|
85
87
|
event_expectations(first_event, expectations)
|
|
86
88
|
end
|
|
87
89
|
|
|
88
90
|
it 'should traverse the parse graph backwards' do
|
|
89
|
-
walker = subject.build_walker(
|
|
91
|
+
walker = subject.build_walker(accept_entry, accept_index)
|
|
90
92
|
event1 = walker.next
|
|
91
93
|
expectations = [:visit, 'Phi. | 0', 4]
|
|
92
94
|
event_expectations(event1, expectations)
|
|
@@ -222,7 +224,7 @@ module Rley # Open this namespace to avoid module qualifier prefixes
|
|
|
222
224
|
end
|
|
223
225
|
|
|
224
226
|
it 'should raise an exception at end of visit' do
|
|
225
|
-
walker = subject.build_walker(
|
|
227
|
+
walker = subject.build_walker(accept_entry, accept_index)
|
|
226
228
|
32.times { walker.next }
|
|
227
229
|
|
|
228
230
|
expect{ walker.next }.to raise_error(StopIteration)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rley
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.01
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dimitri Geshef
|
|
@@ -293,7 +293,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
293
293
|
version: '0'
|
|
294
294
|
requirements: []
|
|
295
295
|
rubyforge_project:
|
|
296
|
-
rubygems_version: 2.
|
|
296
|
+
rubygems_version: 2.6.7
|
|
297
297
|
signing_key:
|
|
298
298
|
specification_version: 4
|
|
299
299
|
summary: Ruby implementation of the Earley's parsing algorithm
|