class Rley::ParseTreeVisitor
A visitor class dedicated in the visit of a parse tree. It combines the Visitor and Observer patterns.
Attributes
Link to the parse tree to visit
List of objects that subscribed to the visit event notification.
Indicates the kind of tree traversal to perform: :post_order, :pre-order
Public Class Methods
Source
# File lib/rley/parse_tree_visitor.rb, line 18 def initialize(aParseTree, aTraversalStrategy = :post_order) raise StandardError if aParseTree.nil? @ptree = aParseTree @subscribers = [] @traversal = aTraversalStrategy end
Build a visitor for the given ptree. @param aParseTree [ParseTree] the parse tree to visit.
Public Instance Methods
Source
# File lib/rley/parse_tree_visitor.rb, line 74 def end_visit_nonterminal(aNonTerminalNode) broadcast(:after_non_terminal, aNonTerminalNode) end
Visit event. The visitor has completed its visit of the given non-terminal node. @param aNonTerminalNode [NonTerminalNode] the node to visit.
Source
# File lib/rley/parse_tree_visitor.rb, line 80 def end_visit_ptree(aParseTree) broadcast(:after_ptree, aParseTree) end
Visit event. The visitor has completed the visit of the ptree. @param aParseTree [ParseTree] the ptree to visit.
Source
# File lib/rley/parse_tree_visitor.rb, line 40 def start ptree.accept(self) end
The signal to begin the visit of the parse tree.
Source
# File lib/rley/parse_tree_visitor.rb, line 46 def start_visit_ptree(aParseTree) broadcast(:before_ptree, aParseTree) end
Visit event. The visitor is about to visit the ptree. @param aParseTree [ParseTree] the ptree to visit.
Source
# File lib/rley/parse_tree_visitor.rb, line 28 def subscribe(aSubscriber) subscribers << aSubscriber end
Add a subscriber for the visit event notifications. @param aSubscriber [Object]
Source
# File lib/rley/parse_tree_visitor.rb, line 35 def unsubscribe(aSubscriber) subscribers.delete_if { |entry| entry == aSubscriber } end
Remove the given object from the subscription list. The object won’t be notified of visit events. @param aSubscriber [Object]
Source
# File lib/rley/parse_tree_visitor.rb, line 52 def visit_nonterminal(aNonTerminalNode) if @traversal == :post_order broadcast(:before_non_terminal, aNonTerminalNode) traverse_subnodes(aNonTerminalNode) else traverse_subnodes(aNonTerminalNode) broadcast(:before_non_terminal, aNonTerminalNode) end broadcast(:after_non_terminal, aNonTerminalNode) end
Visit event. The visitor is about to visit the given non terminal node. @param aNonTerminalNode [NonTerminalNode] the node to visit.
Source
# File lib/rley/parse_tree_visitor.rb, line 66 def visit_terminal(aTerminalNode) broadcast(:before_terminal, aTerminalNode) broadcast(:after_terminal, aTerminalNode) end
Visit event. The visitor is visiting the given terminal node. @param aTerminalNode [TerminalNode] the terminal to visit.
Private Instance Methods
Source
# File lib/rley/parse_tree_visitor.rb, line 102 def broadcast(msg, *args) subscribers.each do |subscr| next unless subscr.respond_to?(msg) || subscr.respond_to?(:accept_all) subscr.send(msg, *args) end end
Send a notification to all subscribers. @param msg [Symbol] event to notify @param args [Array] arguments of the notification.
Source
# File lib/rley/parse_tree_visitor.rb, line 89 def traverse_subnodes(aParentNode) subnodes = aParentNode.subnodes broadcast(:before_subnodes, aParentNode, subnodes) # Let's proceed with the visit of subnodes subnodes.each { |a_node| a_node.accept(self) } broadcast(:after_subnodes, aParentNode, subnodes) end
Visit event. The visitor is about to visit the subnodes of a non terminal node. @param aParentNode [NonTeminalNode] the (non-terminal) parent node.