Class: Rley::Parser::ParseWalkerFactory
- Inherits:
-
Object
- Object
- Rley::Parser::ParseWalkerFactory
- Defined in:
- lib/rley/parser/parse_walker_factory.rb
Overview
A factory that creates an Enumerator object that itself walks through a GFGParsing object. The walker (= Enumerator) yields visit events. This class implements an external iterator for a given GFGParsing object. This is different from the internal iterators, usually implemented in Ruby with an :each method. Allows to perform a backwards traversal over the relevant parse entries. backwards traversal means that the traversal starts from the accepting (final) parse entries and goes to the initial parse entry. Relevant parse entries are parse entries that "count" in the parse (i.e. they belong to a path that leads to the accepting parse entry)
Instance Method Summary collapse
-
#build_walker(acceptingEntry, maxIndex, lazyWalk = false) ⇒ Enumerator
Build an Enumerator that will yield the parse entries as it walks backwards on the parse graph.
Instance Method Details
#build_walker(acceptingEntry, maxIndex, lazyWalk = false) ⇒ Enumerator
Build an Enumerator that will yield the parse entries as it walks backwards on the parse graph.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/rley/parser/parse_walker_factory.rb', line 56 def build_walker(acceptingEntry, maxIndex, lazyWalk = false) msg = 'Internal error: nil entry argument' raise StandardError, msg if acceptingEntry.nil? # Local context for the enumerator ctx = init_context(acceptingEntry, maxIndex, lazyWalk) walker = Enumerator.new do |receiver| # 'receiver' is a Yielder # At this point: current entry == accepting entry loop do event = visit_entry(ctx.curr_entry, ctx) receiver << event unless event.nil? if ctx.curr_entry.orphan? # No antecedent?... msg_prefix = "No antecedent for #{ctx.curr_entry}" msg_suffix = "at rank #{ctx.entry_set_index}" err_msg = msg_prefix + ' ' + msg_suffix raise StandardError, err_msg unless ctx.curr_entry.start_entry? break if ctx.backtrack_points.empty? receiver << use_backtrack_point(ctx) receiver << visit_entry(ctx.curr_entry, ctx) end result = jump_to_antecedent(ctx) # Emit detection of scan edge if any... receiver << result[0] if result.size > 1 ctx.curr_entry = result.last end end return walker end |