rley 0.3.00 → 0.3.01
Sign up to get free protection for your applications and to get access to all the features.
- 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
|