Revisiting the r++ Visitor

Steven T. Hatton hattons at globalsymmetry.com
Fri Sep 2 00:58:05 UTC 2005


I'm trying to create a visitor that can create a DOM on top of the AST.  I've 
actually done it in the simplest form. And in another, more complex, and far 
more verbose form.  If C-M-% means anything to you, you know how I did a lot 
of it.

What has me confused is this: I have to invoke, or completely reimplement the 
functions in DefaultVisitor.  If I don't call up (or is that down Bjarne?) 
the derivation stack, I get one node, the translation unit.  If I call up the 
stack with DefaultVisitor::visit(node) it falls off the face of the Earth.  
Calling per node type works, but it requires that each node know its own name 
at compile time.  IOW, I either use a macro, or I hard-code it into every 
function call.  I guess either one is really not that hard to do.  I'm 
wondering if there is another way to accomplish this.  I don't believe I can 
use the Visitor::_S_table[] to do this because if I call its element 
functions, it will be an unqualified call, which will call the caller, if I'm 
not mistaken.

I'm not sure if the approach used in OSG is applicable, or of any advantage 
here.  The general idea is that you attach a callback functor to the node, 
and call that when you visit the node.  This whole parsing of sourcecode is 
actually a lot like how a scenegraph works.  But I'm not an expert in either 
area.

This should give you a taste of what I'm currently doing:

  void XmlTree::visitAccessSpecifier(AccessSpecifierAST* node) {
    std::string indent(_dw * _w++,' ');
    Tag tag(_createTag(node));
    _out<<indent<<tag.startTagString()<<"\n";
    DefaultVisitor::visitAccessSpecifier(node);
    _out<<indent<<tag.endTagString()<<"\n";
    --_w;
  }

  void XmlTree::visitAsmDefinition(AsmDefinitionAST* node) {
    std::string indent(_dw * _w++,' ');
    Tag tag(_createTag(node));
    _out<<indent<<tag.startTagString()<<"\n";
    DefaultVisitor::visitAsmDefinition(node);
    _out<<indent<<tag.endTagString()<<"\n";
    --_w;
  }

  void XmlTree::visitBaseClause(BaseClauseAST* node) {
    std::string indent(_dw * _w++,' ');
    Tag tag(_createTag(node));
    _out<<indent<<tag.startTagString()<<"\n";
    DefaultVisitor::visitBaseClause(node);
    _out<<indent<<tag.endTagString()<<"\n";
    --_w;
  }

The reason I want to visit every node by type is because many of them have 
unique attributes I want to collect.

-- 
Regards,
Steven




More information about the KDevelop-devel mailing list