rley 0.3.04 → 0.3.05
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -188,13 +188,13 @@ module Rley # This module is used as a namespace
|
|
188
188
|
term_names = terminals.map(&:name)
|
189
189
|
err_msg = "Syntax error at or near token #{pos}"
|
190
190
|
err_msg << ">>>#{lexeme_at_pos}<<<:\nExpected "
|
191
|
-
if terminals.size > 1
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
191
|
+
err_msg << if terminals.size > 1
|
192
|
+
"one of: ['#{term_names.join("', '")}'],"
|
193
|
+
else
|
194
|
+
": #{term_names[0]},"
|
195
|
+
end
|
196
196
|
err_msg << " found a '#{aParsing.tokens[pos - 1].terminal.name}'"
|
197
|
-
|
197
|
+
raise StandardError, err_msg + ' instead.'
|
198
198
|
end
|
199
199
|
end # class
|
200
200
|
end # module
|
@@ -27,13 +27,6 @@ module Rley # This module is used as a namespace
|
|
27
27
|
push_entry(aGFGraph.start_vertex, 0, 0, :start_rule)
|
28
28
|
end
|
29
29
|
|
30
|
-
# The dotted item/rule used to seed the parse chart.
|
31
|
-
# It corresponds to the start production and a dot placed
|
32
|
-
# at the beginning of the rhs
|
33
|
-
# def start_dotted_rule()
|
34
|
-
# return self[0].entries.first.dotted_rule
|
35
|
-
# end
|
36
|
-
|
37
30
|
# Return the start (non-terminal) symbol of the grammar.
|
38
31
|
def start_symbol()
|
39
32
|
return sets.first.entries[0].vertex.non_terminal
|
@@ -47,11 +40,11 @@ module Rley # This module is used as a namespace
|
|
47
40
|
# Return the index value of the last non-empty entry set.
|
48
41
|
def last_index()
|
49
42
|
first_empty = sets.find_index(&:empty?)
|
50
|
-
if first_empty.nil?
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
43
|
+
index = if first_empty.nil?
|
44
|
+
sets.size - 1
|
45
|
+
else
|
46
|
+
first_empty.zero? ? 0 : first_empty - 1
|
47
|
+
end
|
55
48
|
|
56
49
|
return index
|
57
50
|
end
|
@@ -71,7 +64,7 @@ module Rley # This module is used as a namespace
|
|
71
64
|
when :completion
|
72
65
|
tracer.trace_completion(anIndex, new_entry)
|
73
66
|
else
|
74
|
-
|
67
|
+
raise NotImplementedError, "Unknown push_entry mode #{aReason}"
|
75
68
|
end
|
76
69
|
end
|
77
70
|
|
@@ -92,9 +85,9 @@ module Rley # This module is used as a namespace
|
|
92
85
|
# Retrieve all the end entries (i.e. of the form
|
93
86
|
last_entries = sets[last_index].entries.select(&:end_entry?)
|
94
87
|
|
95
|
-
# ... now find the end vertex for start symbol and with origin at zero
|
88
|
+
# ... now find the end vertex for start symbol and with origin at zero.
|
96
89
|
success_entries = last_entries.select do |entry|
|
97
|
-
entry.origin
|
90
|
+
entry.origin.zero? && entry.vertex.non_terminal == start_symbol
|
98
91
|
end
|
99
92
|
|
100
93
|
return success_entries.first
|
@@ -6,7 +6,6 @@ module Rley # This module is used as a namespace
|
|
6
6
|
module Parser # This module is used as a namespace
|
7
7
|
# Implementation of a parser that uses the Earley parsing algorithm.
|
8
8
|
class GFGEarleyParser < BaseParser
|
9
|
-
|
10
9
|
# The Grammar Flow graph for the given grammar
|
11
10
|
attr_reader :gf_graph
|
12
11
|
|
@@ -48,7 +47,8 @@ module Rley # This module is used as a namespace
|
|
48
47
|
return result
|
49
48
|
end
|
50
49
|
|
51
|
-
private
|
50
|
+
private
|
51
|
+
|
52
52
|
# Let the current sigma set be the ith parse entry set.
|
53
53
|
# This method is invoked when an entry is added to the parse entry set
|
54
54
|
# and is of the form [A => alpha . B beta, k].
|
@@ -77,8 +77,8 @@ private
|
|
77
77
|
end
|
78
78
|
|
79
79
|
# This method must be invoked when an entry is added to a parse entry set
|
80
|
-
# and is of the form [B => γ ., k] (the dot is at the end of the
|
81
|
-
# Then entry [B., k] is added to the current entry set.
|
80
|
+
# and is of the form [B => γ ., k] (the dot is at the end of the
|
81
|
+
# production. Then entry [B., k] is added to the current entry set.
|
82
82
|
# Gist: for an entry corresponding to a reduced production, add an entry
|
83
83
|
# for each exit edge in the graph.
|
84
84
|
def exit_rule(aParsing, anEntry, aPosition, aTracer)
|
@@ -100,13 +100,15 @@ private
|
|
100
100
|
end
|
101
101
|
|
102
102
|
# Given that the terminal t is at the specified position,
|
103
|
-
# Locate all entries in the current sigma set that expect t:
|
103
|
+
# Locate all entries in the current sigma set that expect t:
|
104
|
+
# [A => α . t γ, i]
|
104
105
|
# and allow them to cross the edge, adding the node on the back side
|
105
106
|
# of the edge as an entry to the next sigma set:
|
106
107
|
# add an entry to the next sigma set [A => α t . γ, i]
|
107
108
|
def scan_rule(aParsing, aPosition, aTracer)
|
108
109
|
if aTracer.level > 1
|
109
|
-
|
110
|
+
prefix = "Chart[#{aPosition}] Scan rule applied upon "
|
111
|
+
puts prefix + aParsing.tokens[aPosition].to_s
|
110
112
|
end
|
111
113
|
aParsing.scan_rule(aPosition)
|
112
114
|
end
|
@@ -124,16 +126,16 @@ private
|
|
124
126
|
term_names = terminals.map(&:name)
|
125
127
|
err_msg = "Syntax error at or near token #{pos}"
|
126
128
|
err_msg << ">>>#{lexeme_at_pos}<<<:\nExpected "
|
127
|
-
if terminals.size > 1
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
129
|
+
err_msg << if terminals.size > 1
|
130
|
+
"one of: ['#{term_names.join("', '")}'],"
|
131
|
+
else
|
132
|
+
": #{term_names[0]},"
|
133
|
+
end
|
132
134
|
err_msg << " found a '#{aParsing.tokens[pos - 1].terminal.name}'"
|
133
|
-
|
135
|
+
raise StandardError, err_msg + ' instead.'
|
134
136
|
end
|
135
137
|
end # class
|
136
138
|
end # module
|
137
139
|
end # module
|
138
140
|
|
139
|
-
# End of file
|
141
|
+
# End of file
|
@@ -15,9 +15,11 @@ module Rley # This module is used as a namespace
|
|
15
15
|
# The sequence of input token to parse
|
16
16
|
attr_reader(:tokens)
|
17
17
|
|
18
|
-
# A Hash with pairs of the form:
|
19
|
-
#
|
20
|
-
#
|
18
|
+
# A Hash with pairs of the form:
|
19
|
+
# parse entry => [ antecedent parse entries ]
|
20
|
+
# It associates to a every parse entry its antecedent(s), that is,
|
21
|
+
# the parse entry/ies that causes the key parse entry to be created
|
22
|
+
# with one the gfg rules
|
21
23
|
attr_reader(:antecedence)
|
22
24
|
|
23
25
|
# @param aTracer [ParseTracer] An object that traces the parsing.
|
@@ -42,7 +44,8 @@ module Rley # This module is used as a namespace
|
|
42
44
|
def call_rule(anEntry, aPosition)
|
43
45
|
next_symbol = anEntry.next_symbol
|
44
46
|
start_vertex = gf_graph.start_vertex_for[next_symbol]
|
45
|
-
|
47
|
+
pos = aPosition
|
48
|
+
apply_rule(anEntry, start_vertex, pos, pos, :call_rule)
|
46
49
|
end
|
47
50
|
|
48
51
|
# Let the current sigma set be the ith parse entry set.
|
@@ -62,8 +65,8 @@ module Rley # This module is used as a namespace
|
|
62
65
|
end
|
63
66
|
|
64
67
|
# This method must be invoked when an entry is added to a parse entry set
|
65
|
-
# and is of the form [B => γ ., k] (the dot is at the end of the
|
66
|
-
# Then entry [B., k] is added to the current entry set.
|
68
|
+
# and is of the form [B => γ ., k] (the dot is at the end of the
|
69
|
+
# production. Then entry [B., k] is added to the current entry set.
|
67
70
|
# Gist: for an entry corresponding to a reduced production, add an entry
|
68
71
|
# for each exit edge in the graph.
|
69
72
|
def exit_rule(anEntry, aPosition)
|
@@ -86,12 +89,15 @@ module Rley # This module is used as a namespace
|
|
86
89
|
expecting_nterm_k.each do |ntry|
|
87
90
|
# Get the vertices after the expected non-terminal
|
88
91
|
vertex_after_terminal = ntry.vertex.shortcut.successor
|
89
|
-
|
92
|
+
origin = ntry.origin
|
93
|
+
pos = aPosition
|
94
|
+
apply_rule(anEntry, vertex_after_terminal, origin, pos, :end_rule)
|
90
95
|
end
|
91
96
|
end
|
92
97
|
|
93
98
|
# Given that the terminal t is at the specified position,
|
94
|
-
# Locate all entries in the current sigma set that expect t:
|
99
|
+
# Locate all entries in the current sigma set that expect t:
|
100
|
+
# [A => α . t γ, i]
|
95
101
|
# and allow them to cross the edge, adding the node on the back side
|
96
102
|
# of the edge as an entry to the next sigma set:
|
97
103
|
# add an entry to the next sigma set [A => α t . γ, i]
|
@@ -108,7 +114,9 @@ module Rley # This module is used as a namespace
|
|
108
114
|
# Get the vertices after the expected terminal
|
109
115
|
ntry.vertex.edges.each do |an_edge|
|
110
116
|
vertex_after_terminal = an_edge.successor
|
111
|
-
|
117
|
+
origin = ntry.origin
|
118
|
+
pos = aPosition + 1
|
119
|
+
apply_rule(ntry, vertex_after_terminal, origin, pos, :scan_rule)
|
112
120
|
end
|
113
121
|
end
|
114
122
|
end
|
@@ -117,18 +125,16 @@ module Rley # This module is used as a namespace
|
|
117
125
|
# Return true if the parse was successful (= input tokens
|
118
126
|
# followed the syntax specified by the grammar)
|
119
127
|
def success?()
|
120
|
-
return chart.accepting_entry
|
128
|
+
return chart.accepting_entry ? true : false
|
121
129
|
end
|
122
130
|
|
123
131
|
# Return true if there are more than one complete state
|
124
132
|
# for the same lhs and same origin in any state set.
|
125
133
|
def ambiguous?()
|
126
134
|
found = chart.sets.find { |set| !set.ambiguities.empty? }
|
127
|
-
return !
|
135
|
+
return !found.nil?
|
128
136
|
end
|
129
137
|
|
130
|
-
|
131
|
-
|
132
138
|
# Factory method. Builds a ParseForest from the parse result.
|
133
139
|
# @return [ParseForest]
|
134
140
|
def parse_forest()
|
@@ -152,7 +158,6 @@ module Rley # This module is used as a namespace
|
|
152
158
|
return chart.accepting_entry
|
153
159
|
end
|
154
160
|
|
155
|
-
|
156
161
|
private
|
157
162
|
|
158
163
|
# Raise an exception to indicate a syntax error.
|
@@ -165,13 +170,13 @@ module Rley # This module is used as a namespace
|
|
165
170
|
term_names = expected.map(&:name)
|
166
171
|
err_msg = "Syntax error at or near token #{aPosition + 1}"
|
167
172
|
err_msg << ">>>#{lexeme_at_pos}<<<:\nExpected "
|
168
|
-
if expected.size > 1
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
+
err_msg << if expected.size > 1
|
174
|
+
"one of: ['#{term_names.join("', '")}'],"
|
175
|
+
else
|
176
|
+
": #{term_names[0]},"
|
177
|
+
end
|
173
178
|
err_msg << " found a '#{actual.name}'"
|
174
|
-
|
179
|
+
raise StandardError, err_msg + ' instead.'
|
175
180
|
end
|
176
181
|
|
177
182
|
def apply_rule(antecedentEntry, aVertex, anOrigin, aPosition, aRuleId)
|
@@ -183,7 +188,7 @@ module Rley # This module is used as a namespace
|
|
183
188
|
# Push a parse entry (vertex + origin) to the
|
184
189
|
# chart entry with given index if it isn't yet in the chart entry.
|
185
190
|
def push_entry(aVertex, anOrigin, aChartIndex, aReason)
|
186
|
-
|
191
|
+
raise StandardError, 'Vertex may not be nil' if aVertex.nil?
|
187
192
|
chart.push_entry(aVertex, anOrigin, aChartIndex, aReason)
|
188
193
|
end
|
189
194
|
|
@@ -202,7 +207,6 @@ module Rley # This module is used as a namespace
|
|
202
207
|
|
203
208
|
return instance
|
204
209
|
end
|
205
|
-
|
206
210
|
end # class
|
207
211
|
end # module
|
208
212
|
end # module
|
@@ -9,7 +9,7 @@ module Rley # This module is used as a namespace
|
|
9
9
|
items = []
|
10
10
|
aGrammar.rules.each do |prod|
|
11
11
|
rhs_size = prod.rhs.size
|
12
|
-
if rhs_size
|
12
|
+
if rhs_size.zero?
|
13
13
|
items << DottedItem.new(prod, 0)
|
14
14
|
else
|
15
15
|
items += (0..rhs_size).map { |i| DottedItem.new(prod, i) }
|
@@ -20,4 +20,5 @@ module Rley # This module is used as a namespace
|
|
20
20
|
end
|
21
21
|
end # module
|
22
22
|
end # module
|
23
|
-
end # module
|
23
|
+
end # module
|
24
|
+
# End of file
|
@@ -4,7 +4,6 @@ require_relative '../gfg/item_vertex'
|
|
4
4
|
|
5
5
|
module Rley # This module is used as a namespace
|
6
6
|
module Parser # This module is used as a namespace
|
7
|
-
|
8
7
|
# Responsibilities:
|
9
8
|
# - To know whether the vertex is a start, end or item vertex
|
10
9
|
# - To know the next symbol to expect
|
@@ -34,12 +33,7 @@ module Rley # This module is used as a namespace
|
|
34
33
|
def ==(other)
|
35
34
|
return true if object_id == other.object_id
|
36
35
|
|
37
|
-
|
38
|
-
result = true
|
39
|
-
else
|
40
|
-
result = false
|
41
|
-
end
|
42
|
-
|
36
|
+
result = (vertex == other.vertex) && (origin == other.origin)
|
43
37
|
return result
|
44
38
|
end
|
45
39
|
|
@@ -137,7 +131,7 @@ module Rley # This module is used as a namespace
|
|
137
131
|
|
138
132
|
# Return the validated GFG vertex
|
139
133
|
def valid_vertex(aVertex)
|
140
|
-
|
134
|
+
raise StandardError, 'GFG vertex cannot be nil' if aVertex.nil?
|
141
135
|
|
142
136
|
return aVertex
|
143
137
|
end
|
@@ -145,4 +139,4 @@ module Rley # This module is used as a namespace
|
|
145
139
|
end # module
|
146
140
|
end # module
|
147
141
|
|
148
|
-
# End of file
|
142
|
+
# End of file
|
@@ -14,14 +14,6 @@ module Rley # This module is used as a namespace
|
|
14
14
|
# The set of parse entries
|
15
15
|
attr_reader :entries
|
16
16
|
|
17
|
-
# A Hash with pairs of the form:
|
18
|
-
# terminal symbol => [ parse entry expecting the terminal ]
|
19
|
-
#attr_reader :entries4term
|
20
|
-
|
21
|
-
# A Hash with pairs of the form:
|
22
|
-
# non terminal symbol => [ parse entry expecting the non-terminal ]
|
23
|
-
# attr_reader :entries4n_term
|
24
|
-
|
25
17
|
def initialize()
|
26
18
|
@entries = []
|
27
19
|
@entries4term = Hash.new { |hash, key| hash[key] = [] }
|
@@ -33,10 +25,14 @@ module Rley # This module is used as a namespace
|
|
33
25
|
return entries[index]
|
34
26
|
end
|
35
27
|
|
28
|
+
# Returns a Hash with pairs of the form:
|
29
|
+
# terminal symbol => [ parse entry expecting the terminal ]
|
36
30
|
def entries4term(aTerminal)
|
37
31
|
return @entries4term.fetch(aTerminal, [])
|
38
32
|
end
|
39
33
|
|
34
|
+
# Returns a Hash with pairs of the form:
|
35
|
+
# non terminal symbol => [ parse entry expecting the non-terminal ]
|
40
36
|
def entries4n_term(aNonTerminal)
|
41
37
|
return @entries4n_term.fetch(aNonTerminal, [])
|
42
38
|
end
|
@@ -49,8 +45,6 @@ module Rley # This module is used as a namespace
|
|
49
45
|
match = entries.find { |entry| entry == anEntry }
|
50
46
|
if match
|
51
47
|
result = match
|
52
|
-
#if entries.include?(anEntry) # TODO: check performance
|
53
|
-
# result = false
|
54
48
|
else
|
55
49
|
@entries << anEntry
|
56
50
|
expecting = anEntry.next_symbol
|
@@ -64,12 +58,12 @@ module Rley # This module is used as a namespace
|
|
64
58
|
|
65
59
|
# Return an Array of Arrays of ambiguous parse entries.
|
66
60
|
def ambiguities()
|
67
|
-
complete_entries = entries.select
|
61
|
+
complete_entries = entries.select(&:exit_entry?)
|
68
62
|
return [] if complete_entries.size <= 1
|
69
63
|
|
70
64
|
# Group parse entries by lhs symbol and origin
|
71
65
|
groupings = complete_entries.group_by do |entry|
|
72
|
-
|
66
|
+
entry.vertex.dotted_rule.lhs.object_id.to_s
|
73
67
|
end
|
74
68
|
|
75
69
|
# Retain the groups having more than one element.
|
@@ -87,18 +81,19 @@ module Rley # This module is used as a namespace
|
|
87
81
|
return @entries4term.keys
|
88
82
|
end
|
89
83
|
|
90
|
-
private
|
84
|
+
private
|
85
|
+
|
91
86
|
def add_lookup4symbol(anEntry)
|
92
87
|
symb = anEntry.next_symbol
|
93
88
|
case symb
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
89
|
+
when Syntax::Terminal
|
90
|
+
@entries4term[symb] << anEntry
|
91
|
+
|
92
|
+
when Syntax::NonTerminal
|
93
|
+
@entries4n_term[symb] << anEntry
|
99
94
|
end
|
100
95
|
end
|
101
96
|
end # class
|
102
97
|
end # module
|
103
98
|
end # module
|
104
|
-
# End of file
|
99
|
+
# End of file
|
@@ -1,56 +1,56 @@
|
|
1
|
-
module Rley # This module is used as a namespace
|
2
|
-
module Parser # This module is used as a namespace
|
3
|
-
# Helper class that keeps track of the parse entries used
|
4
|
-
# while a Parsing instance is constructing a parse forest.
|
5
|
-
class ParseEntryTracker
|
6
|
-
# The index of the current entry set
|
7
|
-
attr_reader(:entry_set_index)
|
8
|
-
|
9
|
-
# The current parse entry
|
10
|
-
attr_reader(:parse_entry)
|
11
|
-
|
12
|
-
# The already processed entries from current entry set
|
13
|
-
attr_reader(:processed_entries)
|
14
|
-
|
15
|
-
# Constructor.
|
16
|
-
def initialize(aEntrySetIndex)
|
17
|
-
self.entry_set_index = aEntrySetIndex
|
18
|
-
end
|
19
|
-
|
20
|
-
# Write accessor. Sets the value of the entry set index
|
21
|
-
def entry_set_index=(anIndex)
|
22
|
-
@entry_set_index = anIndex
|
23
|
-
@processed_entries = {}
|
24
|
-
end
|
25
|
-
|
26
|
-
# Write accessor. Set the given parse entry as the current one.
|
27
|
-
def parse_entry=(aParseEntry)
|
28
|
-
|
29
|
-
@parse_entry = aParseEntry
|
30
|
-
processed_entries[parse_entry] = true
|
31
|
-
end
|
32
|
-
|
33
|
-
# Take the first provided entry that wasn't processed yet.
|
34
|
-
def select_entry(theEntrys)
|
35
|
-
a_entry = theEntrys.find { |st| !processed_entries.include?(st) }
|
36
|
-
self.parse_entry = a_entry
|
37
|
-
end
|
38
|
-
|
39
|
-
# The dotted item for the current parse entry.
|
40
|
-
def curr_dotted_item()
|
41
|
-
parse_entry.dotted_rule
|
42
|
-
end
|
43
|
-
|
44
|
-
def symbol_on_left()
|
45
|
-
return curr_dotted_item.prev_symbol
|
46
|
-
end
|
47
|
-
|
48
|
-
# Notification that one begins with the previous entry set
|
49
|
-
def to_prev_entry_set()
|
50
|
-
self.entry_set_index = entry_set_index - 1
|
51
|
-
end
|
52
|
-
end # class
|
53
|
-
end # module
|
54
|
-
end # module
|
55
|
-
|
56
|
-
# End of file
|
1
|
+
module Rley # This module is used as a namespace
|
2
|
+
module Parser # This module is used as a namespace
|
3
|
+
# Helper class that keeps track of the parse entries used
|
4
|
+
# while a Parsing instance is constructing a parse forest.
|
5
|
+
class ParseEntryTracker
|
6
|
+
# The index of the current entry set
|
7
|
+
attr_reader(:entry_set_index)
|
8
|
+
|
9
|
+
# The current parse entry
|
10
|
+
attr_reader(:parse_entry)
|
11
|
+
|
12
|
+
# The already processed entries from current entry set
|
13
|
+
attr_reader(:processed_entries)
|
14
|
+
|
15
|
+
# Constructor.
|
16
|
+
def initialize(aEntrySetIndex)
|
17
|
+
self.entry_set_index = aEntrySetIndex
|
18
|
+
end
|
19
|
+
|
20
|
+
# Write accessor. Sets the value of the entry set index
|
21
|
+
def entry_set_index=(anIndex)
|
22
|
+
@entry_set_index = anIndex
|
23
|
+
@processed_entries = {}
|
24
|
+
end
|
25
|
+
|
26
|
+
# Write accessor. Set the given parse entry as the current one.
|
27
|
+
def parse_entry=(aParseEntry)
|
28
|
+
raise StandardError, 'Nil parse entry' if aParseEntry.nil?
|
29
|
+
@parse_entry = aParseEntry
|
30
|
+
processed_entries[parse_entry] = true
|
31
|
+
end
|
32
|
+
|
33
|
+
# Take the first provided entry that wasn't processed yet.
|
34
|
+
def select_entry(theEntrys)
|
35
|
+
a_entry = theEntrys.find { |st| !processed_entries.include?(st) }
|
36
|
+
self.parse_entry = a_entry
|
37
|
+
end
|
38
|
+
|
39
|
+
# The dotted item for the current parse entry.
|
40
|
+
def curr_dotted_item()
|
41
|
+
parse_entry.dotted_rule
|
42
|
+
end
|
43
|
+
|
44
|
+
def symbol_on_left()
|
45
|
+
return curr_dotted_item.prev_symbol
|
46
|
+
end
|
47
|
+
|
48
|
+
# Notification that one begins with the previous entry set
|
49
|
+
def to_prev_entry_set()
|
50
|
+
self.entry_set_index = entry_set_index - 1
|
51
|
+
end
|
52
|
+
end # class
|
53
|
+
end # module
|
54
|
+
end # module
|
55
|
+
|
56
|
+
# End of file
|