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