def traverse(include_self = false, &block)
      raise 'traverse requires a block' unless block_given?

      block.call(:enter, self, 0) if include_self

      each_with_index do |exp, index|
        if exp.terminal?
          block.call(:visit, exp, index)
        else
          block.call(:enter, exp, index)
          exp.traverse(&block)
          block.call(:exit, exp, index)
        end
      end

      block.call(:exit, self, 0) if include_self

      self
    end
def traverse(include_self = false, &block)
      raise 'traverse requires a block' unless block_given?

      block.call(:enter, self, 0) if include_self

      each_with_index do |exp, index|
        if exp.terminal?
          block.call(:visit, exp, index)
        else
          block.call(:enter, exp, index)
          exp.traverse(&block)
          block.call(:exit, exp, index)
        end
      end

      block.call(:exit, self, 0) if include_self

      self
    end
Traverses the subexpression (depth-first, pre-order) and calls the given
 block for each expression with three arguments; the traversal event,
 the expression, and the index of the expression within its parent.

 The event argument is passed as follows:

 - For subexpressions, :enter upon entering the subexpression, and
   :exit upon exiting it.

 - For terminal expressions, :visit is called once.

 Returns self.