rley 0.3.04 → 0.3.05
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/.rubocop.yml +7 -3
- data/CHANGELOG.md +3 -0
- data/Rakefile +30 -30
- data/examples/parsers/parsing_L0.rb +1 -1
- data/examples/parsers/parsing_L1.rb +1 -1
- data/examples/parsers/parsing_abc.rb +1 -1
- data/examples/parsers/parsing_ambig.rb +1 -1
- data/examples/parsers/parsing_another.rb +1 -1
- data/examples/parsers/parsing_b_expr.rb +1 -1
- data/examples/parsers/parsing_err_expr.rb +1 -1
- data/examples/parsers/parsing_groucho.rb +1 -1
- data/examples/parsers/parsing_right_recursive.rb +1 -1
- data/examples/parsers/parsing_tricky.rb +1 -1
- data/lib/rley/constants.rb +2 -2
- data/lib/rley/formatter/base_formatter.rb +0 -2
- data/lib/rley/formatter/debug.rb +0 -2
- data/lib/rley/formatter/json.rb +1 -3
- data/lib/rley/gfg/call_edge.rb +31 -30
- data/lib/rley/gfg/edge.rb +22 -23
- data/lib/rley/gfg/end_vertex.rb +22 -24
- data/lib/rley/gfg/epsilon_edge.rb +20 -21
- data/lib/rley/gfg/grm_flow_graph.rb +39 -39
- data/lib/rley/gfg/item_vertex.rb +16 -17
- data/lib/rley/gfg/non_terminal_vertex.rb +3 -4
- data/lib/rley/gfg/return_edge.rb +32 -31
- data/lib/rley/gfg/scan_edge.rb +25 -26
- data/lib/rley/gfg/shortcut_edge.rb +25 -26
- data/lib/rley/gfg/start_vertex.rb +0 -2
- data/lib/rley/gfg/vertex.rb +8 -8
- data/lib/rley/parse_forest_visitor.rb +113 -115
- data/lib/rley/parse_tree_visitor.rb +0 -2
- data/lib/rley/parser/base_parser.rb +27 -27
- data/lib/rley/parser/chart.rb +14 -14
- data/lib/rley/parser/dotted_item.rb +33 -33
- data/lib/rley/parser/earley_parser.rb +6 -6
- data/lib/rley/parser/gfg_chart.rb +8 -15
- data/lib/rley/parser/gfg_earley_parser.rb +15 -13
- data/lib/rley/parser/gfg_parsing.rb +26 -22
- data/lib/rley/parser/grm_items_builder.rb +3 -2
- data/lib/rley/parser/parse_entry.rb +3 -9
- data/lib/rley/parser/parse_entry_set.rb +14 -19
- data/lib/rley/parser/parse_entry_tracker.rb +56 -56
- data/lib/rley/parser/parse_forest_builder.rb +215 -214
- data/lib/rley/parser/parse_forest_factory.rb +57 -56
- data/lib/rley/parser/parse_state.rb +8 -11
- data/lib/rley/parser/parse_state_tracker.rb +56 -56
- data/lib/rley/parser/parse_tracer.rb +3 -3
- data/lib/rley/parser/parse_tree_builder.rb +10 -10
- data/lib/rley/parser/parse_walker_factory.rb +30 -33
- data/lib/rley/parser/parsing.rb +8 -8
- data/lib/rley/parser/state_set.rb +23 -26
- data/lib/rley/ptree/non_terminal_node.rb +1 -1
- data/lib/rley/ptree/token_range.rb +2 -2
- data/lib/rley/sppf/alternative_node.rb +32 -34
- data/lib/rley/sppf/composite_node.rb +27 -27
- data/lib/rley/sppf/epsilon_node.rb +26 -27
- data/lib/rley/sppf/leaf_node.rb +11 -12
- data/lib/rley/sppf/non_terminal_node.rb +37 -38
- data/lib/rley/sppf/sppf_node.rb +1 -1
- data/lib/rley/sppf/token_node.rb +29 -29
- data/lib/rley/syntax/grammar.rb +1 -3
- data/lib/rley/syntax/grammar_builder.rb +8 -8
- data/lib/rley/syntax/non_terminal.rb +2 -4
- data/lib/rley/syntax/production.rb +3 -3
- data/lib/rley/syntax/symbol_seq.rb +1 -1
- data/spec/rley/gfg/call_edge_spec.rb +50 -51
- data/spec/rley/gfg/edge_spec.rb +33 -33
- data/spec/rley/gfg/end_vertex_spec.rb +26 -27
- data/spec/rley/gfg/epsilon_edge_spec.rb +25 -25
- data/spec/rley/gfg/grm_flow_graph_spec.rb +1 -1
- data/spec/rley/gfg/item_vertex_spec.rb +3 -4
- data/spec/rley/gfg/return_edge_spec.rb +51 -51
- data/spec/rley/gfg/scan_edge_spec.rb +32 -30
- data/spec/rley/gfg/shortcut_edge_spec.rb +1 -1
- data/spec/rley/gfg/vertex_spec.rb +3 -3
- data/spec/rley/parse_forest_visitor_spec.rb +239 -238
- data/spec/rley/parser/dotted_item_spec.rb +1 -1
- data/spec/rley/parser/earley_parser_spec.rb +16 -16
- data/spec/rley/parser/gfg_earley_parser_spec.rb +30 -31
- data/spec/rley/parser/gfg_parsing_spec.rb +11 -10
- data/spec/rley/parser/grm_items_builder_spec.rb +2 -2
- data/spec/rley/parser/parse_entry_set_spec.rb +4 -4
- data/spec/rley/parser/parse_entry_spec.rb +0 -2
- data/spec/rley/parser/parse_forest_builder_spec.rb +82 -57
- data/spec/rley/parser/parse_forest_factory_spec.rb +84 -82
- data/spec/rley/parser/parse_walker_factory_spec.rb +10 -9
- data/spec/rley/parser/parsing_spec.rb +0 -1
- data/spec/rley/sppf/alternative_node_spec.rb +2 -2
- data/spec/rley/sppf/non_terminal_node_spec.rb +0 -1
- data/spec/rley/support/ambiguous_grammar_helper.rb +1 -1
- data/spec/rley/support/expectation_helper.rb +37 -36
- data/spec/rley/support/grammar_abc_helper.rb +17 -17
- data/spec/rley/support/grammar_b_expr_helper.rb +40 -39
- data/spec/rley/support/grammar_helper.rb +2 -1
- data/spec/rley/support/{grammar_L0_helper.rb → grammar_l0_helper.rb} +82 -81
- data/spec/rley/support/grammar_sppf_helper.rb +24 -25
- data/spec/rley/syntax/grammar_spec.rb +1 -1
- metadata +2 -2
@@ -1,214 +1,215 @@
|
|
1
|
-
require_relative '../syntax/terminal'
|
2
|
-
require_relative '../syntax/non_terminal'
|
3
|
-
require_relative '../gfg/end_vertex'
|
4
|
-
require_relative '../gfg/item_vertex'
|
5
|
-
require_relative '../gfg/start_vertex'
|
6
|
-
require_relative '../sppf/epsilon_node'
|
7
|
-
require_relative '../sppf/non_terminal_node'
|
8
|
-
require_relative '../sppf/alternative_node'
|
9
|
-
require_relative '../sppf/parse_forest'
|
10
|
-
|
11
|
-
module Rley # This module is used as a namespace
|
12
|
-
module Parser # This module is used as a namespace
|
13
|
-
# Builder GoF pattern. Builder pattern builds a complex object
|
14
|
-
# (say, a parse forest) from simpler objects (terminal and non-terminal
|
15
|
-
# nodes) and using a step by step approach.
|
16
|
-
class ParseForestBuilder
|
17
|
-
# The sequence of input tokens
|
18
|
-
attr_reader(:tokens)
|
19
|
-
|
20
|
-
# Link to forest object
|
21
|
-
attr_reader(:forest)
|
22
|
-
|
23
|
-
# Link to current path
|
24
|
-
attr_reader(:curr_path)
|
25
|
-
|
26
|
-
# The last parse entry visited
|
27
|
-
attr_reader(:last_visitee)
|
28
|
-
|
29
|
-
# A hash with pairs of the form: visited parse entry => forest node
|
30
|
-
attr_reader(:entry2node)
|
31
|
-
|
32
|
-
# A hash with pairs of the form:
|
33
|
-
#
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
@
|
39
|
-
@
|
40
|
-
@
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
#
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
#
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
#
|
167
|
-
# with same
|
168
|
-
#
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
#
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
end # module
|
213
|
-
|
214
|
-
|
1
|
+
require_relative '../syntax/terminal'
|
2
|
+
require_relative '../syntax/non_terminal'
|
3
|
+
require_relative '../gfg/end_vertex'
|
4
|
+
require_relative '../gfg/item_vertex'
|
5
|
+
require_relative '../gfg/start_vertex'
|
6
|
+
require_relative '../sppf/epsilon_node'
|
7
|
+
require_relative '../sppf/non_terminal_node'
|
8
|
+
require_relative '../sppf/alternative_node'
|
9
|
+
require_relative '../sppf/parse_forest'
|
10
|
+
|
11
|
+
module Rley # This module is used as a namespace
|
12
|
+
module Parser # This module is used as a namespace
|
13
|
+
# Builder GoF pattern. Builder pattern builds a complex object
|
14
|
+
# (say, a parse forest) from simpler objects (terminal and non-terminal
|
15
|
+
# nodes) and using a step by step approach.
|
16
|
+
class ParseForestBuilder
|
17
|
+
# The sequence of input tokens
|
18
|
+
attr_reader(:tokens)
|
19
|
+
|
20
|
+
# Link to forest object
|
21
|
+
attr_reader(:forest)
|
22
|
+
|
23
|
+
# Link to current path
|
24
|
+
attr_reader(:curr_path)
|
25
|
+
|
26
|
+
# The last parse entry visited
|
27
|
+
attr_reader(:last_visitee)
|
28
|
+
|
29
|
+
# A hash with pairs of the form: visited parse entry => forest node
|
30
|
+
attr_reader(:entry2node)
|
31
|
+
|
32
|
+
# A hash with pairs of the form:
|
33
|
+
# parent end entry => path to alternative node
|
34
|
+
# This is needed for synchronizing backtracking
|
35
|
+
attr_reader(:entry2path_to_alt)
|
36
|
+
|
37
|
+
def initialize(theTokens)
|
38
|
+
@tokens = theTokens
|
39
|
+
@curr_path = []
|
40
|
+
@entry2node = {}
|
41
|
+
@entry2path_to_alt = {}
|
42
|
+
end
|
43
|
+
|
44
|
+
def receive_event(anEvent, anEntry, anIndex)
|
45
|
+
# puts "Event: #{anEvent} #{anEntry} #{anIndex}"
|
46
|
+
if anEntry.dotted_entry?
|
47
|
+
process_item_entry(anEvent, anEntry, anIndex)
|
48
|
+
elsif anEntry.start_entry?
|
49
|
+
process_start_entry(anEvent, anEntry, anIndex)
|
50
|
+
elsif anEntry.end_entry?
|
51
|
+
process_end_entry(anEvent, anEntry, anIndex)
|
52
|
+
else
|
53
|
+
raise NotImplementedError
|
54
|
+
end
|
55
|
+
|
56
|
+
@last_visitee = anEntry
|
57
|
+
end
|
58
|
+
|
59
|
+
# Return the current_parent node
|
60
|
+
def curr_parent()
|
61
|
+
return curr_path.last
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def process_start_entry(_anEvent, _anEntry, _anIndex)
|
67
|
+
curr_path.pop
|
68
|
+
end
|
69
|
+
|
70
|
+
def process_end_entry(anEvent, anEntry, anIndex)
|
71
|
+
case anEvent
|
72
|
+
when :visit
|
73
|
+
# create a node with the non-terminal
|
74
|
+
# with same right extent as curr_entry_set_index
|
75
|
+
# add the new node as first child of current_parent
|
76
|
+
# append the new node to the curr_path
|
77
|
+
range = { low: anEntry.origin, high: anIndex }
|
78
|
+
non_terminal = anEntry.vertex.non_terminal
|
79
|
+
create_non_terminal_node(anEntry, range, non_terminal)
|
80
|
+
@forest = create_forest(curr_parent) unless @last_visitee
|
81
|
+
|
82
|
+
when :backtrack
|
83
|
+
# Restore path
|
84
|
+
@curr_path = entry2path_to_alt[anEntry].dup
|
85
|
+
# puts "Restore path #{curr_path.join(', ')}]"
|
86
|
+
antecedent_index = curr_parent.subnodes.size
|
87
|
+
# puts "Current parent #{curr_parent.to_string(0)}"
|
88
|
+
# puts "Antecedent index #{antecedent_index}"
|
89
|
+
|
90
|
+
|
91
|
+
when :revisit
|
92
|
+
# Retrieve the already existing node corresponding
|
93
|
+
# to re-visited entry
|
94
|
+
popular = @entry2node[anEntry]
|
95
|
+
|
96
|
+
# Share with parent
|
97
|
+
curr_parent.add_subnode(popular)
|
98
|
+
|
99
|
+
else
|
100
|
+
raise NotImplementedError
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
def process_item_entry(_anEvent, anEntry, anIndex)
|
106
|
+
if anEntry.exit_entry?
|
107
|
+
# Previous entry was an end entry (X. pattern)
|
108
|
+
# Does the previous entry have multiple antecedent?
|
109
|
+
if last_visitee.end_entry? && last_visitee.antecedents.size > 1
|
110
|
+
# Store current path for later backtracking
|
111
|
+
# puts "Store backtrack context #{last_visitee}"
|
112
|
+
# puts "path [#{curr_path.join(', ')}]"
|
113
|
+
entry2path_to_alt[last_visitee] = curr_path.dup
|
114
|
+
curr_parent.refinement = :or
|
115
|
+
|
116
|
+
create_alternative_node(anEntry)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Retrieve the grammar symbol before the dot (if any)
|
121
|
+
prev_symbol = anEntry.prev_symbol
|
122
|
+
case prev_symbol
|
123
|
+
when Syntax::Terminal
|
124
|
+
# Add node without changing current path
|
125
|
+
create_token_node(anEntry, anIndex)
|
126
|
+
|
127
|
+
when NilClass # Dot at the beginning of production
|
128
|
+
if anEntry.vertex.dotted_item.production.empty?
|
129
|
+
# Empty rhs => create an epsilon node ...
|
130
|
+
# ... without changing current path
|
131
|
+
create_epsilon_node(anEntry, anIndex)
|
132
|
+
end
|
133
|
+
curr_path.pop if curr_parent.kind_of?(SPPF::AlternativeNode)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# Create an empty parse forest
|
138
|
+
def create_forest(aRootNode)
|
139
|
+
return Rley::SPPF::ParseForest.new(aRootNode)
|
140
|
+
end
|
141
|
+
|
142
|
+
|
143
|
+
# Factory method. Build and return an SPPF non-terminal node.
|
144
|
+
def create_non_terminal_node(anEntry, aRange, nonTSymb = nil)
|
145
|
+
non_terminal = nonTSymb.nil? ? anEntry.vertex.non_terminal : nonTSymb
|
146
|
+
new_node = Rley::SPPF::NonTerminalNode.new(non_terminal, aRange)
|
147
|
+
entry2node[anEntry] = new_node
|
148
|
+
# puts "FOREST ADD #{curr_parent.key if curr_parent}/#{new_node.key}"
|
149
|
+
add_subnode(new_node)
|
150
|
+
|
151
|
+
return new_node
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
# Add an alternative node to the forest
|
156
|
+
def create_alternative_node(anEntry)
|
157
|
+
vertex = anEntry.vertex
|
158
|
+
range = curr_parent.range
|
159
|
+
alternative = Rley::SPPF::AlternativeNode.new(vertex, range)
|
160
|
+
add_subnode(alternative)
|
161
|
+
# puts "FOREST ADD #{alternative.key}"
|
162
|
+
|
163
|
+
return alternative
|
164
|
+
end
|
165
|
+
|
166
|
+
# create a token node,
|
167
|
+
# with same origin as token,
|
168
|
+
# with same right extent = origin + 1
|
169
|
+
# add the new node as first child of current_parent
|
170
|
+
def create_token_node(anEntry, anIndex)
|
171
|
+
token_position = anIndex - 1
|
172
|
+
curr_token = tokens[token_position]
|
173
|
+
new_node = SPPF::TokenNode.new(curr_token, token_position)
|
174
|
+
candidate = add_node_to_forest(new_node)
|
175
|
+
entry2node[anEntry] = candidate
|
176
|
+
|
177
|
+
return candidate
|
178
|
+
end
|
179
|
+
|
180
|
+
|
181
|
+
def create_epsilon_node(anEntry, anIndex)
|
182
|
+
new_node = SPPF::EpsilonNode.new(anIndex)
|
183
|
+
candidate = add_node_to_forest(new_node)
|
184
|
+
entry2node[anEntry] = candidate
|
185
|
+
|
186
|
+
return candidate
|
187
|
+
end
|
188
|
+
|
189
|
+
# Add the given node if not yet present in parse forest
|
190
|
+
def add_node_to_forest(aNode)
|
191
|
+
key_node = aNode.key
|
192
|
+
if forest.include?(key_node)
|
193
|
+
new_node = forest.key2node[key_node]
|
194
|
+
else
|
195
|
+
new_node = aNode
|
196
|
+
forest.key2node[key_node] = new_node
|
197
|
+
# puts "FOREST ADD #{key_node}"
|
198
|
+
end
|
199
|
+
add_subnode(new_node, false)
|
200
|
+
|
201
|
+
return new_node
|
202
|
+
end
|
203
|
+
|
204
|
+
|
205
|
+
# Add the given node as sub-node of current parent node
|
206
|
+
# Optionally add the node to the current path
|
207
|
+
def add_subnode(aNode, addToPath = true)
|
208
|
+
curr_parent.add_subnode(aNode) unless curr_path.empty?
|
209
|
+
curr_path << aNode if addToPath
|
210
|
+
end
|
211
|
+
end # class
|
212
|
+
end # module
|
213
|
+
end # module
|
214
|
+
|
215
|
+
# End of file
|
@@ -1,56 +1,57 @@
|
|
1
|
-
require_relative 'parse_walker_factory'
|
2
|
-
require_relative 'parse_forest_builder'
|
3
|
-
|
4
|
-
module Rley # This module is used as a namespace
|
5
|
-
module Parser # This module is used as a namespace
|
6
|
-
# Utility class that helps to create a ParseForest from
|
7
|
-
# a given Parsing object.
|
8
|
-
class ParseForestFactory
|
9
|
-
# Link to Parsing object (= results of recognizer)
|
10
|
-
attr_reader(:parsing)
|
11
|
-
|
12
|
-
|
13
|
-
def initialize(aParsingResult)
|
14
|
-
@parsing = aParsingResult
|
15
|
-
end
|
16
|
-
|
17
|
-
# Factory that produces the parse forest
|
18
|
-
def build_parse_forest()
|
19
|
-
a_walker = walker(parsing)
|
20
|
-
a_builder = builder(parsing)
|
21
|
-
|
22
|
-
begin
|
23
|
-
loop do
|
24
|
-
event = a_walker.next
|
25
|
-
# puts "EVENT #{event[0]} #{event[1]}"
|
26
|
-
a_builder.receive_event(*event)
|
27
|
-
end
|
28
|
-
rescue StopIteration
|
29
|
-
# Do nothing
|
30
|
-
end
|
31
|
-
|
32
|
-
return a_builder.forest
|
33
|
-
end
|
34
|
-
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
#
|
39
|
-
#
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
#
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end # module
|
55
|
-
|
56
|
-
|
1
|
+
require_relative 'parse_walker_factory'
|
2
|
+
require_relative 'parse_forest_builder'
|
3
|
+
|
4
|
+
module Rley # This module is used as a namespace
|
5
|
+
module Parser # This module is used as a namespace
|
6
|
+
# Utility class that helps to create a ParseForest from
|
7
|
+
# a given Parsing object.
|
8
|
+
class ParseForestFactory
|
9
|
+
# Link to Parsing object (= results of recognizer)
|
10
|
+
attr_reader(:parsing)
|
11
|
+
|
12
|
+
|
13
|
+
def initialize(aParsingResult)
|
14
|
+
@parsing = aParsingResult
|
15
|
+
end
|
16
|
+
|
17
|
+
# Factory that produces the parse forest
|
18
|
+
def build_parse_forest()
|
19
|
+
a_walker = walker(parsing)
|
20
|
+
a_builder = builder(parsing)
|
21
|
+
|
22
|
+
begin
|
23
|
+
loop do
|
24
|
+
event = a_walker.next
|
25
|
+
# puts "EVENT #{event[0]} #{event[1]}"
|
26
|
+
a_builder.receive_event(*event)
|
27
|
+
end
|
28
|
+
rescue StopIteration
|
29
|
+
# Do nothing
|
30
|
+
end
|
31
|
+
|
32
|
+
return a_builder.forest
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# Create a Parsing walker, that is, an object
|
39
|
+
# that will iterate over the relevant nodes (= parsing entries)
|
40
|
+
# of a GFGParsing
|
41
|
+
def walker(aParseResult)
|
42
|
+
walker_factory = ParseWalkerFactory.new
|
43
|
+
accept_entry = aParseResult.accepting_entry
|
44
|
+
accept_index = aParseResult.chart.last_index
|
45
|
+
walker_factory.build_walker(accept_entry, accept_index)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Create a Builder, that is, an object
|
49
|
+
# that will create piece by piece the forest
|
50
|
+
def builder(aParseResult)
|
51
|
+
ParseForestBuilder.new(aParseResult.tokens)
|
52
|
+
end
|
53
|
+
end # class
|
54
|
+
end # module
|
55
|
+
end # module
|
56
|
+
|
57
|
+
# End of file
|