Home | History | Annotate | Download | only in tree
      1 #!/usr/bin/ruby
      2 # encoding: utf-8
      3 
      4 =begin LICENSE
      5 
      6 [The "BSD licence"]
      7 Copyright (c) 2009-2010 Kyle Yetter
      8 All rights reserved.
      9 
     10 Redistribution and use in source and binary forms, with or without
     11 modification, are permitted provided that the following conditions
     12 are met:
     13 
     14  1. Redistributions of source code must retain the above copyright
     15     notice, this list of conditions and the following disclaimer.
     16  2. Redistributions in binary form must reproduce the above copyright
     17     notice, this list of conditions and the following disclaimer in the
     18     documentation and/or other materials provided with the distribution.
     19  3. The name of the author may not be used to endorse or promote products
     20     derived from this software without specific prior written permission.
     21 
     22 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     23 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     24 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     25 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     26 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     27 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     31 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32 
     33 =end
     34 
     35 module ANTLR3
     36 module AST
     37 
     38 =begin rdoc ANTLR3::AST::Visitor
     39 
     40 AST::Visitor is an extra utility class for working with tree objects. Visitor
     41 objects are similar to plain vanilla iterators, but provide two action hooks,
     42 instead a standard single iteration block. The <tt>visit(tree)</tt> method walks
     43 through each node of the tree (top-down left-to-right). If +pre_action+ is
     44 defined, a node is yielded to the block when it has been initially entered. If
     45 +post_action+ is defined, a node is yielded to the block after all of its
     46 children have been visited.
     47 
     48 =end
     49 
     50 class Visitor
     51   def initialize( adaptor = nil )
     52     @adaptor = adaptor || CommonTreeAdaptor.new()
     53     @pre_action = nil
     54     @post_action = nil
     55     block_given? and yield( self )
     56   end
     57   
     58   def pre_action( &block )
     59     block_given? and @pre_action = block
     60     return @pre_action
     61   end
     62   
     63   def post_action( &block )
     64     block_given? and @post_action = block
     65     return @post_action
     66   end
     67   
     68   def visit( tree, pre_action = nil, post_action = nil )
     69     flat = @adaptor.flat_list?( tree )
     70     before = pre_action || @pre_action
     71     after = post_action || @post_action
     72     
     73     tree = before.call( tree ) unless before.nil? or flat
     74     @adaptor.child_count( tree ).times do |index|
     75       child = @adaptor.child_of( tree, index )
     76       visit( child, pre_action, post_action )
     77     end
     78     tree = after.call( tree ) unless after.nil? or flat
     79     
     80     return tree
     81   end
     82 end
     83 end
     84 end
     85