rley 0.7.00 → 0.7.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 +51 -34
- data/.travis.yml +10 -9
- data/CHANGELOG.md +9 -0
- data/LICENSE.txt +1 -1
- data/README.md +0 -1
- data/appveyor.yml +10 -8
- data/examples/NLP/benchmark_pico_en.rb +3 -2
- data/examples/NLP/engtagger.rb +23 -12
- data/examples/NLP/nano_eng/nano_en_demo.rb +4 -3
- data/examples/NLP/pico_en_demo.rb +3 -2
- data/examples/data_formats/JSON/json_ast_nodes.rb +3 -0
- data/examples/data_formats/JSON/json_demo.rb +1 -0
- data/examples/data_formats/JSON/json_lexer.rb +2 -1
- data/lib/rley/base/dotted_item.rb +2 -0
- data/lib/rley/constants.rb +1 -1
- data/lib/rley/engine.rb +8 -7
- data/lib/rley/gfg/grm_flow_graph.rb +2 -0
- data/lib/rley/gfg/item_vertex.rb +2 -0
- data/lib/rley/gfg/vertex.rb +2 -1
- data/lib/rley/lexical/token.rb +5 -4
- data/lib/rley/parse_forest_visitor.rb +7 -5
- data/lib/rley/parse_rep/ast_base_builder.rb +1 -1
- data/lib/rley/parse_rep/parse_rep_creator.rb +2 -2
- data/lib/rley/parse_rep/parse_tree_builder.rb +1 -0
- data/lib/rley/parse_tree_visitor.rb +2 -0
- data/lib/rley/parser/error_reason.rb +8 -6
- data/lib/rley/parser/gfg_chart.rb +5 -5
- data/lib/rley/parser/gfg_parsing.rb +10 -5
- data/lib/rley/parser/parse_entry_tracker.rb +1 -0
- data/lib/rley/parser/parse_state.rb +2 -1
- data/lib/rley/parser/parse_state_tracker.rb +1 -0
- data/lib/rley/parser/parse_walker_factory.rb +7 -1
- data/lib/rley/ptree/parse_tree_node.rb +1 -0
- data/lib/rley/sppf/parse_forest.rb +9 -7
- data/lib/rley/syntax/grammar.rb +10 -6
- data/lib/rley/syntax/grammar_builder.rb +2 -2
- data/lib/rley/syntax/grm_symbol.rb +1 -0
- data/lib/support/base_tokenizer.rb +10 -96
- data/spec/rley/engine_spec.rb +3 -3
- data/spec/rley/gfg/grm_flow_graph_spec.rb +1 -0
- data/spec/rley/parse_forest_visitor_spec.rb +63 -38
- data/spec/rley/parse_rep/groucho_spec.rb +9 -8
- data/spec/rley/parse_tree_visitor_spec.rb +1 -1
- data/spec/rley/parser/gfg_earley_parser_spec.rb +7 -7
- data/spec/rley/parser/gfg_parsing_spec.rb +1 -3
- data/spec/rley/parser/parse_entry_spec.rb +1 -1
- data/spec/rley/support/expectation_helper.rb +2 -1
- data/spec/rley/support/grammar_ambig01_helper.rb +4 -3
- data/spec/rley/support/grammar_arr_int_helper.rb +5 -4
- data/spec/rley/support/grammar_b_expr_helper.rb +5 -4
- data/spec/rley/support/grammar_helper.rb +2 -2
- data/spec/rley/support/grammar_l0_helper.rb +3 -2
- data/spec/rley/support/grammar_pb_helper.rb +5 -28
- data/spec/support/base_tokenizer_spec.rb +7 -9
- metadata +2 -2
|
@@ -28,6 +28,7 @@ case cli_options[:format]
|
|
|
28
28
|
when :minify
|
|
29
29
|
msg = "minify format works for 'cst' representation only"
|
|
30
30
|
raise StandardError, msg if tree_rep == :ast
|
|
31
|
+
|
|
31
32
|
renderer = JSONMinifier.new($stdout)
|
|
32
33
|
when :ruby
|
|
33
34
|
msg = "ruby format works for 'ast' representation only"
|
|
@@ -67,6 +67,7 @@ class JSONLexer
|
|
|
67
67
|
end_delimiter = scanner.getch
|
|
68
68
|
err_msg = 'No closing quotes (") found'
|
|
69
69
|
raise ScanError.new(err_msg) if end_delimiter.nil?
|
|
70
|
+
|
|
70
71
|
token = build_token(value, 'string')
|
|
71
72
|
|
|
72
73
|
when /[-0-9]/ # Start character of number literal found
|
|
@@ -85,7 +86,7 @@ class JSONLexer
|
|
|
85
86
|
|
|
86
87
|
return token
|
|
87
88
|
end
|
|
88
|
-
|
|
89
|
+
|
|
89
90
|
def build_token(lexeme, token)
|
|
90
91
|
pos = Rley::Lexical::Position.new(lineno, scanner.pos - line_start)
|
|
91
92
|
Rley::Lexical::Token.new(lexeme, token, pos)
|
|
@@ -113,8 +113,10 @@ module Rley # This module is used as a namespace
|
|
|
113
113
|
# @return [Boolean]
|
|
114
114
|
def successor_of?(another)
|
|
115
115
|
return false if production != another.production
|
|
116
|
+
|
|
116
117
|
to_the_left = prev_position
|
|
117
118
|
return false if to_the_left.nil?
|
|
119
|
+
|
|
118
120
|
return to_the_left == another.position
|
|
119
121
|
end
|
|
120
122
|
|
data/lib/rley/constants.rb
CHANGED
data/lib/rley/engine.rb
CHANGED
|
@@ -30,11 +30,11 @@ module Rley # This module is used as a namespace
|
|
|
30
30
|
# Rley client code from the lower-level classes.
|
|
31
31
|
class Engine
|
|
32
32
|
# @!attribute [r] configuration
|
|
33
|
-
# @return [EngineConfig] the engine's configuration
|
|
33
|
+
# @return [EngineConfig] the engine's configuration
|
|
34
34
|
attr_reader :configuration
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
# @!attribute [r] grammar
|
|
37
|
-
# @return [Rley::Syntax::Grammar] the grammar of the language to parse
|
|
37
|
+
# @return [Rley::Syntax::Grammar] the grammar of the language to parse
|
|
38
38
|
attr_reader :grammar
|
|
39
39
|
|
|
40
40
|
# Constructor.
|
|
@@ -54,17 +54,17 @@ module Rley # This module is used as a namespace
|
|
|
54
54
|
# instance = Engine.new
|
|
55
55
|
# instance.build_grammar do
|
|
56
56
|
# add_terminals('LBRACKET', 'RBRACKET', 'COMMA', 'INTEGER')
|
|
57
|
-
# add_production('start' => 'array')
|
|
57
|
+
# add_production('start' => 'array')
|
|
58
58
|
# add_production('array' => 'LBRACKET elements RBRACKET')
|
|
59
59
|
# add_production('array' => 'LBRACKET RBRACKET')
|
|
60
60
|
# add_production('elements' => 'elements COMMA INTEGER')
|
|
61
|
-
# add_production('elements' => 'INTEGER')
|
|
61
|
+
# add_production('elements' => 'INTEGER')
|
|
62
62
|
# end
|
|
63
63
|
def build_grammar(&aBlock)
|
|
64
64
|
builder = Rley::Syntax::GrammarBuilder.new(&aBlock)
|
|
65
65
|
@grammar = builder.grammar
|
|
66
66
|
end
|
|
67
|
-
|
|
67
|
+
|
|
68
68
|
# Use the given grammar.
|
|
69
69
|
# @param aGrammar [Rley::Syntax::Grammar]
|
|
70
70
|
# @return [Rley::Syntax::Grammar] the grammar of the language to parse.
|
|
@@ -79,6 +79,7 @@ module Rley # This module is used as a namespace
|
|
|
79
79
|
tokens = []
|
|
80
80
|
aTokenizer.each do |a_token|
|
|
81
81
|
next unless a_token
|
|
82
|
+
|
|
82
83
|
term_name = a_token.terminal
|
|
83
84
|
term_symb = grammar.name2symbol[term_name]
|
|
84
85
|
a_token.instance_variable_set(:@terminal, term_symb)
|
|
@@ -88,7 +89,7 @@ module Rley # This module is used as a namespace
|
|
|
88
89
|
parser.gf_graph.diagnose if configuration.diagnose
|
|
89
90
|
result = parser.parse(tokens)
|
|
90
91
|
result.tidy_up!
|
|
91
|
-
|
|
92
|
+
|
|
92
93
|
return result
|
|
93
94
|
end
|
|
94
95
|
|
|
@@ -153,6 +153,7 @@ module Rley # This module is used as a namespace
|
|
|
153
153
|
if stack.last.done?
|
|
154
154
|
popped = stack.pop
|
|
155
155
|
break if stack.empty?
|
|
156
|
+
|
|
156
157
|
# puts "Popped!"
|
|
157
158
|
return_key = popped.in_edge.key.sub(/^CALL/, 'RET')
|
|
158
159
|
curr_edge = visitee.edges.find { |e| e.key == return_key }
|
|
@@ -197,6 +198,7 @@ module Rley # This module is used as a namespace
|
|
|
197
198
|
curr_prod = nil
|
|
198
199
|
theDottedItems.each_with_index do |d_item, index_item|
|
|
199
200
|
next unless curr_prod.nil? || curr_prod != d_item.production
|
|
201
|
+
|
|
200
202
|
# Another production found...
|
|
201
203
|
curr_prod = d_item.production
|
|
202
204
|
if curr_prod.empty?
|
data/lib/rley/gfg/item_vertex.rb
CHANGED
|
@@ -30,7 +30,9 @@ module Rley # This module is used as a namespace
|
|
|
30
30
|
def shortcut=(aShortcut)
|
|
31
31
|
unless aShortcut.kind_of?(ShortcutEdge)
|
|
32
32
|
raise StandardError, 'Invalid shortcut argument'
|
|
33
|
+
|
|
33
34
|
end
|
|
35
|
+
|
|
34
36
|
=begin
|
|
35
37
|
unless next_symbol && next_symbol.kind_of?(Syntax::NonTerminal)
|
|
36
38
|
raise StandardError, 'Invalid shortcut usage'
|
data/lib/rley/gfg/vertex.rb
CHANGED
|
@@ -46,7 +46,7 @@ module Rley # This module is used as a namespace
|
|
|
46
46
|
# @return [String]
|
|
47
47
|
def selfie()
|
|
48
48
|
result = "#{self.class.name}:#{object_id}"
|
|
49
|
-
result << %
|
|
49
|
+
result << %( label="#{label}")
|
|
50
50
|
return result
|
|
51
51
|
end
|
|
52
52
|
|
|
@@ -69,6 +69,7 @@ module Rley # This module is used as a namespace
|
|
|
69
69
|
# unless this method is overridden in subclasses
|
|
70
70
|
def check_add_edge(anEdge)
|
|
71
71
|
raise StandardError, 'At most one edge accepted' unless edges.empty?
|
|
72
|
+
|
|
72
73
|
return anEdge
|
|
73
74
|
end
|
|
74
75
|
|
data/lib/rley/lexical/token.rb
CHANGED
|
@@ -6,8 +6,8 @@ module Rley # This module is used as a namespace
|
|
|
6
6
|
"line #{line}, column #{column}"
|
|
7
7
|
end
|
|
8
8
|
end
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
|
|
10
|
+
|
|
11
11
|
# In Rley, a (lexical) token is an object created by a lexer (tokenizer)
|
|
12
12
|
# and passed to the parser. Such token an object is created when a lexer
|
|
13
13
|
# detects that a sequence of characters(a lexeme) from the input stream
|
|
@@ -25,8 +25,8 @@ module Rley # This module is used as a namespace
|
|
|
25
25
|
|
|
26
26
|
# @return [Syntax::Terminal] Terminal symbol corresponding to the lexeme.
|
|
27
27
|
attr_reader(:terminal)
|
|
28
|
-
|
|
29
|
-
# @return [Position] The position of the lexeme in the source file.
|
|
28
|
+
|
|
29
|
+
# @return [Position] The position of the lexeme in the source file.
|
|
30
30
|
attr_reader(:position)
|
|
31
31
|
|
|
32
32
|
# Constructor.
|
|
@@ -35,6 +35,7 @@ module Rley # This module is used as a namespace
|
|
|
35
35
|
# The terminal symbol corresponding to the lexeme.
|
|
36
36
|
def initialize(theLexeme, aTerminal, aPosition)
|
|
37
37
|
raise 'Internal error: nil terminal symbol detected' if aTerminal.nil?
|
|
38
|
+
|
|
38
39
|
@lexeme = theLexeme
|
|
39
40
|
@terminal = aTerminal
|
|
40
41
|
@position = aPosition
|
|
@@ -50,7 +50,7 @@ module Rley # This module is used as a namespace
|
|
|
50
50
|
@subscribers = []
|
|
51
51
|
@prime_enum = Prime.instance.each
|
|
52
52
|
@legs = []
|
|
53
|
-
@node_accesses = Hash.new { |h, key| h[key] =
|
|
53
|
+
@node_accesses = Hash.new { |h, key| h[key] = [] }
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
# Add a subscriber for the visit event notifications.
|
|
@@ -81,9 +81,9 @@ module Rley # This module is used as a namespace
|
|
|
81
81
|
# @param nonTerminalNd [NonTerminalNode] the node to visit.
|
|
82
82
|
def visit_nonterminal(nonTerminalNd)
|
|
83
83
|
broadcast(:before_non_terminal, nonTerminalNd)
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
unless nonTerminalNd.signature_exist?
|
|
85
|
+
nonTerminalNd.add_edge_signatures(prime_enum)
|
|
86
|
+
end
|
|
87
87
|
traverse_children(nonTerminalNd)
|
|
88
88
|
broadcast(:after_non_terminal, nonTerminalNd)
|
|
89
89
|
end
|
|
@@ -122,7 +122,7 @@ module Rley # This module is used as a namespace
|
|
|
122
122
|
# non-terminal node.
|
|
123
123
|
# @param aNonTerminalNode [NonTerminalNode] the node to visit.
|
|
124
124
|
# def end_visit_nonterminal(aNonTerminalNode)
|
|
125
|
-
|
|
125
|
+
# broadcast(:after_non_terminal, aNonTerminalNode)
|
|
126
126
|
# end
|
|
127
127
|
|
|
128
128
|
# Visit event. The visitor has completed the visit of the pforest.
|
|
@@ -167,6 +167,7 @@ module Rley # This module is used as a namespace
|
|
|
167
167
|
def broadcast(msg, *args)
|
|
168
168
|
subscribers.each do |subscr|
|
|
169
169
|
next unless subscr.respond_to?(msg) || subscr.respond_to?(:accept_all)
|
|
170
|
+
|
|
170
171
|
subscr.send(msg, *args)
|
|
171
172
|
end
|
|
172
173
|
end
|
|
@@ -187,6 +188,7 @@ module Rley # This module is used as a namespace
|
|
|
187
188
|
|
|
188
189
|
def pop_node
|
|
189
190
|
return if legs.empty?
|
|
191
|
+
|
|
190
192
|
legs.pop
|
|
191
193
|
end
|
|
192
194
|
end # class
|
|
@@ -17,7 +17,7 @@ module Rley # This module is used as a namespace
|
|
|
17
17
|
# @return [Hash{String => Class}, Hash{String => Hash{String => Class}}]
|
|
18
18
|
# Returned hash contains pairs of the form:
|
|
19
19
|
# terminal name => Class implementing the terminal tokens
|
|
20
|
-
# terminal name => Hash with pairs:
|
|
20
|
+
# terminal name => Hash with pairs: production name => Class
|
|
21
21
|
def terminal2node()
|
|
22
22
|
raise NotImplementedError
|
|
23
23
|
end
|
|
@@ -28,8 +28,8 @@ module Rley # This module is used as a namespace
|
|
|
28
28
|
# puts "EVENT #{event[0]} #{event[1]}"
|
|
29
29
|
a_builder.receive_event(*event)
|
|
30
30
|
end
|
|
31
|
-
rescue StopIteration
|
|
32
|
-
# Do nothing
|
|
31
|
+
rescue StopIteration
|
|
32
|
+
# Do nothing: gobble the exception
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
a_builder.done!
|
|
@@ -15,6 +15,7 @@ module Rley # This module is used as a namespace
|
|
|
15
15
|
# @param aParseTree [ParseTree] the parse tree to visit.
|
|
16
16
|
def initialize(aParseTree, aTraversalStrategy = :post_order)
|
|
17
17
|
raise StandardError if aParseTree.nil?
|
|
18
|
+
|
|
18
19
|
@ptree = aParseTree
|
|
19
20
|
@subscribers = []
|
|
20
21
|
@traversal = aTraversalStrategy
|
|
@@ -99,6 +100,7 @@ module Rley # This module is used as a namespace
|
|
|
99
100
|
def broadcast(msg, *args)
|
|
100
101
|
subscribers.each do |subscr|
|
|
101
102
|
next unless subscr.respond_to?(msg) || subscr.respond_to?(:accept_all)
|
|
103
|
+
|
|
102
104
|
subscr.send(msg, *args)
|
|
103
105
|
end
|
|
104
106
|
end
|
|
@@ -5,7 +5,7 @@ module Rley # Module used as a namespace
|
|
|
5
5
|
# detected by Rley.
|
|
6
6
|
class ErrorReason
|
|
7
7
|
# @!attribute [r] rank
|
|
8
|
-
# @return [Fixnum] The rank number of the offending input token
|
|
8
|
+
# @return [Fixnum] The rank number of the offending input token
|
|
9
9
|
attr_reader(:rank)
|
|
10
10
|
|
|
11
11
|
# Constructor
|
|
@@ -45,27 +45,29 @@ module Rley # Module used as a namespace
|
|
|
45
45
|
class ExpectationNotMet < ErrorReason
|
|
46
46
|
# The last input token read when error was detected
|
|
47
47
|
attr_reader(:last_token)
|
|
48
|
-
|
|
48
|
+
|
|
49
49
|
# The terminal symbols expected when error was occurred
|
|
50
50
|
attr_reader(:expected_terminals)
|
|
51
51
|
|
|
52
52
|
def initialize(aRank, lastToken, expectedTerminals)
|
|
53
53
|
super(aRank)
|
|
54
54
|
raise StandardError, 'Internal error: nil token' if lastToken.nil?
|
|
55
|
+
|
|
55
56
|
@last_token = lastToken.dup
|
|
56
57
|
@expected_terminals = expectedTerminals.dup
|
|
57
58
|
end
|
|
58
59
|
|
|
59
60
|
protected
|
|
60
|
-
|
|
61
|
+
|
|
61
62
|
def position()
|
|
62
63
|
return last_token.position if last_token.respond_to?(:position)
|
|
64
|
+
|
|
63
65
|
rank + 1
|
|
64
66
|
end
|
|
65
|
-
|
|
67
|
+
|
|
66
68
|
# Emit a text explaining the expected terminal symbols
|
|
67
69
|
def expectations
|
|
68
|
-
term_names = expected_terminals.map(&:name)
|
|
70
|
+
term_names = expected_terminals.map(&:name)
|
|
69
71
|
explain = 'Expected one '
|
|
70
72
|
explain << if expected_terminals.size > 1
|
|
71
73
|
"of: ['#{term_names.join("', '")}']"
|
|
@@ -92,7 +94,7 @@ module Rley # Module used as a namespace
|
|
|
92
94
|
|
|
93
95
|
# This parse error occurs when all input tokens were consumed
|
|
94
96
|
# but the parser still expected one or more tokens from the input.
|
|
95
|
-
class PrematureInputEnd < ExpectationNotMet
|
|
97
|
+
class PrematureInputEnd < ExpectationNotMet
|
|
96
98
|
# Returns the reason's message.
|
|
97
99
|
def to_s
|
|
98
100
|
err_msg = "Premature end of input after '#{last_token.lexeme}'"
|
|
@@ -13,7 +13,7 @@ module Rley # This module is used as a namespace
|
|
|
13
13
|
attr_reader(:sets)
|
|
14
14
|
|
|
15
15
|
# @param aGFGraph [GFG::GrmFlowGraph] The GFG for the grammar in use.
|
|
16
|
-
def initialize(
|
|
16
|
+
def initialize(aGFGraph)
|
|
17
17
|
@sets = [ ParseEntrySet.new ]
|
|
18
18
|
push_entry(aGFGraph.start_vertex, 0, 0, :start_rule)
|
|
19
19
|
end
|
|
@@ -45,7 +45,7 @@ module Rley # This module is used as a namespace
|
|
|
45
45
|
# Push a parse entry for the chart entry with given index
|
|
46
46
|
# @param anIndex [Integer] The rank of the token in the input stream.
|
|
47
47
|
# @return [ParseEntry] the passed parse entry if it is pushed
|
|
48
|
-
def push_entry(aVertex, anOrigin, anIndex,
|
|
48
|
+
def push_entry(aVertex, anOrigin, anIndex, reason)
|
|
49
49
|
# puts "push_entry:"
|
|
50
50
|
# puts " aVertex #{aVertex.inspect}"
|
|
51
51
|
# puts " anOrigin: #{anOrigin}"
|
|
@@ -53,8 +53,9 @@ module Rley # This module is used as a namespace
|
|
|
53
53
|
# puts " _reason: #{_reason}"
|
|
54
54
|
new_entry = ParseEntry.new(aVertex, anOrigin)
|
|
55
55
|
if anIndex == sets.size
|
|
56
|
-
err_msg = "Internal error: unexpected push reason #{
|
|
57
|
-
raise StandardError, err_msg if
|
|
56
|
+
err_msg = "Internal error: unexpected push reason #{reason}"
|
|
57
|
+
raise StandardError, err_msg if reason != :scan_rule
|
|
58
|
+
|
|
58
59
|
add_entry_set
|
|
59
60
|
end
|
|
60
61
|
pushed = self[anIndex].push_entry(new_entry)
|
|
@@ -98,7 +99,6 @@ module Rley # This module is used as a namespace
|
|
|
98
99
|
def add_entry_set()
|
|
99
100
|
@sets << ParseEntrySet.new
|
|
100
101
|
end
|
|
101
|
-
|
|
102
102
|
end # class
|
|
103
103
|
end # module
|
|
104
104
|
end # module
|
|
@@ -176,6 +176,7 @@ module Rley # This module is used as a namespace
|
|
|
176
176
|
# followed the syntax specified by the grammar)
|
|
177
177
|
def success?()
|
|
178
178
|
return false if @failure_reason
|
|
179
|
+
|
|
179
180
|
return chart.accepting_entry ? true : false
|
|
180
181
|
end
|
|
181
182
|
|
|
@@ -272,6 +273,7 @@ END_MSG
|
|
|
272
273
|
# Rule: has 1..* antecedents, all of them are exit items
|
|
273
274
|
antecedents.each do |antec|
|
|
274
275
|
next if antec.exit_entry?
|
|
276
|
+
|
|
275
277
|
msg_prefix = "End vertex parse entry #{consequent}"
|
|
276
278
|
msg_suffix = " has for antecedent #{antec}"
|
|
277
279
|
raise StandardError, msg_prefix + msg_suffix
|
|
@@ -280,16 +282,18 @@ END_MSG
|
|
|
280
282
|
when Rley::GFG::ItemVertex
|
|
281
283
|
# Rule: has exactly one antecedent
|
|
282
284
|
# if antecedents.size > 1
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
285
|
+
# msg_prefix = "Parse entry #{consequent} | #{aPosition}"
|
|
286
|
+
# msg = " has more than one antecedent:\n"
|
|
287
|
+
# msg_suffix = antecedents.map(&:to_s).join("\n")
|
|
288
|
+
# raise(StandardError, msg_prefix + msg + msg_suffix)
|
|
287
289
|
# end
|
|
288
290
|
|
|
289
291
|
when Rley::GFG::StartVertex
|
|
290
|
-
# Rule: has 0..* antecedents, all of them are
|
|
292
|
+
# Rule: has 0..* antecedents, all of them are
|
|
293
|
+
# item vertices but not exit items
|
|
291
294
|
antecedents.each do |antec|
|
|
292
295
|
next if antec.dotted_entry? && !antec.end_entry?
|
|
296
|
+
|
|
293
297
|
msg_prefix = "Parse entry #{consequent}"
|
|
294
298
|
msg_suffix = " has for antecedent #{antec}"
|
|
295
299
|
raise StandardError, msg_prefix + msg_suffix
|
|
@@ -304,6 +308,7 @@ END_MSG
|
|
|
304
308
|
# chart entry with given index if it isn't yet in the chart entry.
|
|
305
309
|
def push_entry(aVertex, anOrigin, aChartIndex, aReason)
|
|
306
310
|
raise StandardError, 'Vertex may not be nil' if aVertex.nil?
|
|
311
|
+
|
|
307
312
|
chart.push_entry(aVertex, anOrigin, aChartIndex, aReason)
|
|
308
313
|
end
|
|
309
314
|
|
|
@@ -26,6 +26,7 @@ module Rley # This module is used as a namespace
|
|
|
26
26
|
# Write accessor. Set the given parse entry as the current one.
|
|
27
27
|
def parse_entry=(aParseEntry)
|
|
28
28
|
raise StandardError, 'Nil parse entry' if aParseEntry.nil?
|
|
29
|
+
|
|
29
30
|
@parse_entry = aParseEntry
|
|
30
31
|
processed_entries[parse_entry] = true
|
|
31
32
|
end
|
|
@@ -16,7 +16,7 @@ module Rley # This module is used as a namespace
|
|
|
16
16
|
def ==(other)
|
|
17
17
|
return true if object_id == other.object_id
|
|
18
18
|
|
|
19
|
-
result = (dotted_rule == other.dotted_rule) &&
|
|
19
|
+
result = (dotted_rule == other.dotted_rule) &&
|
|
20
20
|
(origin == other.origin)
|
|
21
21
|
|
|
22
22
|
return result
|
|
@@ -43,6 +43,7 @@ module Rley # This module is used as a namespace
|
|
|
43
43
|
return false if other == self
|
|
44
44
|
|
|
45
45
|
return false unless origin == other.origin
|
|
46
|
+
|
|
46
47
|
other_production = other.dotted_rule.production
|
|
47
48
|
return false unless dotted_rule.production == other_production
|
|
48
49
|
|
|
@@ -26,6 +26,7 @@ module Rley # This module is used as a namespace
|
|
|
26
26
|
# Write accessor. Set the given parse state as the current one.
|
|
27
27
|
def parse_state=(aParseState)
|
|
28
28
|
raise StandardError, 'Nil parse state' if aParseState.nil?
|
|
29
|
+
|
|
29
30
|
@parse_state = aParseState
|
|
30
31
|
processed_states[parse_state] = true
|
|
31
32
|
end
|
|
@@ -54,6 +54,7 @@ module Rley # This module is used as a namespace
|
|
|
54
54
|
def build_walker(acceptingEntry, maxIndex, lazyWalk = false)
|
|
55
55
|
msg = 'Internal error: nil entry argument'
|
|
56
56
|
raise StandardError, msg if acceptingEntry.nil?
|
|
57
|
+
|
|
57
58
|
# Local context for the enumerator
|
|
58
59
|
ctx = init_context(acceptingEntry, maxIndex, lazyWalk)
|
|
59
60
|
|
|
@@ -65,9 +66,12 @@ module Rley # This module is used as a namespace
|
|
|
65
66
|
receiver << event unless event.nil?
|
|
66
67
|
|
|
67
68
|
if ctx.curr_entry.orphan? # No antecedent?...
|
|
68
|
-
|
|
69
|
+
msg_prefix = "No antecedent for #{ctx.curr_entry}"
|
|
70
|
+
msg_suffix = "at rank #{ctx.entry_set_index}"
|
|
71
|
+
err_msg = msg_prefix + ' ' + msg_suffix
|
|
69
72
|
raise StandardError, err_msg unless ctx.curr_entry.start_entry?
|
|
70
73
|
break if ctx.backtrack_points.empty?
|
|
74
|
+
|
|
71
75
|
receiver << use_backtrack_point(ctx)
|
|
72
76
|
receiver << visit_entry(ctx.curr_entry, ctx)
|
|
73
77
|
end
|
|
@@ -187,6 +191,7 @@ module Rley # This module is used as a namespace
|
|
|
187
191
|
# Pop top of stack
|
|
188
192
|
err_msg = 'Return stack empty!'
|
|
189
193
|
raise ScriptError, err_msg if aContext.return_stack.empty?
|
|
194
|
+
|
|
190
195
|
aContext.return_stack.pop
|
|
191
196
|
# puts "Pop from return stack matching entry #{new_entry}"
|
|
192
197
|
elsif traversed_edge.kind_of?(GFG::ScanEdge)
|
|
@@ -264,6 +269,7 @@ module Rley # This module is used as a namespace
|
|
|
264
269
|
# to a item vertex
|
|
265
270
|
def select_calling_entry(aContext)
|
|
266
271
|
raise ScriptError, 'Empty return stack' if aContext.return_stack.empty?
|
|
272
|
+
|
|
267
273
|
# Retrieve top of stack
|
|
268
274
|
tos = aContext.return_stack.pop
|
|
269
275
|
tos_dotted_item = tos.vertex.dotted_item
|