rley 0.7.06 → 0.8.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/.rubocop.yml +362 -62
- data/.travis.yml +6 -6
- data/CHANGELOG.md +20 -4
- data/LICENSE.txt +1 -1
- data/README.md +7 -7
- data/examples/NLP/engtagger.rb +193 -190
- data/examples/NLP/nano_eng/nano_en_demo.rb +7 -11
- data/examples/NLP/nano_eng/nano_grammar.rb +21 -21
- data/examples/NLP/pico_en_demo.rb +2 -2
- data/examples/data_formats/JSON/cli_options.rb +1 -1
- data/examples/data_formats/JSON/json_ast_builder.rb +21 -27
- data/examples/data_formats/JSON/json_ast_nodes.rb +12 -21
- data/examples/data_formats/JSON/json_demo.rb +1 -2
- data/examples/data_formats/JSON/json_grammar.rb +13 -13
- data/examples/data_formats/JSON/json_lexer.rb +8 -8
- data/examples/data_formats/JSON/json_minifier.rb +1 -1
- data/examples/general/calc_iter1/calc_ast_builder.rb +13 -10
- data/examples/general/calc_iter1/calc_ast_nodes.rb +23 -37
- data/examples/general/calc_iter1/calc_grammar.rb +7 -6
- data/examples/general/calc_iter1/calc_lexer.rb +6 -4
- data/examples/general/calc_iter1/spec/calculator_spec.rb +5 -5
- data/examples/general/calc_iter2/calc_ast_builder.rb +5 -3
- data/examples/general/calc_iter2/calc_ast_nodes.rb +27 -43
- data/examples/general/calc_iter2/calc_grammar.rb +12 -12
- data/examples/general/calc_iter2/calc_lexer.rb +11 -10
- data/examples/general/calc_iter2/spec/calculator_spec.rb +26 -26
- data/examples/general/left.rb +2 -2
- data/examples/general/right.rb +2 -2
- data/lib/rley.rb +1 -1
- data/lib/rley/base/dotted_item.rb +28 -31
- data/lib/rley/base/grm_items_builder.rb +6 -0
- data/lib/rley/constants.rb +2 -2
- data/lib/rley/engine.rb +22 -25
- data/lib/rley/formatter/asciitree.rb +3 -3
- data/lib/rley/formatter/bracket_notation.rb +1 -8
- data/lib/rley/formatter/debug.rb +6 -6
- data/lib/rley/formatter/json.rb +2 -2
- data/lib/rley/gfg/call_edge.rb +1 -1
- data/lib/rley/gfg/edge.rb +5 -5
- data/lib/rley/gfg/end_vertex.rb +2 -6
- data/lib/rley/gfg/epsilon_edge.rb +1 -5
- data/lib/rley/gfg/grm_flow_graph.rb +27 -23
- data/lib/rley/gfg/item_vertex.rb +10 -10
- data/lib/rley/gfg/non_terminal_vertex.rb +4 -4
- data/lib/rley/gfg/scan_edge.rb +1 -1
- data/lib/rley/gfg/shortcut_edge.rb +2 -2
- data/lib/rley/gfg/start_vertex.rb +4 -8
- data/lib/rley/gfg/vertex.rb +43 -39
- data/lib/rley/interface.rb +16 -0
- data/lib/rley/lexical/token_range.rb +6 -6
- data/lib/rley/notation/all_notation_nodes.rb +2 -0
- data/lib/rley/notation/ast_builder.rb +191 -0
- data/lib/rley/notation/ast_node.rb +44 -0
- data/lib/rley/notation/ast_visitor.rb +113 -0
- data/lib/rley/notation/grammar.rb +49 -0
- data/lib/rley/notation/grammar_builder.rb +504 -0
- data/lib/rley/notation/grouping_node.rb +23 -0
- data/lib/rley/notation/parser.rb +56 -0
- data/lib/rley/notation/sequence_node.rb +35 -0
- data/lib/rley/notation/symbol_node.rb +29 -0
- data/lib/rley/notation/tokenizer.rb +192 -0
- data/lib/rley/parse_forest_visitor.rb +5 -5
- data/lib/rley/parse_rep/ast_base_builder.rb +48 -11
- data/lib/rley/parse_rep/cst_builder.rb +5 -6
- data/lib/rley/parse_rep/parse_forest_builder.rb +22 -18
- data/lib/rley/parse_rep/parse_forest_factory.rb +3 -3
- data/lib/rley/parse_rep/parse_rep_creator.rb +14 -16
- data/lib/rley/parse_rep/parse_tree_builder.rb +4 -4
- data/lib/rley/parse_rep/parse_tree_factory.rb +27 -27
- data/lib/rley/parse_tree_visitor.rb +1 -1
- data/lib/rley/parser/error_reason.rb +4 -5
- data/lib/rley/parser/gfg_chart.rb +118 -26
- data/lib/rley/parser/gfg_parsing.rb +22 -33
- data/lib/rley/parser/parse_entry.rb +25 -31
- data/lib/rley/parser/parse_entry_set.rb +19 -16
- data/lib/rley/parser/parse_entry_tracker.rb +4 -4
- data/lib/rley/parser/parse_tracer.rb +13 -13
- data/lib/rley/parser/parse_walker_factory.rb +23 -28
- data/lib/rley/ptree/non_terminal_node.rb +7 -5
- data/lib/rley/ptree/parse_tree.rb +3 -3
- data/lib/rley/ptree/parse_tree_node.rb +5 -5
- data/lib/rley/ptree/terminal_node.rb +7 -7
- data/lib/rley/rley_error.rb +12 -12
- data/lib/rley/sppf/alternative_node.rb +6 -6
- data/lib/rley/sppf/composite_node.rb +7 -7
- data/lib/rley/sppf/epsilon_node.rb +3 -3
- data/lib/rley/sppf/leaf_node.rb +3 -3
- data/lib/rley/sppf/parse_forest.rb +16 -16
- data/lib/rley/sppf/sppf_node.rb +7 -8
- data/lib/rley/sppf/token_node.rb +3 -3
- data/lib/rley/syntax/{grammar_builder.rb → base_grammar_builder.rb} +61 -23
- data/lib/rley/syntax/grammar.rb +5 -5
- data/lib/rley/syntax/grm_symbol.rb +7 -7
- data/lib/rley/syntax/match_closest.rb +43 -0
- data/lib/rley/syntax/non_terminal.rb +9 -15
- data/lib/rley/syntax/production.rb +16 -10
- data/lib/rley/syntax/symbol_seq.rb +7 -9
- data/lib/rley/syntax/terminal.rb +4 -5
- data/lib/rley/syntax/verbatim_symbol.rb +3 -3
- data/lib/support/base_tokenizer.rb +19 -18
- data/spec/rley/base/dotted_item_spec.rb +2 -2
- data/spec/rley/engine_spec.rb +23 -21
- data/spec/rley/formatter/asciitree_spec.rb +7 -7
- data/spec/rley/formatter/bracket_notation_spec.rb +13 -13
- data/spec/rley/formatter/json_spec.rb +1 -1
- data/spec/rley/gfg/end_vertex_spec.rb +5 -5
- data/spec/rley/gfg/grm_flow_graph_spec.rb +2 -2
- data/spec/rley/gfg/item_vertex_spec.rb +10 -10
- data/spec/rley/gfg/non_terminal_vertex_spec.rb +3 -3
- data/spec/rley/gfg/shortcut_edge_spec.rb +1 -1
- data/spec/rley/gfg/start_vertex_spec.rb +5 -5
- data/spec/rley/gfg/vertex_spec.rb +3 -3
- data/spec/rley/lexical/token_range_spec.rb +16 -16
- data/spec/rley/lexical/token_spec.rb +2 -2
- data/spec/rley/notation/grammar_builder_spec.rb +302 -0
- data/spec/rley/notation/parser_spec.rb +184 -0
- data/spec/rley/notation/tokenizer_spec.rb +370 -0
- data/spec/rley/parse_forest_visitor_spec.rb +165 -163
- data/spec/rley/parse_rep/ambiguous_parse_spec.rb +44 -44
- data/spec/rley/parse_rep/ast_builder_spec.rb +6 -7
- data/spec/rley/parse_rep/cst_builder_spec.rb +5 -5
- data/spec/rley/parse_rep/groucho_spec.rb +24 -26
- data/spec/rley/parse_rep/parse_forest_builder_spec.rb +27 -27
- data/spec/rley/parse_rep/parse_forest_factory_spec.rb +8 -8
- data/spec/rley/parse_rep/parse_tree_factory_spec.rb +3 -3
- data/spec/rley/parse_tree_visitor_spec.rb +10 -8
- data/spec/rley/parser/dangling_else_spec.rb +445 -0
- data/spec/rley/parser/error_reason_spec.rb +6 -6
- data/spec/rley/parser/gfg_earley_parser_spec.rb +120 -12
- data/spec/rley/parser/gfg_parsing_spec.rb +6 -13
- data/spec/rley/parser/parse_entry_spec.rb +19 -19
- data/spec/rley/parser/parse_walker_factory_spec.rb +10 -10
- data/spec/rley/ptree/non_terminal_node_spec.rb +5 -3
- data/spec/rley/ptree/parse_tree_node_spec.rb +4 -4
- data/spec/rley/ptree/terminal_node_spec.rb +6 -6
- data/spec/rley/sppf/alternative_node_spec.rb +6 -6
- data/spec/rley/sppf/non_terminal_node_spec.rb +3 -3
- data/spec/rley/sppf/token_node_spec.rb +4 -4
- data/spec/rley/support/ambiguous_grammar_helper.rb +4 -5
- data/spec/rley/support/grammar_abc_helper.rb +3 -5
- data/spec/rley/support/grammar_ambig01_helper.rb +5 -6
- data/spec/rley/support/grammar_arr_int_helper.rb +5 -6
- data/spec/rley/support/grammar_b_expr_helper.rb +5 -6
- data/spec/rley/support/grammar_int_seq_helper.rb +51 -0
- data/spec/rley/support/grammar_l0_helper.rb +14 -17
- data/spec/rley/support/grammar_pb_helper.rb +8 -7
- data/spec/rley/support/grammar_sppf_helper.rb +3 -3
- data/spec/rley/syntax/{grammar_builder_spec.rb → base_grammar_builder_spec.rb} +35 -16
- data/spec/rley/syntax/grammar_spec.rb +6 -6
- data/spec/rley/syntax/grm_symbol_spec.rb +1 -1
- data/spec/rley/syntax/match_closest_spec.rb +46 -0
- data/spec/rley/syntax/non_terminal_spec.rb +8 -8
- data/spec/rley/syntax/production_spec.rb +17 -13
- data/spec/rley/syntax/symbol_seq_spec.rb +2 -2
- data/spec/rley/syntax/terminal_spec.rb +5 -5
- data/spec/rley/syntax/verbatim_symbol_spec.rb +1 -1
- data/spec/spec_helper.rb +0 -12
- data/spec/support/base_tokenizer_spec.rb +7 -2
- metadata +48 -74
- data/.simplecov +0 -7
- data/lib/rley/parser/parse_state.rb +0 -83
- data/lib/rley/parser/parse_state_tracker.rb +0 -59
- data/lib/rley/parser/state_set.rb +0 -101
- data/spec/rley/parser/parse_state_spec.rb +0 -125
- data/spec/rley/parser/parse_tracer_spec.rb +0 -200
- data/spec/rley/parser/state_set_spec.rb +0 -130
@@ -21,16 +21,13 @@ module Rley # This module is used as a namespace
|
|
21
21
|
# non-terminal symbol => { index(=origin) => start entry }
|
22
22
|
:return_stack, # @return [Array<ParseEntry>] A stack of parse entries
|
23
23
|
:backtrack_points,
|
24
|
-
:lazy_walk # If true and revisit end vertex then jump to start vertex
|
25
|
-
)
|
26
|
-
|
24
|
+
:lazy_walk) # If true and revisit end vertex then jump to start vertex
|
27
25
|
|
28
26
|
WalkerBacktrackpoint = Struct.new(
|
29
27
|
:entry_set_index, # Sigma set index of current parse entry
|
30
28
|
:return_stack, # A stack of parse entries
|
31
29
|
:visitee, # The parse entry being visited
|
32
|
-
:antecedent_index
|
33
|
-
)
|
30
|
+
:antecedent_index)
|
34
31
|
|
35
32
|
# A factory that creates an Enumerator object
|
36
33
|
# that itself walks through a GFGParsing object.
|
@@ -53,6 +50,7 @@ module Rley # This module is used as a namespace
|
|
53
50
|
# @param lazyWalk [Boolean] if true then take some shortcut in re-visits.
|
54
51
|
# @return [Enumerator] yields visit events when walking over the
|
55
52
|
# parse result
|
53
|
+
# rubocop: disable Style/OptionalBooleanParameter
|
56
54
|
def build_walker(acceptingEntry, maxIndex, lazyWalk = false)
|
57
55
|
msg = 'Internal error: nil entry argument'
|
58
56
|
raise StandardError, msg if acceptingEntry.nil?
|
@@ -60,7 +58,7 @@ module Rley # This module is used as a namespace
|
|
60
58
|
# Local context for the enumerator
|
61
59
|
ctx = init_context(acceptingEntry, maxIndex, lazyWalk)
|
62
60
|
|
63
|
-
|
61
|
+
Enumerator.new do |receiver| # 'receiver' is a Yielder
|
64
62
|
# At this point: current entry == accepting entry
|
65
63
|
|
66
64
|
loop do
|
@@ -70,7 +68,7 @@ module Rley # This module is used as a namespace
|
|
70
68
|
if ctx.curr_entry.orphan? # No antecedent?...
|
71
69
|
msg_prefix = "No antecedent for #{ctx.curr_entry}"
|
72
70
|
msg_suffix = "at rank #{ctx.entry_set_index}"
|
73
|
-
err_msg = msg_prefix
|
71
|
+
err_msg = "#{msg_prefix} #{msg_suffix}"
|
74
72
|
raise StandardError, err_msg unless ctx.curr_entry.start_entry?
|
75
73
|
break if ctx.backtrack_points.empty?
|
76
74
|
|
@@ -84,9 +82,8 @@ module Rley # This module is used as a namespace
|
|
84
82
|
ctx.curr_entry = result.last
|
85
83
|
end
|
86
84
|
end
|
87
|
-
|
88
|
-
return walker
|
89
85
|
end
|
86
|
+
# rubocop: enable Style/OptionalBooleanParameter
|
90
87
|
|
91
88
|
private
|
92
89
|
|
@@ -101,12 +98,12 @@ module Rley # This module is used as a namespace
|
|
101
98
|
context.backtrack_points = []
|
102
99
|
context.lazy_walk = lazyWalk
|
103
100
|
|
104
|
-
|
101
|
+
context
|
105
102
|
end
|
106
103
|
|
107
104
|
# Initialize the non-terminal to start entry mapping
|
108
|
-
def init_nterm2start
|
109
|
-
|
105
|
+
def init_nterm2start
|
106
|
+
Hash.new do |hsh, defval|
|
110
107
|
entry, index = defval
|
111
108
|
nonterm = entry.vertex.non_terminal
|
112
109
|
if hsh.include? nonterm
|
@@ -116,11 +113,10 @@ module Rley # This module is used as a namespace
|
|
116
113
|
hsh[nonterm] = { index => entry }
|
117
114
|
end
|
118
115
|
end
|
119
|
-
|
120
|
-
return h
|
121
116
|
end
|
122
117
|
|
123
118
|
# [event, entry, index, vertex]
|
119
|
+
# rubocop: disable Lint/DuplicateBranch
|
124
120
|
def visit_entry(anEntry, aContext)
|
125
121
|
index = aContext.entry_set_index
|
126
122
|
aContext.nterm2start[[anEntry, index]] if anEntry.start_entry?
|
@@ -156,11 +152,12 @@ module Rley # This module is used as a namespace
|
|
156
152
|
event = [:visit, anEntry, index]
|
157
153
|
end
|
158
154
|
|
159
|
-
|
155
|
+
event
|
160
156
|
end
|
157
|
+
# rubocop: enable Lint/DuplicateBranch
|
161
158
|
|
162
159
|
def detect_scan_edge(_ctx)
|
163
|
-
|
160
|
+
nil unless aContext.curr_entry.dotted_entry?
|
164
161
|
end
|
165
162
|
|
166
163
|
# Given the current entry from context object
|
@@ -170,13 +167,11 @@ module Rley # This module is used as a namespace
|
|
170
167
|
entries = []
|
171
168
|
return entries if aContext.curr_entry.orphan?
|
172
169
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
entries
|
170
|
+
if aContext.curr_entry.antecedents.size == 1
|
171
|
+
antecedent_of(aContext)
|
172
|
+
else
|
173
|
+
select_antecedent(aContext)
|
174
|
+
end
|
180
175
|
end
|
181
176
|
|
182
177
|
# Handle the case of an entry having one antecedent only
|
@@ -205,7 +200,7 @@ module Rley # This module is used as a namespace
|
|
205
200
|
raise NotImplementedError, "edge is a #{traversed_edge.class}"
|
206
201
|
end
|
207
202
|
|
208
|
-
|
203
|
+
events
|
209
204
|
end
|
210
205
|
|
211
206
|
# Handle the case of an entry having multiple antecedents
|
@@ -231,7 +226,7 @@ module Rley # This module is used as a namespace
|
|
231
226
|
raise StandardError, 'Internal error'
|
232
227
|
end
|
233
228
|
|
234
|
-
|
229
|
+
[new_entry]
|
235
230
|
end
|
236
231
|
|
237
232
|
def add_backtrack_point(aContext)
|
@@ -243,7 +238,7 @@ module Rley # This module is used as a namespace
|
|
243
238
|
bp.antecedent_index = 0
|
244
239
|
aContext.backtrack_points << bp
|
245
240
|
# puts "Backtrack size after addition #{aContext.backtrack_points.size}"
|
246
|
-
|
241
|
+
bp
|
247
242
|
end
|
248
243
|
|
249
244
|
def use_backtrack_point(aContext)
|
@@ -263,7 +258,7 @@ module Rley # This module is used as a namespace
|
|
263
258
|
# puts "Backtrack size after backtracking #{aContext.backtrack_points.size}"
|
264
259
|
|
265
260
|
# Emit a backtrack event
|
266
|
-
|
261
|
+
[:backtrack, bp.visitee, aContext.entry_set_index]
|
267
262
|
end
|
268
263
|
|
269
264
|
# From the antecedent of the current parse entry
|
@@ -287,7 +282,7 @@ module Rley # This module is used as a namespace
|
|
287
282
|
new_entry ||= aContext.curr_entry
|
288
283
|
|
289
284
|
# puts "Pop from return stack matching entry #{new_entry}"
|
290
|
-
|
285
|
+
new_entry
|
291
286
|
end
|
292
287
|
end # class
|
293
288
|
end # module
|
@@ -18,20 +18,22 @@ module Rley # This module is used as a namespace
|
|
18
18
|
def add_subnode(aSubnode)
|
19
19
|
subnodes.unshift(aSubnode)
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
# Emit a (formatted) string representation of the node.
|
23
23
|
# Mainly used for diagnosis/debugging purposes.
|
24
|
+
# rubocop: disable Style/StringConcatenation
|
24
25
|
def to_string(indentation)
|
25
26
|
connector = '+- '
|
26
27
|
selfie = super(indentation)
|
27
28
|
prefix = "\n" + (' ' * connector.size * indentation) + connector
|
28
29
|
subnodes_repr = subnodes.reduce(+'') do |sub_result, subnode|
|
29
|
-
sub_result << prefix + subnode.to_string(indentation + 1)
|
30
|
+
sub_result << prefix + subnode.to_string(indentation + 1)
|
30
31
|
end
|
31
|
-
|
32
|
-
|
32
|
+
|
33
|
+
selfie + subnodes_repr
|
33
34
|
end
|
34
|
-
|
35
|
+
# rubocop: enable Style/StringConcatenation
|
36
|
+
|
35
37
|
# Part of the 'visitee' role in Visitor design pattern.
|
36
38
|
# @param aVisitor[ParseTreeVisitor] the visitor
|
37
39
|
def accept(aVisitor)
|
@@ -6,12 +6,12 @@ require_relative 'non_terminal_node'
|
|
6
6
|
module Rley # This module is used as a namespace
|
7
7
|
module PTree # This module is used as a namespace
|
8
8
|
# A parse tree (a.k.a. concrete syntax tree) is a tree-based representation
|
9
|
-
# for the parse that corresponds to the input text. In a parse tree,
|
9
|
+
# for the parse that corresponds to the input text. In a parse tree,
|
10
10
|
# a node corresponds to a grammar symbol used during the parsing:
|
11
11
|
# - a leaf node maps to a terminal symbol occurring in
|
12
12
|
# the input, and
|
13
13
|
# - a intermediate node maps to a non-terminal node reduced
|
14
|
-
# during the parse.
|
14
|
+
# during the parse.
|
15
15
|
# The root node corresponds to the main/start symbol of the grammar.
|
16
16
|
class ParseTree
|
17
17
|
# @return [ParseTreeNode] The root node of the tree.
|
@@ -21,7 +21,7 @@ module Rley # This module is used as a namespace
|
|
21
21
|
def initialize(theRootNode)
|
22
22
|
@root = theRootNode
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
# Notification from the builder telling that the parse tree construction
|
26
26
|
# is over. This method can be overriden.
|
27
27
|
def done!
|
@@ -15,9 +15,9 @@ module Rley # This module is used as a namespace
|
|
15
15
|
@symbol = aSymbol
|
16
16
|
@range = Lexical::TokenRange.new(aRange)
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
# Notify the builder that the construction is over
|
20
|
-
def done!
|
20
|
+
def done!
|
21
21
|
# Do nothing
|
22
22
|
end
|
23
23
|
|
@@ -29,13 +29,13 @@ module Rley # This module is used as a namespace
|
|
29
29
|
# Emit a (formatted) string representation of the node.
|
30
30
|
# Mainly used for diagnosis/debugging purposes.
|
31
31
|
def to_string(indentation)
|
32
|
-
|
32
|
+
"#{symbol.name}#{range.to_string(indentation)}"
|
33
33
|
end
|
34
34
|
|
35
35
|
# Emit a short string representation of the node.
|
36
36
|
# Mainly used for diagnosis/debugging purposes.
|
37
|
-
def to_s
|
38
|
-
|
37
|
+
def to_s
|
38
|
+
"#{symbol.name}#{range.to_string(0)}"
|
39
39
|
end
|
40
40
|
end # class
|
41
41
|
end # module
|
@@ -9,10 +9,10 @@ module Rley # This module is used as a namespace
|
|
9
9
|
attr_reader(:token)
|
10
10
|
|
11
11
|
# @param aToken [Lexical::Token] Input Token object
|
12
|
-
# @param aPos [Integer] position of the token in the input stream.
|
12
|
+
# @param aPos [Integer] position of the token in the input stream.
|
13
13
|
def initialize(aToken, aPos)
|
14
|
-
# (major, minor) =
|
15
|
-
|
14
|
+
# (major, minor) =
|
15
|
+
|
16
16
|
# Use '1.class' trick to support both Integer and Fixnum classes
|
17
17
|
range = aPos.kind_of?(1.class) ? { low: aPos, high: aPos + 1 } : aPos
|
18
18
|
super(aToken.terminal, range)
|
@@ -24,18 +24,18 @@ module Rley # This module is used as a namespace
|
|
24
24
|
def to_string(indentation)
|
25
25
|
return super + ": '#{token.lexeme}'"
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
# Emit a short string representation of the node.
|
29
29
|
# Mainly used for diagnosis/debugging purposes.
|
30
|
-
def to_s
|
30
|
+
def to_s
|
31
31
|
return super + ": '#{token.lexeme}'"
|
32
|
-
end
|
32
|
+
end
|
33
33
|
|
34
34
|
# Part of the 'visitee' role in Visitor design pattern.
|
35
35
|
# @param aVisitor[ParseTreeVisitor] the visitor
|
36
36
|
def accept(aVisitor)
|
37
37
|
aVisitor.visit_terminal(self)
|
38
|
-
end
|
38
|
+
end
|
39
39
|
end # class
|
40
40
|
end # module
|
41
41
|
end # module
|
data/lib/rley/rley_error.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# File: rley_error.rb
|
4
|
-
|
5
|
-
module Rley # Module used as a namespace
|
6
|
-
# @abstract
|
7
|
-
# Base class for any exception explicitly raised by Rley code.
|
8
|
-
class RleyError < StandardError
|
9
|
-
end # class
|
10
|
-
end # module
|
11
|
-
|
12
|
-
# End of file
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# File: rley_error.rb
|
4
|
+
|
5
|
+
module Rley # Module used as a namespace
|
6
|
+
# @abstract
|
7
|
+
# Base class for any exception explicitly raised by Rley code.
|
8
|
+
class RleyError < StandardError
|
9
|
+
end # class
|
10
|
+
end # module
|
11
|
+
|
12
|
+
# End of file
|
@@ -13,10 +13,10 @@ module Rley # This module is used as a namespace
|
|
13
13
|
# @return [Syntax::NonTerminal] Link to lhs symbol
|
14
14
|
attr_reader(:symbol)
|
15
15
|
|
16
|
-
# @param aVertex [GFG::ItemVertex]
|
17
|
-
# A GFG vertex that corresponds to a dotted item
|
16
|
+
# @param aVertex [GFG::ItemVertex]
|
17
|
+
# A GFG vertex that corresponds to a dotted item
|
18
18
|
# with the dot at the end) for the alternative under consideration.
|
19
|
-
# @param aRange [Lexical::TokenRange]
|
19
|
+
# @param aRange [Lexical::TokenRange]
|
20
20
|
# A range of token indices corresponding to this node.
|
21
21
|
def initialize(aVertex, aRange)
|
22
22
|
super(aRange)
|
@@ -28,14 +28,14 @@ module Rley # This module is used as a namespace
|
|
28
28
|
# Mainly used for diagnosis/debugging purposes.
|
29
29
|
# @return [String]
|
30
30
|
def to_string(indentation)
|
31
|
-
|
31
|
+
"Alt(#{label})#{range.to_string(indentation)}"
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
# Part of the 'visitee' role in Visitor design pattern.
|
35
35
|
# @param aVisitor[ParseTreeVisitor] the visitor
|
36
36
|
def accept(aVisitor)
|
37
37
|
aVisitor.visit_alternative(self)
|
38
|
-
end
|
38
|
+
end
|
39
39
|
end # class
|
40
40
|
end # module
|
41
41
|
end # module
|
@@ -9,11 +9,11 @@ module Rley # This module is used as a namespace
|
|
9
9
|
class CompositeNode < SPPFNode
|
10
10
|
# @return [Array<SPFFNode>] Sub-nodes (children).
|
11
11
|
attr_reader(:subnodes)
|
12
|
-
|
13
|
-
alias children subnodes
|
12
|
+
|
13
|
+
alias children subnodes
|
14
14
|
|
15
15
|
# Constructor
|
16
|
-
# @param aRange [Lexical::TokenRange]
|
16
|
+
# @param aRange [Lexical::TokenRange]
|
17
17
|
def initialize(aRange)
|
18
18
|
super(aRange)
|
19
19
|
@subnodes = []
|
@@ -24,14 +24,14 @@ module Rley # This module is used as a namespace
|
|
24
24
|
def add_subnode(aSubnode)
|
25
25
|
subnodes.unshift(aSubnode)
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
# @return [String] a text representation of the node.
|
29
|
-
def inspect
|
29
|
+
def inspect
|
30
30
|
key
|
31
|
-
end
|
31
|
+
end
|
32
32
|
|
33
33
|
# @return [String]
|
34
|
-
def key
|
34
|
+
def key
|
35
35
|
@key ||= to_string(0)
|
36
36
|
end
|
37
37
|
end # class
|
@@ -17,14 +17,14 @@ module Rley # This module is used as a namespace
|
|
17
17
|
# Mainly used for diagnosis/debugging purposes.
|
18
18
|
# @return [String]
|
19
19
|
def to_string(indentation)
|
20
|
-
|
20
|
+
"_#{range.to_string(indentation)}"
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
# Part of the 'visitee' role in Visitor design pattern.
|
24
24
|
# @param aVisitor[ParseTreeVisitor] the visitor
|
25
25
|
def accept(aVisitor)
|
26
26
|
aVisitor.visit_epsilon(self)
|
27
|
-
end
|
27
|
+
end
|
28
28
|
end # class
|
29
29
|
end # module
|
30
30
|
end # module
|
data/lib/rley/sppf/leaf_node.rb
CHANGED
@@ -8,14 +8,14 @@ module Rley # This module is used as a namespace
|
|
8
8
|
# child node.
|
9
9
|
class LeafNode < SPPFNode
|
10
10
|
# @return [String] a text representation of the node.
|
11
|
-
def inspect
|
11
|
+
def inspect
|
12
12
|
key
|
13
13
|
end
|
14
14
|
|
15
15
|
# @return [String]
|
16
|
-
def key
|
16
|
+
def key
|
17
17
|
@key ||= to_string(0)
|
18
|
-
end
|
18
|
+
end
|
19
19
|
end # class
|
20
20
|
end # module
|
21
21
|
end # module
|
@@ -7,19 +7,19 @@ require_relative 'alternative_node'
|
|
7
7
|
module Rley # This module is used as a namespace
|
8
8
|
module SPPF # This module is used as a namespace
|
9
9
|
# In an ambiguous grammar there are valid inputs that can result in multiple
|
10
|
-
# parse trees. A set of parse trees is commonly referred to as a parse
|
11
|
-
# forest. More specifically a parse forest is a graph data
|
10
|
+
# parse trees. A set of parse trees is commonly referred to as a parse
|
11
|
+
# forest. More specifically a parse forest is a graph data
|
12
12
|
# structure designed to represent a set of equally syntactically correct
|
13
13
|
# parse trees. Parse forests generated by Rley are so-called Shared Packed
|
14
|
-
# Parse Forests (SPPF). SPPFs allow very compact representation of parse
|
14
|
+
# Parse Forests (SPPF). SPPFs allow very compact representation of parse
|
15
15
|
# trees by sharing common sub-tree amongst the parse trees.
|
16
16
|
class ParseForest
|
17
17
|
# The root node of the forest
|
18
18
|
attr_reader(:root)
|
19
|
-
|
19
|
+
|
20
20
|
# A Hash with pairs of the kind node key => node
|
21
21
|
attr_reader(:key2node)
|
22
|
-
|
22
|
+
|
23
23
|
# A setter that tells that the parse is ambiguous.
|
24
24
|
attr_writer(:is_ambiguous)
|
25
25
|
|
@@ -30,34 +30,34 @@ module Rley # This module is used as a namespace
|
|
30
30
|
@key2node = {}
|
31
31
|
@is_ambiguous = false
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
# Notification that the SPPF construction is over
|
35
35
|
def done!
|
36
36
|
# Do nothing
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
# Returns true if the given node is present in the forest.
|
40
40
|
def include?(aNode)
|
41
|
-
|
41
|
+
key2node.include?(aNode)
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
# Returns true if the parse encountered a structural ambiguity
|
45
45
|
# (i.e. more than one parse tree for the given input)
|
46
|
-
def ambiguous?
|
47
|
-
|
46
|
+
def ambiguous?
|
47
|
+
@is_ambiguous
|
48
48
|
end
|
49
|
-
|
50
|
-
# Create an Enumerator that helps to iterate over the possible
|
51
|
-
# parse trees. That enumerator will generate a parse tree when
|
49
|
+
|
50
|
+
# Create an Enumerator that helps to iterate over the possible
|
51
|
+
# parse trees. That enumerator will generate a parse tree when
|
52
52
|
# called with `next` method.
|
53
53
|
# @return [Enumerator]
|
54
|
-
def to_ptree_enum
|
54
|
+
def to_ptree_enum
|
55
55
|
# How to implement?
|
56
56
|
# One visits the forest => beware of dependency
|
57
57
|
# At each visited item create a corresponding tree node.
|
58
58
|
# At end of visit & stack not empty
|
59
59
|
# Re-generate another ptree
|
60
|
-
end
|
60
|
+
end
|
61
61
|
|
62
62
|
# Part of the 'visitee' role in the Visitor design pattern.
|
63
63
|
# A visitee is expected to accept the visit from a visitor object
|