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