rley 0.7.07 → 0.7.08
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +348 -54
- data/LICENSE.txt +1 -1
- data/README.md +3 -2
- data/examples/NLP/engtagger.rb +193 -190
- data/examples/NLP/nano_eng/nano_grammar.rb +5 -5
- data/examples/data_formats/JSON/cli_options.rb +1 -1
- data/examples/data_formats/JSON/json_ast_builder.rb +12 -9
- data/examples/data_formats/JSON/json_ast_nodes.rb +12 -21
- data/examples/data_formats/JSON/json_grammar.rb +2 -2
- 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 +2 -2
- 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 +3 -3
- 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/base/dotted_item.rb +23 -31
- data/lib/rley/constants.rb +2 -2
- data/lib/rley/engine.rb +20 -23
- 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/lexical/token_range.rb +6 -6
- data/lib/rley/parse_forest_visitor.rb +5 -5
- data/lib/rley/parse_rep/ast_base_builder.rb +9 -11
- data/lib/rley/parse_rep/cst_builder.rb +5 -6
- data/lib/rley/parse_rep/parse_forest_builder.rb +20 -18
- data/lib/rley/parse_rep/parse_forest_factory.rb +3 -3
- data/lib/rley/parse_rep/parse_rep_creator.rb +11 -13
- 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 +20 -22
- data/lib/rley/parser/gfg_parsing.rb +16 -30
- data/lib/rley/parser/parse_entry.rb +25 -31
- data/lib/rley/parser/parse_entry_set.rb +18 -15
- data/lib/rley/parser/parse_entry_tracker.rb +4 -4
- data/lib/rley/parser/parse_state.rb +16 -21
- data/lib/rley/parser/parse_state_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/parser/state_set.rb +9 -10
- 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.rb +5 -5
- data/lib/rley/syntax/grammar_builder.rb +9 -9
- data/lib/rley/syntax/grm_symbol.rb +6 -6
- data/lib/rley/syntax/non_terminal.rb +9 -15
- data/lib/rley/syntax/production.rb +10 -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 +17 -15
- 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/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/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 -6
- data/spec/rley/parse_rep/cst_builder_spec.rb +5 -5
- data/spec/rley/parse_rep/groucho_spec.rb +21 -21
- data/spec/rley/parse_rep/parse_forest_builder_spec.rb +26 -26
- data/spec/rley/parse_rep/parse_forest_factory_spec.rb +6 -6
- data/spec/rley/parse_rep/parse_tree_factory_spec.rb +2 -2
- data/spec/rley/parse_tree_visitor_spec.rb +10 -8
- data/spec/rley/parser/error_reason_spec.rb +6 -6
- data/spec/rley/parser/gfg_earley_parser_spec.rb +4 -2
- data/spec/rley/parser/gfg_parsing_spec.rb +4 -8
- data/spec/rley/parser/parse_entry_spec.rb +19 -19
- data/spec/rley/parser/parse_state_spec.rb +5 -5
- data/spec/rley/parser/parse_walker_factory_spec.rb +1 -1
- data/spec/rley/parser/state_set_spec.rb +22 -22
- 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 +3 -4
- data/spec/rley/support/grammar_abc_helper.rb +2 -4
- data/spec/rley/support/grammar_ambig01_helper.rb +4 -5
- data/spec/rley/support/grammar_arr_int_helper.rb +4 -5
- data/spec/rley/support/grammar_b_expr_helper.rb +4 -5
- data/spec/rley/support/grammar_l0_helper.rb +10 -11
- data/spec/rley/support/grammar_pb_helper.rb +6 -5
- data/spec/rley/support/grammar_sppf_helper.rb +1 -1
- data/spec/rley/syntax/grammar_builder_spec.rb +5 -5
- data/spec/rley/syntax/grammar_spec.rb +6 -6
- data/spec/rley/syntax/grm_symbol_spec.rb +1 -1
- data/spec/rley/syntax/non_terminal_spec.rb +8 -8
- data/spec/rley/syntax/production_spec.rb +13 -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 +21 -62
- data/.simplecov +0 -8
@@ -32,7 +32,7 @@ module Rley # This module is used as a namespace
|
|
32
32
|
# Returns a string containing a human-readable representation of the
|
33
33
|
# production.
|
34
34
|
# @return [String]
|
35
|
-
def inspect
|
35
|
+
def inspect
|
36
36
|
result = selfie
|
37
37
|
result << ' @antecedents=['
|
38
38
|
antecedents.each do |antec|
|
@@ -40,7 +40,7 @@ module Rley # This module is used as a namespace
|
|
40
40
|
end
|
41
41
|
result << ']>'
|
42
42
|
|
43
|
-
|
43
|
+
result
|
44
44
|
end
|
45
45
|
|
46
46
|
# Add a link to an antecedent parse entry
|
@@ -53,56 +53,55 @@ module Rley # This module is used as a namespace
|
|
53
53
|
def ==(other)
|
54
54
|
return true if equal? other
|
55
55
|
|
56
|
-
|
57
|
-
return result
|
56
|
+
(vertex == other.vertex) && (origin == other.origin)
|
58
57
|
end
|
59
|
-
|
58
|
+
|
60
59
|
def hash
|
61
|
-
@hash ||=
|
60
|
+
@hash ||= (vertex.oid_str + "-#{origin}").hash
|
62
61
|
end
|
63
62
|
|
64
63
|
# Returns true iff the vertex is a start vertex (i.e. of the form: .X)
|
65
|
-
def start_entry?
|
66
|
-
|
64
|
+
def start_entry?
|
65
|
+
vertex.kind_of?(GFG::StartVertex)
|
67
66
|
end
|
68
67
|
|
69
68
|
# Returns true iff the vertex is at the start of rhs
|
70
69
|
# (i.e. of the form: X => .Y
|
71
|
-
def entry_entry?
|
70
|
+
def entry_entry?
|
72
71
|
return false unless vertex.kind_of?(GFG::ItemVertex)
|
73
72
|
|
74
|
-
|
73
|
+
vertex.dotted_item.at_start?
|
75
74
|
end
|
76
75
|
|
77
76
|
# Returns true iff the vertex corresponds to a dotted item
|
78
77
|
# X => Y
|
79
78
|
def dotted_entry?
|
80
|
-
|
79
|
+
vertex.kind_of?(GFG::ItemVertex)
|
81
80
|
end
|
82
81
|
|
83
82
|
# Returns true iff the vertex is at end of rhs (i.e. of the form: X => Y.)
|
84
|
-
def exit_entry?
|
85
|
-
|
83
|
+
def exit_entry?
|
84
|
+
vertex.complete?
|
86
85
|
end
|
87
86
|
|
88
87
|
# Returns true iff the vertex is an end vertex (i.e. of the form: X.)
|
89
|
-
def end_entry?
|
90
|
-
|
88
|
+
def end_entry?
|
89
|
+
vertex.kind_of?(GFG::EndVertex)
|
91
90
|
end
|
92
91
|
|
93
92
|
# Return the symbol before the dot (if any)
|
94
|
-
def prev_symbol
|
95
|
-
|
93
|
+
def prev_symbol
|
94
|
+
vertex.prev_symbol
|
96
95
|
end
|
97
96
|
|
98
97
|
# Return the symbol after the dot (if any)
|
99
|
-
def next_symbol
|
100
|
-
|
98
|
+
def next_symbol
|
99
|
+
vertex.next_symbol
|
101
100
|
end
|
102
101
|
|
103
102
|
# Return true if the entry has no antecedent entry
|
104
|
-
def orphan?
|
105
|
-
|
103
|
+
def orphan?
|
104
|
+
antecedents.empty?
|
106
105
|
end
|
107
106
|
|
108
107
|
=begin
|
@@ -117,11 +116,6 @@ module Rley # This module is used as a namespace
|
|
117
116
|
return vertex.predicted_item?
|
118
117
|
end
|
119
118
|
|
120
|
-
# Next expected symbol in the production
|
121
|
-
def next_symbol()
|
122
|
-
return vertex.next_symbol
|
123
|
-
end
|
124
|
-
|
125
119
|
# Does this parse state have the 'other' as successor?
|
126
120
|
def precedes?(other)
|
127
121
|
return false if self == other
|
@@ -145,21 +139,21 @@ module Rley # This module is used as a namespace
|
|
145
139
|
# The format of the text representation is
|
146
140
|
# "format of dotted rule" + " | " + origin
|
147
141
|
# @return [String]
|
148
|
-
def to_s
|
149
|
-
|
142
|
+
def to_s
|
143
|
+
vertex.label + " | #{origin}"
|
150
144
|
end
|
151
145
|
|
152
146
|
protected
|
153
147
|
|
154
148
|
# Returns a human-readable and partial representation of itself.
|
155
149
|
# @return [String]
|
156
|
-
def selfie
|
150
|
+
def selfie
|
157
151
|
result = +"#<#{self.class.name}:#{object_id}"
|
158
152
|
result << " @vertex=<#{vertex.class.name}:#{vertex.object_id}"
|
159
153
|
result << " label=#{vertex.label}>"
|
160
154
|
result << " @origin=#{origin}"
|
161
155
|
|
162
|
-
|
156
|
+
result
|
163
157
|
end
|
164
158
|
|
165
159
|
private
|
@@ -169,7 +163,7 @@ module Rley # This module is used as a namespace
|
|
169
163
|
def valid_vertex(aVertex)
|
170
164
|
raise StandardError, 'GFG vertex cannot be nil' if aVertex.nil?
|
171
165
|
|
172
|
-
|
166
|
+
aVertex
|
173
167
|
end
|
174
168
|
end # class
|
175
169
|
end # module
|
@@ -16,44 +16,45 @@ module Rley # This module is used as a namespace
|
|
16
16
|
|
17
17
|
# @return [Array<ParseEntry>] The array of parse entries
|
18
18
|
attr_reader :entries
|
19
|
-
|
19
|
+
|
20
20
|
# @return [Hash] A Hash with pairs { hash of ParseEntry => ParseEntry }
|
21
|
-
attr_reader :membership
|
21
|
+
attr_reader :membership
|
22
22
|
|
23
23
|
# Constructor.
|
24
|
-
def initialize
|
24
|
+
def initialize
|
25
25
|
@entries = []
|
26
26
|
@membership = {}
|
27
27
|
@entries4term = Hash.new { |hash, key| hash[key] = [] }
|
28
28
|
@entries4n_term = Hash.new { |hash, key| hash[key] = [] }
|
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
|
# set of parse entries.
|
33
33
|
# @return [String]
|
34
|
-
def inspect
|
34
|
+
def inspect
|
35
35
|
result = +"#<#{self.class.name}:#{object_id}"
|
36
36
|
result << ' @entries=['
|
37
37
|
entries.each { |e| result << e.inspect }
|
38
38
|
result << ']>'
|
39
|
-
|
39
|
+
|
40
|
+
result
|
40
41
|
end
|
41
42
|
|
42
43
|
# Access the entry at given position
|
43
44
|
def [](index)
|
44
|
-
|
45
|
+
entries[index]
|
45
46
|
end
|
46
47
|
|
47
48
|
# Returns a Hash with pairs of the form:
|
48
49
|
# terminal symbol => [ parse entry expecting the terminal ]
|
49
50
|
def entries4term(aTerminal)
|
50
|
-
|
51
|
+
@entries4term.fetch(aTerminal, [])
|
51
52
|
end
|
52
53
|
|
53
54
|
# Returns a Hash with pairs of the form:
|
54
55
|
# non terminal symbol => [ parse entry expecting the non-terminal ]
|
55
56
|
def entries4n_term(aNonTerminal)
|
56
|
-
|
57
|
+
@entries4n_term.fetch(aNonTerminal, [])
|
57
58
|
end
|
58
59
|
|
59
60
|
# Append the given entry (if it isn't yet in the set)
|
@@ -71,11 +72,11 @@ module Rley # This module is used as a namespace
|
|
71
72
|
result = anEntry
|
72
73
|
end
|
73
74
|
|
74
|
-
|
75
|
+
result
|
75
76
|
end
|
76
77
|
|
77
78
|
# Return an Array of Arrays of ambiguous parse entries.
|
78
|
-
def ambiguities
|
79
|
+
def ambiguities
|
79
80
|
complete_entries = entries.select(&:exit_entry?)
|
80
81
|
return [] if complete_entries.size <= 1
|
81
82
|
|
@@ -90,20 +91,22 @@ module Rley # This module is used as a namespace
|
|
90
91
|
ambiguous_groups << a_group if a_group.size > 1
|
91
92
|
end
|
92
93
|
|
93
|
-
|
94
|
+
ambiguous_groups
|
94
95
|
end
|
95
96
|
|
96
97
|
# The list of distinct expected terminal symbols. An expected symbol
|
97
98
|
# is on the left of a dot in a parse state of the parse set.
|
98
|
-
def expected_terminals
|
99
|
+
def expected_terminals
|
99
100
|
return @entries4term.keys
|
100
101
|
end
|
101
|
-
|
102
|
+
|
102
103
|
def count_edges
|
104
|
+
# rubocop: disable Lint/UselessAssignment
|
103
105
|
entries.reduce(0) do |sub_result, entry|
|
104
106
|
sub_result += entry.vertex.edges.size
|
105
107
|
end
|
106
108
|
end
|
109
|
+
# rubocop: enable Lint/UselessAssignment
|
107
110
|
|
108
111
|
private
|
109
112
|
|
@@ -40,16 +40,16 @@ module Rley # This module is used as a namespace
|
|
40
40
|
end
|
41
41
|
|
42
42
|
# The dotted item for the current parse entry.
|
43
|
-
def curr_dotted_item
|
43
|
+
def curr_dotted_item
|
44
44
|
parse_entry.dotted_rule
|
45
45
|
end
|
46
46
|
|
47
|
-
def symbol_on_left
|
48
|
-
|
47
|
+
def symbol_on_left
|
48
|
+
curr_dotted_item.prev_symbol
|
49
49
|
end
|
50
50
|
|
51
51
|
# Notification that one begins with the previous entry set
|
52
|
-
def to_prev_entry_set
|
52
|
+
def to_prev_entry_set
|
53
53
|
self.entry_set_index = entry_set_index - 1
|
54
54
|
end
|
55
55
|
end # class
|
@@ -18,26 +18,24 @@ module Rley # This module is used as a namespace
|
|
18
18
|
def ==(other)
|
19
19
|
return true if equal?(other)
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
return result
|
21
|
+
(dotted_rule == other.dotted_rule) &&
|
22
|
+
(origin == other.origin)
|
25
23
|
end
|
26
24
|
|
27
25
|
# Returns true if the dot is at the end of the rhs of the production.
|
28
26
|
# In other words, the complete rhs matches the input.
|
29
|
-
def complete?
|
30
|
-
|
27
|
+
def complete?
|
28
|
+
dotted_rule.reduce_item?
|
31
29
|
end
|
32
30
|
|
33
31
|
# Returns true if the dot is at the start of the rhs of the production.
|
34
|
-
def predicted?
|
35
|
-
|
32
|
+
def predicted?
|
33
|
+
dotted_rule.predicted_item?
|
36
34
|
end
|
37
35
|
|
38
36
|
# Next expected symbol in the production
|
39
|
-
def next_symbol
|
40
|
-
|
37
|
+
def next_symbol
|
38
|
+
dotted_rule.next_symbol
|
41
39
|
end
|
42
40
|
|
43
41
|
# Does this parse state have the 'other' as successor?
|
@@ -50,31 +48,28 @@ module Rley # This module is used as a namespace
|
|
50
48
|
return false unless dotted_rule.production == other_production
|
51
49
|
|
52
50
|
prev_position = other.dotted_rule.prev_position
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
return result
|
51
|
+
if prev_position.nil?
|
52
|
+
false
|
53
|
+
else
|
54
|
+
dotted_rule.position == prev_position
|
55
|
+
end
|
60
56
|
end
|
61
57
|
|
62
58
|
# Give a String representation of itself.
|
63
59
|
# The format of the text representation is
|
64
60
|
# "format of dotted rule" + " | " + origin
|
65
61
|
# @return [String]
|
66
|
-
def to_s
|
67
|
-
|
62
|
+
def to_s
|
63
|
+
dotted_rule.to_s + " | #{origin}"
|
68
64
|
end
|
69
65
|
|
70
|
-
|
71
66
|
private
|
72
67
|
|
73
68
|
# Return the validated dotted item(rule)
|
74
69
|
def valid_dotted_rule(aDottedRule)
|
75
70
|
raise StandardError, 'Dotted item cannot be nil' if aDottedRule.nil?
|
76
71
|
|
77
|
-
|
72
|
+
aDottedRule
|
78
73
|
end
|
79
74
|
end # class
|
80
75
|
end # module
|
@@ -28,7 +28,7 @@ module Rley # This module is used as a namespace
|
|
28
28
|
# Write accessor. Set the given parse state as the current one.
|
29
29
|
def parse_state=(aParseState)
|
30
30
|
raise StandardError, 'Nil parse state' if aParseState.nil?
|
31
|
-
|
31
|
+
|
32
32
|
@parse_state = aParseState
|
33
33
|
processed_states[parse_state] = true
|
34
34
|
end
|
@@ -40,16 +40,16 @@ module Rley # This module is used as a namespace
|
|
40
40
|
end
|
41
41
|
|
42
42
|
# The dotted item for the current parse state.
|
43
|
-
def curr_dotted_item
|
43
|
+
def curr_dotted_item
|
44
44
|
parse_state.dotted_rule
|
45
45
|
end
|
46
46
|
|
47
|
-
def symbol_on_left
|
47
|
+
def symbol_on_left
|
48
48
|
return curr_dotted_item.prev_symbol
|
49
49
|
end
|
50
50
|
|
51
51
|
# Notification that one begins with the previous state set
|
52
|
-
def to_prev_state_set
|
52
|
+
def to_prev_state_set
|
53
53
|
self.state_set_index = state_set_index - 1
|
54
54
|
end
|
55
55
|
end # class
|
@@ -11,9 +11,7 @@ module Rley # This module is used as a namespace
|
|
11
11
|
|
12
12
|
# The trace level
|
13
13
|
attr_reader(:level)
|
14
|
-
|
15
14
|
attr_reader(:lexemes)
|
16
|
-
|
17
15
|
attr_reader(:col_width)
|
18
16
|
|
19
17
|
def initialize(aTraceLevel, anIO, aTokenSequence)
|
@@ -36,8 +34,8 @@ module Rley # This module is used as a namespace
|
|
36
34
|
def trace_scanning(aStatesetIndex, aParseState)
|
37
35
|
return unless level
|
38
36
|
|
39
|
-
scan_picture =
|
40
|
-
org = OpenStruct.new(origin: aStatesetIndex - 1,
|
37
|
+
scan_picture = "[#{'-' * (col_width - 1)}]"
|
38
|
+
org = OpenStruct.new(origin: aStatesetIndex - 1,
|
41
39
|
dotted_rule: aParseState.dotted_rule)
|
42
40
|
trace_diagram(aStatesetIndex, org, scan_picture)
|
43
41
|
end
|
@@ -47,35 +45,36 @@ module Rley # This module is used as a namespace
|
|
47
45
|
|
48
46
|
trace_diagram(aStatesetIndex, aParseState, '>')
|
49
47
|
end
|
50
|
-
|
48
|
+
|
51
49
|
def trace_completion(aStatesetIndex, aParseState)
|
52
50
|
return unless level
|
53
51
|
|
54
|
-
if aStatesetIndex == lexemes.size && aParseState.origin.zero? &&
|
52
|
+
if aStatesetIndex == lexemes.size && aParseState.origin.zero? &&
|
55
53
|
aParseState.complete?
|
56
54
|
picture = '=' * (col_width * lexemes.size - 1)
|
57
55
|
else
|
58
56
|
count = col_width * (aStatesetIndex - aParseState.origin) - 1
|
59
57
|
picture = '-' * count
|
60
58
|
end
|
61
|
-
completion_picture =
|
59
|
+
completion_picture = "[#{picture}#{aParseState.complete? ? ']' : '>'}"
|
62
60
|
trace_diagram(aStatesetIndex, aParseState, completion_picture)
|
63
61
|
end
|
64
62
|
|
65
63
|
private
|
66
64
|
|
67
|
-
def emit_tokens
|
65
|
+
def emit_tokens
|
68
66
|
literals = lexemes.map { |lx| "'#{lx}'" }
|
69
|
-
print_if 1,
|
67
|
+
print_if 1, "[#{literals.join(', ')}]\n"
|
70
68
|
end
|
71
69
|
|
72
|
-
def emit_heading
|
70
|
+
def emit_heading
|
73
71
|
longest = lexemes.map(&:length).max
|
74
72
|
@col_width = longest + 3
|
75
73
|
headers = lexemes.map { |l| l.center(col_width - 1, ' ').to_s }
|
76
|
-
print_if 1,
|
74
|
+
print_if 1, "|.#{headers.join('.')}.|\n"
|
77
75
|
end
|
78
76
|
|
77
|
+
# rubocop: disable Style/StringConcatenation
|
79
78
|
def padding(aStatesetIndex, aParseState, aPicture)
|
80
79
|
l_pad_pattern = '.' + ' ' * (col_width - 1)
|
81
80
|
left_padding = l_pad_pattern * [0, aParseState.origin].max
|
@@ -83,6 +82,7 @@ module Rley # This module is used as a namespace
|
|
83
82
|
right_padding = r_pad_pattern * (lexemes.size - aStatesetIndex)
|
84
83
|
return left_padding + aPicture + right_padding
|
85
84
|
end
|
85
|
+
# rubocop: enable Style/StringConcatenation
|
86
86
|
|
87
87
|
def parse_state_str(aStatesetIndex, aParseState)
|
88
88
|
"[#{aParseState.origin}:#{aStatesetIndex}] #{aParseState.dotted_rule}"
|
@@ -91,10 +91,10 @@ module Rley # This module is used as a namespace
|
|
91
91
|
def trace_diagram(aStatesetIndex, aParseState, aPicture)
|
92
92
|
diagram = padding(aStatesetIndex, aParseState, aPicture)
|
93
93
|
prefix = '|'
|
94
|
-
suffix =
|
94
|
+
suffix = "| #{parse_state_str(aStatesetIndex, aParseState)}"
|
95
95
|
trace = prefix + diagram + suffix
|
96
96
|
|
97
|
-
print_if 1, trace
|
97
|
+
print_if 1, "#{trace}\n"
|
98
98
|
end
|
99
99
|
end # class
|
100
100
|
end # module
|
@@ -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
|