rley 0.7.03 → 0.7.08
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 -7
- data/CHANGELOG.md +20 -1
- data/LICENSE.txt +1 -1
- data/README.md +6 -7
- data/Rakefile +2 -0
- data/appveyor.yml +2 -4
- data/examples/NLP/benchmark_pico_en.rb +2 -0
- data/examples/NLP/engtagger.rb +193 -188
- data/examples/NLP/nano_eng/nano_en_demo.rb +2 -0
- data/examples/NLP/nano_eng/nano_grammar.rb +7 -5
- data/examples/NLP/pico_en_demo.rb +2 -0
- data/examples/data_formats/JSON/cli_options.rb +3 -1
- data/examples/data_formats/JSON/json_ast_builder.rb +14 -9
- data/examples/data_formats/JSON/json_ast_nodes.rb +14 -21
- data/examples/data_formats/JSON/json_demo.rb +2 -0
- data/examples/data_formats/JSON/json_grammar.rb +4 -2
- data/examples/data_formats/JSON/json_lexer.rb +10 -8
- data/examples/data_formats/JSON/json_minifier.rb +3 -1
- data/examples/general/calc_iter1/calc_ast_builder.rb +15 -10
- data/examples/general/calc_iter1/calc_ast_nodes.rb +25 -37
- data/examples/general/calc_iter1/calc_demo.rb +2 -0
- data/examples/general/calc_iter1/calc_grammar.rb +4 -2
- data/examples/general/calc_iter1/calc_lexer.rb +8 -4
- data/examples/general/calc_iter1/spec/calculator_spec.rb +7 -5
- data/examples/general/calc_iter2/calc_ast_builder.rb +7 -3
- data/examples/general/calc_iter2/calc_ast_nodes.rb +29 -43
- data/examples/general/calc_iter2/calc_demo.rb +2 -0
- data/examples/general/calc_iter2/calc_grammar.rb +5 -3
- data/examples/general/calc_iter2/calc_lexer.rb +13 -10
- data/examples/general/calc_iter2/spec/calculator_spec.rb +28 -26
- data/examples/general/left.rb +4 -2
- data/examples/general/right.rb +4 -2
- data/lib/rley.rb +2 -0
- data/lib/rley/base/base_parser.rb +2 -0
- data/lib/rley/base/dotted_item.rb +38 -41
- data/lib/rley/base/grm_items_builder.rb +2 -0
- data/lib/rley/constants.rb +5 -3
- data/lib/rley/engine.rb +22 -24
- data/lib/rley/formatter/asciitree.rb +6 -4
- data/lib/rley/formatter/base_formatter.rb +2 -0
- data/lib/rley/formatter/bracket_notation.rb +3 -8
- data/lib/rley/formatter/debug.rb +8 -6
- data/lib/rley/formatter/json.rb +4 -2
- data/lib/rley/gfg/call_edge.rb +3 -1
- data/lib/rley/gfg/edge.rb +7 -5
- data/lib/rley/gfg/end_vertex.rb +4 -6
- data/lib/rley/gfg/epsilon_edge.rb +3 -5
- data/lib/rley/gfg/grm_flow_graph.rb +31 -25
- data/lib/rley/gfg/item_vertex.rb +12 -22
- data/lib/rley/gfg/non_terminal_vertex.rb +6 -4
- data/lib/rley/gfg/return_edge.rb +2 -0
- data/lib/rley/gfg/scan_edge.rb +3 -1
- data/lib/rley/gfg/shortcut_edge.rb +4 -2
- data/lib/rley/gfg/start_vertex.rb +6 -8
- data/lib/rley/gfg/vertex.rb +47 -41
- data/lib/rley/lexical/token.rb +3 -1
- data/lib/rley/lexical/token_range.rb +8 -6
- data/lib/rley/parse_forest_visitor.rb +7 -5
- data/lib/rley/parse_rep/ast_base_builder.rb +11 -11
- data/lib/rley/parse_rep/cst_builder.rb +7 -4
- data/lib/rley/parse_rep/parse_forest_builder.rb +36 -25
- data/lib/rley/parse_rep/parse_forest_factory.rb +5 -3
- data/lib/rley/parse_rep/parse_rep_creator.rb +18 -13
- data/lib/rley/parse_rep/parse_tree_builder.rb +15 -15
- data/lib/rley/parse_rep/parse_tree_factory.rb +27 -25
- data/lib/rley/parse_tree_visitor.rb +3 -1
- data/lib/rley/parser/error_reason.rb +9 -8
- data/lib/rley/parser/gfg_chart.rb +54 -22
- data/lib/rley/parser/gfg_earley_parser.rb +3 -1
- data/lib/rley/parser/gfg_parsing.rb +51 -31
- data/lib/rley/parser/parse_entry.rb +29 -33
- data/lib/rley/parser/parse_entry_set.rb +32 -27
- data/lib/rley/parser/parse_entry_tracker.rb +6 -4
- data/lib/rley/parser/parse_state.rb +18 -21
- data/lib/rley/parser/parse_state_tracker.rb +6 -4
- data/lib/rley/parser/parse_tracer.rb +15 -13
- data/lib/rley/parser/parse_walker_factory.rb +28 -29
- data/lib/rley/parser/state_set.rb +11 -10
- data/lib/rley/ptree/non_terminal_node.rb +10 -6
- data/lib/rley/ptree/parse_tree.rb +6 -4
- data/lib/rley/ptree/parse_tree_node.rb +7 -5
- data/lib/rley/ptree/terminal_node.rb +9 -7
- data/lib/rley/rley_error.rb +12 -10
- data/lib/rley/sppf/alternative_node.rb +8 -6
- data/lib/rley/sppf/composite_node.rb +9 -7
- data/lib/rley/sppf/epsilon_node.rb +5 -3
- data/lib/rley/sppf/leaf_node.rb +5 -3
- data/lib/rley/sppf/non_terminal_node.rb +2 -0
- data/lib/rley/sppf/parse_forest.rb +19 -17
- data/lib/rley/sppf/sppf_node.rb +9 -8
- data/lib/rley/sppf/token_node.rb +5 -3
- data/lib/rley/syntax/grammar.rb +7 -5
- data/lib/rley/syntax/grammar_builder.rb +11 -9
- data/lib/rley/syntax/grm_symbol.rb +8 -6
- data/lib/rley/syntax/literal.rb +2 -0
- data/lib/rley/syntax/non_terminal.rb +11 -15
- data/lib/rley/syntax/production.rb +13 -11
- data/lib/rley/syntax/symbol_seq.rb +10 -10
- data/lib/rley/syntax/terminal.rb +6 -5
- data/lib/rley/syntax/verbatim_symbol.rb +5 -3
- data/lib/support/base_tokenizer.rb +23 -20
- data/spec/rley/base/dotted_item_spec.rb +4 -2
- data/spec/rley/base/grm_items_builder_spec.rb +2 -0
- data/spec/rley/engine_spec.rb +47 -9
- data/spec/rley/formatter/asciitree_spec.rb +11 -9
- data/spec/rley/formatter/bracket_notation_spec.rb +16 -14
- data/spec/rley/formatter/debug_spec.rb +4 -2
- data/spec/rley/formatter/json_spec.rb +5 -3
- data/spec/rley/gfg/call_edge_spec.rb +2 -0
- data/spec/rley/gfg/edge_spec.rb +2 -0
- data/spec/rley/gfg/end_vertex_spec.rb +7 -5
- data/spec/rley/gfg/epsilon_edge_spec.rb +2 -0
- data/spec/rley/gfg/grm_flow_graph_spec.rb +2 -0
- data/spec/rley/gfg/item_vertex_spec.rb +12 -10
- data/spec/rley/gfg/non_terminal_vertex_spec.rb +5 -3
- data/spec/rley/gfg/return_edge_spec.rb +2 -0
- data/spec/rley/gfg/scan_edge_spec.rb +2 -0
- data/spec/rley/gfg/shortcut_edge_spec.rb +3 -1
- data/spec/rley/gfg/start_vertex_spec.rb +7 -5
- data/spec/rley/gfg/vertex_spec.rb +5 -3
- data/spec/rley/lexical/token_range_spec.rb +18 -16
- data/spec/rley/lexical/token_spec.rb +4 -2
- data/spec/rley/parse_forest_visitor_spec.rb +167 -163
- data/spec/rley/parse_rep/ambiguous_parse_spec.rb +46 -44
- data/spec/rley/parse_rep/ast_builder_spec.rb +8 -6
- data/spec/rley/parse_rep/cst_builder_spec.rb +7 -5
- data/spec/rley/parse_rep/groucho_spec.rb +25 -25
- data/spec/rley/parse_rep/parse_forest_builder_spec.rb +28 -26
- data/spec/rley/parse_rep/parse_forest_factory_spec.rb +8 -6
- data/spec/rley/parse_rep/parse_tree_factory_spec.rb +4 -2
- data/spec/rley/parse_tree_visitor_spec.rb +12 -8
- data/spec/rley/parser/error_reason_spec.rb +8 -6
- data/spec/rley/parser/gfg_chart_spec.rb +17 -4
- data/spec/rley/parser/gfg_earley_parser_spec.rb +16 -11
- data/spec/rley/parser/gfg_parsing_spec.rb +41 -252
- data/spec/rley/parser/parse_entry_set_spec.rb +2 -0
- data/spec/rley/parser/parse_entry_spec.rb +21 -19
- data/spec/rley/parser/parse_state_spec.rb +7 -5
- data/spec/rley/parser/parse_tracer_spec.rb +16 -14
- data/spec/rley/parser/parse_walker_factory_spec.rb +10 -8
- data/spec/rley/parser/state_set_spec.rb +24 -22
- data/spec/rley/ptree/non_terminal_node_spec.rb +7 -3
- data/spec/rley/ptree/parse_tree_node_spec.rb +6 -4
- data/spec/rley/ptree/parse_tree_spec.rb +2 -0
- data/spec/rley/ptree/terminal_node_spec.rb +8 -6
- data/spec/rley/sppf/alternative_node_spec.rb +8 -6
- data/spec/rley/sppf/non_terminal_node_spec.rb +5 -3
- data/spec/rley/sppf/token_node_spec.rb +6 -4
- data/spec/rley/support/ambiguous_grammar_helper.rb +5 -4
- data/spec/rley/support/expectation_helper.rb +2 -0
- data/spec/rley/support/grammar_abc_helper.rb +4 -4
- data/spec/rley/support/grammar_ambig01_helper.rb +6 -5
- data/spec/rley/support/grammar_arr_int_helper.rb +6 -5
- data/spec/rley/support/grammar_b_expr_helper.rb +6 -5
- data/spec/rley/support/grammar_helper.rb +2 -0
- data/spec/rley/support/grammar_l0_helper.rb +15 -16
- data/spec/rley/support/grammar_pb_helper.rb +8 -5
- data/spec/rley/support/grammar_sppf_helper.rb +3 -1
- data/spec/rley/syntax/grammar_builder_spec.rb +7 -5
- data/spec/rley/syntax/grammar_spec.rb +8 -6
- data/spec/rley/syntax/grm_symbol_spec.rb +3 -1
- data/spec/rley/syntax/literal_spec.rb +2 -0
- data/spec/rley/syntax/non_terminal_spec.rb +10 -8
- data/spec/rley/syntax/production_spec.rb +15 -13
- data/spec/rley/syntax/symbol_seq_spec.rb +4 -2
- data/spec/rley/syntax/terminal_spec.rb +7 -5
- data/spec/rley/syntax/verbatim_symbol_spec.rb +3 -1
- data/spec/spec_helper.rb +2 -12
- data/spec/support/base_tokenizer_spec.rb +9 -2
- metadata +21 -63
- data/.simplecov +0 -7
- data/Gemfile +0 -8
data/lib/rley/gfg/vertex.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Rley # This module is used as a namespace
|
2
4
|
module GFG # This module is used as a namespace
|
3
5
|
# Abstract class. Represents a vertex in a grammar flow graph
|
@@ -8,60 +10,65 @@ module Rley # This module is used as a namespace
|
|
8
10
|
# The edges linking the successor vertices to this one.
|
9
11
|
# @return [Array<Edge>] The edge(s) linking this vertex to successor(s)
|
10
12
|
attr_reader :edges
|
11
|
-
|
13
|
+
|
14
|
+
# Return the object id in string format
|
15
|
+
# @return [String]
|
16
|
+
attr_reader :oid_str
|
17
|
+
|
12
18
|
# Constructor to extend in subclasses.
|
13
|
-
def initialize
|
19
|
+
def initialize
|
14
20
|
@edges = []
|
21
|
+
@oid_str = object_id.to_s
|
15
22
|
end
|
16
|
-
|
17
|
-
#
|
18
|
-
# @param anEdge [Edge] the edge to be added.
|
19
|
-
def add_edge(anEdge)
|
20
|
-
arrow = check_add_edge(anEdge)
|
21
|
-
edges << arrow
|
22
|
-
end
|
23
|
-
|
24
|
-
# Determine if the vertex corresponds to an dotted item that has
|
23
|
+
|
24
|
+
# Determine if the vertex corresponds to an dotted item that has
|
25
25
|
# its dot at the end of a production (i.e. is a reduced item).
|
26
26
|
# @return [Boolean] true iff vertex corresponds to reduced item.
|
27
|
-
def complete?
|
28
|
-
|
27
|
+
def complete?
|
28
|
+
false # Default implementation
|
29
29
|
end
|
30
|
-
|
31
|
-
# Returns a string containing a human-readable representation of the
|
30
|
+
|
31
|
+
# Returns a string containing a human-readable representation of the
|
32
32
|
# vertex.
|
33
33
|
# @return [String]
|
34
|
-
def inspect
|
35
|
-
result = '#<'
|
34
|
+
def inspect
|
35
|
+
result = +'#<'
|
36
36
|
result << selfie
|
37
37
|
edges.each { |e| result << e.inspect }
|
38
38
|
result << specific_inspect
|
39
39
|
result << '>'
|
40
|
-
|
41
|
-
|
40
|
+
|
41
|
+
result
|
42
42
|
end
|
43
|
-
|
44
|
-
# Returns a string containing a human-readable representation of the
|
43
|
+
|
44
|
+
# Returns a string containing a human-readable representation of the
|
45
45
|
# vertex without the edges.
|
46
|
-
# @return [String]
|
47
|
-
def selfie
|
48
|
-
result = "#{self.class.name}:#{object_id}"
|
46
|
+
# @return [String]
|
47
|
+
def selfie
|
48
|
+
result = +"#{self.class.name}:#{object_id}"
|
49
49
|
result << %( label="#{label}")
|
50
|
-
|
50
|
+
result
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
# Retrieve the grammar symbol before the dot.
|
54
54
|
# @return [GrmSymbol, NilClass] The symbol or otherwise nil.
|
55
|
-
def prev_symbol
|
56
|
-
|
57
|
-
end
|
58
|
-
|
55
|
+
def prev_symbol
|
56
|
+
nil # Default implementation
|
57
|
+
end
|
58
|
+
|
59
59
|
# Retrieve the grammar symbol after the dot.
|
60
|
-
# @return [GrmSymbol, NilClass] The symbol or otherwise nil.
|
61
|
-
def next_symbol
|
62
|
-
|
60
|
+
# @return [GrmSymbol, NilClass] The symbol or otherwise nil.
|
61
|
+
def next_symbol
|
62
|
+
nil # Default implementation
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
|
+
# Add an graph edge to this vertex.
|
66
|
+
# @param anEdge [Edge] the edge to be added.
|
67
|
+
def add_edge(anEdge)
|
68
|
+
arrow = check_add_edge(anEdge)
|
69
|
+
edges << arrow
|
70
|
+
end
|
71
|
+
|
65
72
|
protected
|
66
73
|
|
67
74
|
# Validation method for adding an outgoing edge to the vertex.
|
@@ -69,14 +76,13 @@ module Rley # This module is used as a namespace
|
|
69
76
|
# unless this method is overridden in subclasses
|
70
77
|
def check_add_edge(anEdge)
|
71
78
|
raise StandardError, 'At most one edge accepted' unless edges.empty?
|
72
|
-
|
73
|
-
|
79
|
+
|
80
|
+
anEdge
|
81
|
+
end
|
82
|
+
|
83
|
+
def specific_inspect
|
84
|
+
''
|
74
85
|
end
|
75
|
-
|
76
|
-
def specific_inspect()
|
77
|
-
return ''
|
78
|
-
end
|
79
|
-
|
80
86
|
end # class
|
81
87
|
end # module
|
82
88
|
end # module
|
data/lib/rley/lexical/token.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Rley # This module is used as a namespace
|
2
4
|
module Lexical # This module is used as a namespace
|
3
5
|
# A Position is the location of a lexeme within a source file.
|
@@ -23,7 +25,7 @@ module Rley # This module is used as a namespace
|
|
23
25
|
# @return [String] Input substring that is an instance of the terminal.
|
24
26
|
attr_reader(:lexeme)
|
25
27
|
|
26
|
-
# @return [
|
28
|
+
# @return [String] The name of terminal symbol matching the lexeme.
|
27
29
|
attr_reader(:terminal)
|
28
30
|
|
29
31
|
# @return [Position] The position of the lexeme in the source file.
|
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Rley # This module is used as a namespace
|
2
4
|
module Lexical # This module is used as a namespace
|
3
|
-
# A token range (also called an extent) represents an interval
|
5
|
+
# A token range (also called an extent) represents an interval
|
4
6
|
# of token positions that is matched by a given grammar symbol.
|
5
7
|
# For instance consider the expression E: 3 + 11,
|
6
8
|
# let's assume that the integer literal '3' is the fifth input token and
|
7
9
|
# that the '+' and '11' tokens are respectively at position 6 and 7;
|
8
10
|
# then the token range associated with E is [5, 7]
|
9
|
-
# While the parse tree/forest is being constructed the boundaries of the
|
11
|
+
# While the parse tree/forest is being constructed the boundaries of the
|
10
12
|
# token range can be temporarily undefined (= set to nil)
|
11
13
|
class TokenRange
|
12
14
|
# The index of the lower bound of token range
|
@@ -45,8 +47,8 @@ module Rley # This module is used as a namespace
|
|
45
47
|
end
|
46
48
|
|
47
49
|
# true when both bounds aren't nil.
|
48
|
-
def bounded?
|
49
|
-
|
50
|
+
def bounded?
|
51
|
+
!(low.nil? || high.nil?)
|
50
52
|
end
|
51
53
|
|
52
54
|
# Conditional assign
|
@@ -71,8 +73,8 @@ module Rley # This module is used as a namespace
|
|
71
73
|
def to_string(_indentation)
|
72
74
|
low_text = low.nil? ? '?' : low.to_s
|
73
75
|
high_text = high.nil? ? '?' : high.to_s
|
74
|
-
|
75
|
-
|
76
|
+
|
77
|
+
"[#{low_text}, #{high_text}]"
|
76
78
|
end
|
77
79
|
|
78
80
|
private
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# require 'pry'
|
2
4
|
require 'prime'
|
3
5
|
|
@@ -13,8 +15,8 @@ module Rley # This module is used as a namespace
|
|
13
15
|
@signatures = subnodes.map { |_| prime_enumerator.next }
|
14
16
|
end
|
15
17
|
|
16
|
-
def signature_exist?
|
17
|
-
|
18
|
+
def signature_exist?
|
19
|
+
!@signatures.nil?
|
18
20
|
end
|
19
21
|
end # class
|
20
22
|
end # module
|
@@ -67,7 +69,7 @@ module Rley # This module is used as a namespace
|
|
67
69
|
end
|
68
70
|
|
69
71
|
# The signal to begin the visit of the parse forest.
|
70
|
-
def start
|
72
|
+
def start
|
71
73
|
pforest.accept(self)
|
72
74
|
end
|
73
75
|
|
@@ -167,7 +169,7 @@ module Rley # This module is used as a namespace
|
|
167
169
|
def broadcast(msg, *args)
|
168
170
|
subscribers.each do |subscr|
|
169
171
|
next unless subscr.respond_to?(msg) || subscr.respond_to?(:accept_all)
|
170
|
-
|
172
|
+
|
171
173
|
subscr.send(msg, *args)
|
172
174
|
end
|
173
175
|
end
|
@@ -188,7 +190,7 @@ module Rley # This module is used as a namespace
|
|
188
190
|
|
189
191
|
def pop_node
|
190
192
|
return if legs.empty?
|
191
|
-
|
193
|
+
|
192
194
|
legs.pop
|
193
195
|
end
|
194
196
|
end # class
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative '../ptree/parse_tree'
|
2
4
|
require_relative 'parse_tree_builder'
|
3
5
|
|
@@ -18,14 +20,14 @@ module Rley # This module is used as a namespace
|
|
18
20
|
# Returned hash contains pairs of the form:
|
19
21
|
# terminal name => Class implementing the terminal tokens
|
20
22
|
# terminal name => Hash with pairs: production name => Class
|
21
|
-
def terminal2node
|
23
|
+
def terminal2node
|
22
24
|
raise NotImplementedError
|
23
25
|
end
|
24
26
|
|
25
27
|
# Method to override in subclass.
|
26
28
|
# Default class for representing terminal nodes.
|
27
29
|
# @return [Class]
|
28
|
-
def terminalnode_class
|
30
|
+
def terminalnode_class
|
29
31
|
PTree::TerminalNode
|
30
32
|
end
|
31
33
|
|
@@ -35,7 +37,7 @@ module Rley # This module is used as a namespace
|
|
35
37
|
# @param aProductionName [String]
|
36
38
|
# @return [String]
|
37
39
|
def method_name(aProductionName)
|
38
|
-
|
40
|
+
"reduce_#{aProductionName}"
|
39
41
|
end
|
40
42
|
|
41
43
|
# Utility method.
|
@@ -44,7 +46,7 @@ module Rley # This module is used as a namespace
|
|
44
46
|
# @param _tokens [Array<Lexical::Token>]
|
45
47
|
# @param theChildren [Array<Object>]
|
46
48
|
def return_first_child(_range, _tokens, theChildren)
|
47
|
-
|
49
|
+
theChildren[0]
|
48
50
|
end
|
49
51
|
|
50
52
|
# Utility method.
|
@@ -53,7 +55,7 @@ module Rley # This module is used as a namespace
|
|
53
55
|
# @param _tokens [Array<Lexical::Token>]
|
54
56
|
# @param theChildren [Array<Object>]
|
55
57
|
def return_second_child(_range, _tokens, theChildren)
|
56
|
-
|
58
|
+
theChildren[1]
|
57
59
|
end
|
58
60
|
|
59
61
|
# Utility method.
|
@@ -62,7 +64,7 @@ module Rley # This module is used as a namespace
|
|
62
64
|
# @param _tokens [Array<Lexical::Token>]
|
63
65
|
# @param theChildren [Array<Object>]
|
64
66
|
def return_last_child(_range, _tokens, theChildren)
|
65
|
-
|
67
|
+
theChildren[-1]
|
66
68
|
end
|
67
69
|
|
68
70
|
# Simply return an epsilon symbol
|
@@ -70,7 +72,7 @@ module Rley # This module is used as a namespace
|
|
70
72
|
# @param _tokens [Array<Lexical::Token>]
|
71
73
|
# @param _children [Array<Object>]
|
72
74
|
def return_epsilon(_range, _tokens, _children)
|
73
|
-
|
75
|
+
nil
|
74
76
|
end
|
75
77
|
|
76
78
|
protected
|
@@ -79,7 +81,7 @@ module Rley # This module is used as a namespace
|
|
79
81
|
# Create a parse tree object with given
|
80
82
|
# node as root node.
|
81
83
|
def create_tree(aRootNode)
|
82
|
-
|
84
|
+
Rley::PTree::ParseTree.new(aRootNode)
|
83
85
|
end
|
84
86
|
|
85
87
|
# Factory method for creating a node object for the given
|
@@ -94,9 +96,7 @@ module Rley # This module is used as a namespace
|
|
94
96
|
# Lexical ambiguity...
|
95
97
|
klass = klass.fetch(aProduction.name)
|
96
98
|
end
|
97
|
-
|
98
|
-
|
99
|
-
return node
|
99
|
+
klass.new(aToken, aTokenPosition)
|
100
100
|
end
|
101
101
|
|
102
102
|
# Method to override.
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'parse_tree_builder'
|
2
4
|
require_relative '../ptree/non_terminal_node'
|
3
5
|
require_relative '../ptree/terminal_node'
|
@@ -14,13 +16,13 @@ module Rley # This module is used as a namespace
|
|
14
16
|
# nodes) and using a step by step approach.
|
15
17
|
class CSTBuilder < ParseTreeBuilder
|
16
18
|
protected
|
17
|
-
|
19
|
+
|
18
20
|
# Method to override
|
19
21
|
# Create a parse tree object with given
|
20
22
|
# node as root node.
|
21
23
|
def create_tree(aRootNode)
|
22
24
|
return Rley::PTree::ParseTree.new(aRootNode)
|
23
|
-
end
|
25
|
+
end
|
24
26
|
|
25
27
|
# Method to override
|
26
28
|
# Factory method for creating a node object for the given
|
@@ -40,8 +42,9 @@ module Rley # This module is used as a namespace
|
|
40
42
|
# @param theChildren [Array] Children nodes (one per rhs symbol)
|
41
43
|
def new_parent_node(aProduction, aRange, _tokens, theChildren)
|
42
44
|
node = Rley::PTree::NonTerminalNode.new(aProduction.lhs, aRange)
|
43
|
-
theChildren
|
44
|
-
|
45
|
+
theChildren&.reverse_each { |child| node.add_subnode(child) }
|
46
|
+
|
47
|
+
node
|
45
48
|
end
|
46
49
|
end # class
|
47
50
|
end # module
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative '../syntax/terminal'
|
2
4
|
require_relative '../syntax/non_terminal'
|
3
5
|
require_relative '../gfg/end_vertex'
|
@@ -40,9 +42,9 @@ module Rley # This module is used as a namespace
|
|
40
42
|
@entry2node = {}
|
41
43
|
@entry2path_to_alt = {}
|
42
44
|
end
|
43
|
-
|
45
|
+
|
44
46
|
# Notify the builder that the construction is over
|
45
|
-
def done!
|
47
|
+
def done!
|
46
48
|
result.done!
|
47
49
|
end
|
48
50
|
|
@@ -62,20 +64,21 @@ module Rley # This module is used as a namespace
|
|
62
64
|
end
|
63
65
|
|
64
66
|
# Return the current_parent node
|
65
|
-
def curr_parent
|
66
|
-
|
67
|
+
def curr_parent
|
68
|
+
curr_path.last
|
67
69
|
end
|
68
70
|
|
69
71
|
private
|
70
72
|
|
71
73
|
def process_start_entry(_anEvent, _anEntry, _anIndex)
|
72
74
|
curr_path.pop
|
75
|
+
raise StandardError, "path is nil for #{anEntry}" if curr_path.nil?
|
73
76
|
end
|
74
77
|
|
75
78
|
def process_end_entry(anEvent, anEntry, anIndex)
|
76
79
|
case anEvent
|
77
80
|
when :visit
|
78
|
-
# create a node with the non-terminal
|
81
|
+
# create a forest node with the non-terminal
|
79
82
|
# with same right extent as curr_entry_set_index
|
80
83
|
# add the new node as first child of current_parent
|
81
84
|
# append the new node to the curr_path
|
@@ -87,16 +90,18 @@ module Rley # This module is used as a namespace
|
|
87
90
|
when :backtrack
|
88
91
|
# Restore path
|
89
92
|
@curr_path = entry2path_to_alt[anEntry].dup
|
93
|
+
raise StandardError, "path is nil for #{anEntry}" if curr_path.nil?
|
90
94
|
|
91
95
|
when :revisit
|
92
|
-
# Retrieve the already existing node corresponding
|
96
|
+
# Retrieve the already existing forest node corresponding
|
93
97
|
# to re-visited entry
|
94
98
|
popular = @entry2node[anEntry]
|
95
99
|
|
96
100
|
# Share with parent (if needed)...
|
97
|
-
|
98
|
-
|
99
|
-
|
101
|
+
if curr_parent
|
102
|
+
children = curr_parent.subnodes
|
103
|
+
curr_parent.add_subnode(popular) unless children.include? popular
|
104
|
+
end
|
100
105
|
else
|
101
106
|
raise NotImplementedError
|
102
107
|
end
|
@@ -105,18 +110,18 @@ module Rley # This module is used as a namespace
|
|
105
110
|
def process_item_entry(anEvent, anEntry, anIndex)
|
106
111
|
case anEvent
|
107
112
|
when :visit
|
108
|
-
if anEntry.exit_entry?
|
113
|
+
if anEntry.exit_entry? && last_visitee.end_entry? &&
|
114
|
+
last_visitee.antecedents.size > 1
|
109
115
|
# Previous entry was an end entry (X. pattern)
|
110
116
|
# Does the previous entry have multiple antecedent?
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
end
|
117
|
+
|
118
|
+
# Store current path for later backtracking
|
119
|
+
# puts "Store backtrack context #{last_visitee}"
|
120
|
+
# puts "path [#{curr_path.map{|e|e.to_string(0)}.join(', ')}]"
|
121
|
+
entry2path_to_alt[last_visitee] = curr_path.dup
|
122
|
+
curr_parent.refinement = :or
|
123
|
+
|
124
|
+
create_alternative_node(anEntry)
|
120
125
|
end
|
121
126
|
|
122
127
|
# Does this entry have multiple antecedent?
|
@@ -149,6 +154,8 @@ module Rley # This module is used as a namespace
|
|
149
154
|
when :backtrack
|
150
155
|
# Restore path
|
151
156
|
@curr_path = entry2path_to_alt[anEntry].dup
|
157
|
+
raise StandardError, 'path is nil' if curr_path.nil?
|
158
|
+
|
152
159
|
create_alternative_node(anEntry)
|
153
160
|
|
154
161
|
when :revisit
|
@@ -172,7 +179,7 @@ module Rley # This module is used as a namespace
|
|
172
179
|
|
173
180
|
# Create an empty parse forest
|
174
181
|
def create_forest(aRootNode)
|
175
|
-
|
182
|
+
Rley::SPPF::ParseForest.new(aRootNode)
|
176
183
|
end
|
177
184
|
|
178
185
|
# Factory method. Build and return an SPPF non-terminal node.
|
@@ -183,7 +190,7 @@ module Rley # This module is used as a namespace
|
|
183
190
|
add_subnode(new_node)
|
184
191
|
# puts "FOREST ADD #{curr_parent.key if curr_parent}/#{new_node.key}"
|
185
192
|
|
186
|
-
|
193
|
+
new_node
|
187
194
|
end
|
188
195
|
|
189
196
|
# Add an alternative node to the forest
|
@@ -195,7 +202,7 @@ module Rley # This module is used as a namespace
|
|
195
202
|
result.is_ambiguous = true
|
196
203
|
# puts "FOREST ADD #{alternative.key}"
|
197
204
|
|
198
|
-
|
205
|
+
alternative
|
199
206
|
end
|
200
207
|
|
201
208
|
# create a token node,
|
@@ -209,7 +216,7 @@ module Rley # This module is used as a namespace
|
|
209
216
|
candidate = add_node_to_forest(new_node)
|
210
217
|
entry2node[anEntry] = candidate
|
211
218
|
|
212
|
-
|
219
|
+
candidate
|
213
220
|
end
|
214
221
|
|
215
222
|
def create_epsilon_node(anEntry, anIndex)
|
@@ -217,7 +224,7 @@ module Rley # This module is used as a namespace
|
|
217
224
|
candidate = add_node_to_forest(new_node)
|
218
225
|
entry2node[anEntry] = candidate
|
219
226
|
|
220
|
-
|
227
|
+
candidate
|
221
228
|
end
|
222
229
|
|
223
230
|
# Add the given node if not yet present in parse forest
|
@@ -232,15 +239,19 @@ module Rley # This module is used as a namespace
|
|
232
239
|
end
|
233
240
|
add_subnode(new_node, false)
|
234
241
|
|
235
|
-
|
242
|
+
new_node
|
236
243
|
end
|
237
244
|
|
238
245
|
# Add the given node as sub-node of current parent node
|
239
246
|
# Optionally add the node to the current path
|
247
|
+
# rubocop: disable Style/OptionalBooleanParameter
|
240
248
|
def add_subnode(aNode, addToPath = true)
|
249
|
+
raise StandardError, 'node is nil' if aNode.nil?
|
250
|
+
|
241
251
|
curr_parent.add_subnode(aNode) unless curr_path.empty?
|
242
252
|
curr_path << aNode if addToPath
|
243
253
|
end
|
254
|
+
# rubocop: enable Style/OptionalBooleanParameter
|
244
255
|
end # class
|
245
256
|
end # module
|
246
257
|
end # module
|