Class: Dendroid::Parsing::WalkContext
- Inherits:
-
Object
- Object
- Dendroid::Parsing::WalkContext
- Defined in:
- lib/dendroid/parsing/chart_walker.rb
Overview
Keeps track of the visited chart entries in order to implement the sharing of parse nodes.
Instance Attribute Summary collapse
-
#entry2node ⇒ Hash{Dendroid::Recognizer::EItem => ParseNode}
readonly
Mapping chart item => ParseNode for the current item set.
- #or_nodes_crossed ⇒ Hash{OrNode => true} readonly
- #sharing ⇒ Hash{Parsing::ParseNode => Array<Dendroid::Parsing::WalkProgress>} readonly
- #token2node ⇒ Hash{Syntax::Token => TerminalNode} readonly
Instance Method Summary collapse
-
#add_and_node(walk_progress, anEItem) ⇒ Object
Add an and node as a child of current parent of given walk progress.
-
#add_terminal_node(walk_progress, token) ⇒ Object
For a given token, make a terminal node a child of the current parent.
-
#advance(walk_progress, anEItem, aNode) ⇒ Object
Make the given chart entry the new current item and mark its related node as known (visited).
-
#initialize ⇒ WalkContext
constructor
A new instance of WalkContext.
-
#join_or_node(walk_progress, anOrNode) ⇒ Boolean
Check whether the given node was already seen.
-
#known_entry?(anEItem) ⇒ Boolean
Was the given chart entry already encountered?.
-
#pop_multiple_parents(walk_progress, count) ⇒ Object
Remove multiple parent from the parent stack of provided walk progress.
- #start_delegation(anEItem, walk_progress) ⇒ Object
-
#stop_delegation(aNode, walk_progress, desired_state) ⇒ Object
If the given node is shared by other WalkProgress, update them with the advancement of the provided WalkProgress & dissolve the delegation.
Constructor Details
#initialize ⇒ WalkContext
Returns a new instance of WalkContext.
23 24 25 26 27 28 |
# File 'lib/dendroid/parsing/chart_walker.rb', line 23 def initialize @entry2node = {} @token2node = {} @or_nodes_crossed = {} @sharing = {} end |
Instance Attribute Details
#entry2node ⇒ Hash{Dendroid::Recognizer::EItem => ParseNode} (readonly)
Mapping chart item => ParseNode for the current item set.
12 13 14 |
# File 'lib/dendroid/parsing/chart_walker.rb', line 12 def entry2node @entry2node end |
#or_nodes_crossed ⇒ Hash{OrNode => true} (readonly)
18 19 20 |
# File 'lib/dendroid/parsing/chart_walker.rb', line 18 def or_nodes_crossed @or_nodes_crossed end |
#sharing ⇒ Hash{Parsing::ParseNode => Array<Dendroid::Parsing::WalkProgress>} (readonly)
21 22 23 |
# File 'lib/dendroid/parsing/chart_walker.rb', line 21 def sharing @sharing end |
#token2node ⇒ Hash{Syntax::Token => TerminalNode} (readonly)
15 16 17 |
# File 'lib/dendroid/parsing/chart_walker.rb', line 15 def token2node @token2node end |
Instance Method Details
#add_and_node(walk_progress, anEItem) ⇒ Object
Add an and node as a child of current parent of given walk progress
62 63 64 65 |
# File 'lib/dendroid/parsing/chart_walker.rb', line 62 def add_and_node(walk_progress, anEItem) new_node = walk_progress.push_and_node(anEItem) advance(walk_progress, anEItem, new_node) end |
#add_terminal_node(walk_progress, token) ⇒ Object
For a given token, make a terminal node a child of the current parent.
49 50 51 52 53 54 55 56 57 |
# File 'lib/dendroid/parsing/chart_walker.rb', line 49 def add_terminal_node(walk_progress, token) if token2node.include? token walk_progress.add_child_node(token2node[token]) walk_progress.curr_rank -= 1 else new_node = walk_progress.add_terminal_node(token) token2node[token] = new_node end end |
#advance(walk_progress, anEItem, aNode) ⇒ Object
Make the given chart entry the new current item and mark its related node as known (visited)
41 42 43 44 |
# File 'lib/dendroid/parsing/chart_walker.rb', line 41 def advance(walk_progress, anEItem, aNode) walk_progress.curr_item = anEItem entry2node[anEItem] = aNode end |
#join_or_node(walk_progress, anOrNode) ⇒ Boolean
Check whether the given node was already seen. If yes, set the state of the walk progress to Complete
72 73 74 75 76 77 78 79 80 81 |
# File 'lib/dendroid/parsing/chart_walker.rb', line 72 def join_or_node(walk_progress, anOrNode) already_crossed = or_nodes_crossed.include?(anOrNode) if already_crossed walk_progress.state = :Complete else or_nodes_crossed[anOrNode] = true end already_crossed end |
#known_entry?(anEItem) ⇒ Boolean
Was the given chart entry already encountered?
32 33 34 |
# File 'lib/dendroid/parsing/chart_walker.rb', line 32 def known_entry?(anEItem) entry2node.include?(anEItem) end |
#pop_multiple_parents(walk_progress, count) ⇒ Object
Remove multiple parent from the parent stack of provided walk progress. If one of the removed node is an OrNode and it was already encountered, then the walk progress is deemed complete.
121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/dendroid/parsing/chart_walker.rb', line 121 def pop_multiple_parents(walk_progress, count) removed = walk_progress.parents.pop(count) if removed.is_a?(Array) or_nodes = removed.select { |entry| entry.is_a?(OrNode) } unless or_nodes.empty? or_nodes.reverse_each do |or_nd| break if join_or_node(walk_progress, or_nd) end end elsif removed.is_a?(OrNode) join_or_node(walk_progress, removed) end end |
#start_delegation(anEItem, walk_progress) ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/dendroid/parsing/chart_walker.rb', line 85 def start_delegation(anEItem, walk_progress) shared_node = entry2node[anEItem] if sharing.include? shared_node sharing[shared_node] << walk_progress else sharing[shared_node] = [walk_progress] end walk_progress.add_child_node(shared_node) walk_progress.parents.push(shared_node) walk_progress.state = :Delegating end |
#stop_delegation(aNode, walk_progress, desired_state) ⇒ Object
If the given node is shared by other WalkProgress, update them with the advancement of the provided WalkProgress & dissolve the delegation
102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/dendroid/parsing/chart_walker.rb', line 102 def stop_delegation(aNode, walk_progress, desired_state) if sharing.include? aNode delegating = sharing[aNode] unless delegating.include? walk_progress delegating.each do |dlg| dlg.curr_rank = walk_progress.curr_rank dlg.curr_item = walk_progress.curr_item dlg.state = desired_state end sharing.delete(aNode) end end end |