rley 0.7.00 → 0.7.01

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +51 -34
  3. data/.travis.yml +10 -9
  4. data/CHANGELOG.md +9 -0
  5. data/LICENSE.txt +1 -1
  6. data/README.md +0 -1
  7. data/appveyor.yml +10 -8
  8. data/examples/NLP/benchmark_pico_en.rb +3 -2
  9. data/examples/NLP/engtagger.rb +23 -12
  10. data/examples/NLP/nano_eng/nano_en_demo.rb +4 -3
  11. data/examples/NLP/pico_en_demo.rb +3 -2
  12. data/examples/data_formats/JSON/json_ast_nodes.rb +3 -0
  13. data/examples/data_formats/JSON/json_demo.rb +1 -0
  14. data/examples/data_formats/JSON/json_lexer.rb +2 -1
  15. data/lib/rley/base/dotted_item.rb +2 -0
  16. data/lib/rley/constants.rb +1 -1
  17. data/lib/rley/engine.rb +8 -7
  18. data/lib/rley/gfg/grm_flow_graph.rb +2 -0
  19. data/lib/rley/gfg/item_vertex.rb +2 -0
  20. data/lib/rley/gfg/vertex.rb +2 -1
  21. data/lib/rley/lexical/token.rb +5 -4
  22. data/lib/rley/parse_forest_visitor.rb +7 -5
  23. data/lib/rley/parse_rep/ast_base_builder.rb +1 -1
  24. data/lib/rley/parse_rep/parse_rep_creator.rb +2 -2
  25. data/lib/rley/parse_rep/parse_tree_builder.rb +1 -0
  26. data/lib/rley/parse_tree_visitor.rb +2 -0
  27. data/lib/rley/parser/error_reason.rb +8 -6
  28. data/lib/rley/parser/gfg_chart.rb +5 -5
  29. data/lib/rley/parser/gfg_parsing.rb +10 -5
  30. data/lib/rley/parser/parse_entry_tracker.rb +1 -0
  31. data/lib/rley/parser/parse_state.rb +2 -1
  32. data/lib/rley/parser/parse_state_tracker.rb +1 -0
  33. data/lib/rley/parser/parse_walker_factory.rb +7 -1
  34. data/lib/rley/ptree/parse_tree_node.rb +1 -0
  35. data/lib/rley/sppf/parse_forest.rb +9 -7
  36. data/lib/rley/syntax/grammar.rb +10 -6
  37. data/lib/rley/syntax/grammar_builder.rb +2 -2
  38. data/lib/rley/syntax/grm_symbol.rb +1 -0
  39. data/lib/support/base_tokenizer.rb +10 -96
  40. data/spec/rley/engine_spec.rb +3 -3
  41. data/spec/rley/gfg/grm_flow_graph_spec.rb +1 -0
  42. data/spec/rley/parse_forest_visitor_spec.rb +63 -38
  43. data/spec/rley/parse_rep/groucho_spec.rb +9 -8
  44. data/spec/rley/parse_tree_visitor_spec.rb +1 -1
  45. data/spec/rley/parser/gfg_earley_parser_spec.rb +7 -7
  46. data/spec/rley/parser/gfg_parsing_spec.rb +1 -3
  47. data/spec/rley/parser/parse_entry_spec.rb +1 -1
  48. data/spec/rley/support/expectation_helper.rb +2 -1
  49. data/spec/rley/support/grammar_ambig01_helper.rb +4 -3
  50. data/spec/rley/support/grammar_arr_int_helper.rb +5 -4
  51. data/spec/rley/support/grammar_b_expr_helper.rb +5 -4
  52. data/spec/rley/support/grammar_helper.rb +2 -2
  53. data/spec/rley/support/grammar_l0_helper.rb +3 -2
  54. data/spec/rley/support/grammar_pb_helper.rb +5 -28
  55. data/spec/support/base_tokenizer_spec.rb +7 -9
  56. 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
 
@@ -3,7 +3,7 @@
3
3
 
4
4
  module Rley # Module used as a namespace
5
5
  # The version number of the gem.
6
- Version = '0.7.00'.freeze
6
+ Version = '0.7.01'.freeze
7
7
 
8
8
  # Brief description of the gem.
9
9
  Description = "Ruby implementation of the Earley's parsing algorithm".freeze
@@ -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?
@@ -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'
@@ -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 << %Q( label="#{label}")
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
 
@@ -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] = Array.new }
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
- unless nonTerminalNd.signature_exist?
85
- nonTerminalNd.add_edge_signatures(prime_enum)
86
- end
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
- # broadcast(:after_non_terminal, aNonTerminalNode)
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: rule name => Class
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 => exc
32
- # Do nothing
31
+ rescue StopIteration
32
+ # Do nothing: gobble the exception
33
33
  end
34
34
 
35
35
  a_builder.done!
@@ -85,6 +85,7 @@ module Rley # This module is used as a namespace
85
85
  # node as root node.
86
86
  def create_tree(aRootNode)
87
87
  raise StandardError, 'Root node of parse tree is nil!' if aRootNode.nil?
88
+
88
89
  return Rley::PTree::ParseTree.new(aRootNode)
89
90
  end
90
91
 
@@ -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( aGFGraph)
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, _reason)
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 #{_reason}"
57
- raise StandardError, err_msg if _reason != :scan_rule
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
- # msg_prefix = "Parse entry #{consequent} | #{aPosition}"
284
- # msg = " has more than one antecedent:\n"
285
- # msg_suffix = antecedents.map(&:to_s).join("\n")
286
- # raise(StandardError, msg_prefix + msg + msg_suffix)
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 item vertices but not exit items
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
- err_msg = "No antecedent for #{ctx.curr_entry} at rank #{ctx.entry_set_index}"
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