Class: Dendroid::Parsing::WalkContext

Inherits:
Object
  • Object
show all
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

Instance Method Summary collapse

Constructor Details

#initializeWalkContext

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

#entry2nodeHash{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_crossedHash{OrNode => true} (readonly)

Returns:



18
19
20
# File 'lib/dendroid/parsing/chart_walker.rb', line 18

def or_nodes_crossed
  @or_nodes_crossed
end

#sharingHash{Parsing::ParseNode => Array<Dendroid::Parsing::WalkProgress>} (readonly)



21
22
23
# File 'lib/dendroid/parsing/chart_walker.rb', line 21

def sharing
  @sharing
end

#token2nodeHash{Syntax::Token => TerminalNode} (readonly)

Returns:



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

Parameters:



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.

Parameters:



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

Parameters:

Returns:

  • (Boolean)

    true if the walk progress is in Complete state



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?

Parameters:

Returns:

  • (Boolean)


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.

Parameters:



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

Parameters:



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

Parameters:



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