KDevelop API Documentation

BaseAST.cpp

Go to the documentation of this file.
00001 /* ANTLR Translator Generator
00002  * Project led by Terence Parr at http://www.jGuru.com
00003  * Software rights: http://www.antlr.org/RIGHTS.html
00004  *
00005  * $Id: BaseAST.cpp,v 1.3 2003/12/26 22:56:34 harald Exp $
00006  */
00007 
00008 #include "antlr/config.hpp"
00009 #include "antlr/AST.hpp"
00010 #include "antlr/BaseAST.hpp"
00011 
00012 #include <typeinfo>
00013 #include <iostream>
00014 
00015 ANTLR_USING_NAMESPACE(std)
00016 #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
00017 namespace antlr {
00018 #endif
00019 
00020 //bool BaseAST::verboseStringConversion;
00021 //ANTLR_USE_NAMESPACE(std)vector<ANTLR_USE_NAMESPACE(std)string> BaseAST::tokenNames;
00022 
00023 BaseAST::BaseAST() : AST()
00024 {
00025 }
00026 
00027 BaseAST::~BaseAST()
00028 {
00029 }
00030 
00031 BaseAST::BaseAST(const BaseAST& other)
00032 : AST(other) // RK: don't copy links! , down(other.down), right(other.right)
00033 {
00034 }
00035 
00036 const char* BaseAST::typeName( void ) const
00037 {
00038     return "BaseAST";
00039 }
00040 
00041 RefAST BaseAST::clone( void ) const
00042 {
00043     cerr << "BaseAST::clone()" << endl;
00044     return nullAST;
00045 }
00046 
00047 void BaseAST::addChild( RefAST c )
00048 {
00049     if( !c )
00050         return;
00051 
00052     RefBaseAST tmp = down;
00053 
00054     if (tmp)
00055     {
00056         while (tmp->right)
00057             tmp = tmp->right;
00058         tmp->right = c;
00059     }
00060     else
00061         down = c;
00062 }
00063 
00064 void BaseAST::doWorkForFindAll(
00065         ANTLR_USE_NAMESPACE(std)vector<RefAST>& v,
00066         RefAST target,bool partialMatch)
00067 {
00068     // Start walking sibling lists, looking for matches.
00069     for (RefAST sibling=this;
00070             sibling;
00071             sibling=sibling->getNextSibling())
00072     {
00073         if ( (partialMatch && sibling->equalsTreePartial(target)) ||
00074                 (!partialMatch && sibling->equalsTree(target)) ) {
00075             v.push_back(sibling);
00076         }
00077         // regardless of match or not, check any children for matches
00078         if ( sibling->getFirstChild() ) {
00079             RefBaseAST(sibling->getFirstChild())->doWorkForFindAll(v, target, partialMatch);
00080         }
00081     }
00082 }
00083 
00087 bool BaseAST::equalsList(RefAST t) const
00088 {
00089     // the empty tree is not a match of any non-null tree.
00090     if (!t)
00091         return false;
00092 
00093     // Otherwise, start walking sibling lists.  First mismatch, return false.
00094     RefAST sibling=this;
00095     for (;sibling && t;
00096             sibling=sibling->getNextSibling(), t=t->getNextSibling()) {
00097         // as a quick optimization, check roots first.
00098         if (!sibling->equals(t))
00099             return false;
00100         // if roots match, do full list match test on children.
00101         if (sibling->getFirstChild()) {
00102             if (!sibling->getFirstChild()->equalsList(t->getFirstChild()))
00103                 return false;
00104         }
00105         // sibling has no kids, make sure t doesn't either
00106         else if (t->getFirstChild())
00107             return false;
00108     }
00109 
00110     if (!sibling && !t)
00111         return true;
00112 
00113     // one sibling list has more than the other
00114     return false;
00115 }
00116 
00120 bool BaseAST::equalsListPartial(RefAST sub) const
00121 {
00122     // the empty tree is always a subset of any tree.
00123     if (!sub)
00124         return true;
00125 
00126     // Otherwise, start walking sibling lists.  First mismatch, return false.
00127     RefAST sibling=this;
00128     for (;sibling && sub;
00129             sibling=sibling->getNextSibling(), sub=sub->getNextSibling()) {
00130         // as a quick optimization, check roots first.
00131         if (!sibling->equals(sub))
00132             return false;
00133         // if roots match, do partial list match test on children.
00134         if (sibling->getFirstChild())
00135             if (!sibling->getFirstChild()->equalsListPartial(sub->getFirstChild()))
00136                 return false;
00137     }
00138 
00139     if (!sibling && sub)
00140         // nothing left to match in this tree, but subtree has more
00141         return false;
00142 
00143     // either both are null or sibling has more, but subtree doesn't
00144     return true;
00145 }
00146 
00150 bool BaseAST::equalsTree(RefAST t) const
00151 {
00152     // check roots first
00153     if (!equals(t))
00154         return false;
00155     // if roots match, do full list match test on children.
00156     if (getFirstChild()) {
00157         if (!getFirstChild()->equalsList(t->getFirstChild()))
00158             return false;
00159     }
00160     // sibling has no kids, make sure t doesn't either
00161     else if (t->getFirstChild())
00162         return false;
00163 
00164     return true;
00165 }
00166 
00170 bool BaseAST::equalsTreePartial(RefAST sub) const
00171 {
00172     // the empty tree is always a subset of any tree.
00173     if (!sub)
00174         return true;
00175 
00176     // check roots first
00177     if (!equals(sub))
00178         return false;
00179     // if roots match, do full list partial match test on children.
00180     if (getFirstChild())
00181         if (!getFirstChild()->equalsListPartial(sub->getFirstChild()))
00182             return false;
00183 
00184     return true;
00185 }
00186 
00191 ANTLR_USE_NAMESPACE(std)vector<RefAST> BaseAST::findAll(RefAST target)
00192 {
00193     ANTLR_USE_NAMESPACE(std)vector<RefAST> roots;
00194 
00195     // the empty tree cannot result in an enumeration
00196     if (target) {
00197         doWorkForFindAll(roots,target,false); // find all matches recursively
00198     }
00199 
00200     return roots;
00201 }
00202 
00207 ANTLR_USE_NAMESPACE(std)vector<RefAST> BaseAST::findAllPartial(RefAST target)
00208 {
00209     ANTLR_USE_NAMESPACE(std)vector<RefAST> roots;
00210 
00211     // the empty tree cannot result in an enumeration
00212     if (target)
00213         doWorkForFindAll(roots,target,true); // find all matches recursively
00214 
00215     return roots;
00216 }
00217 
00218 void BaseAST::setText(const ANTLR_USE_NAMESPACE(std)string& /*txt*/)
00219 {
00220 }
00221 
00222 void BaseAST::setType(int /*type*/)
00223 {
00224 }
00225 
00226 ANTLR_USE_NAMESPACE(std)string BaseAST::toString() const
00227 {
00228     return getText();
00229 }
00230 
00231 ANTLR_USE_NAMESPACE(std)string BaseAST::toStringList() const
00232 {
00233     ANTLR_USE_NAMESPACE(std)string ts="";
00234 
00235     if (getFirstChild())
00236     {
00237         ts+=" ( ";
00238         ts+=toString();
00239         ts+=getFirstChild()->toStringList();
00240         ts+=" )";
00241     }
00242     else
00243     {
00244         ts+=" ";
00245         ts+=toString();
00246     }
00247 
00248     if (getNextSibling())
00249         ts+=getNextSibling()->toStringList();
00250 
00251     return ts;
00252 }
00253 
00254 ANTLR_USE_NAMESPACE(std)string BaseAST::toStringTree() const
00255 {
00256     ANTLR_USE_NAMESPACE(std)string ts = "";
00257 
00258     if (getFirstChild())
00259     {
00260         ts+=" ( ";
00261         ts+=toString();
00262         ts+=getFirstChild()->toStringList();
00263         ts+=" )";
00264     }
00265     else
00266     {
00267         ts+=" ";
00268         ts+=toString();
00269     }
00270     return ts;
00271 }
00272 
00273 #ifdef ANTLR_SUPPORT_XML
00274 /* This whole XML output stuff needs a little bit more thought
00275  * I'd like to store extra XML data in the node. e.g. for custom ast's
00276  * with for instance symboltable references. This
00277  * should be more pluggable..
00278  * @returns boolean value indicating wether a closetag should be produced.
00279  */
00280 bool BaseAST::attributesToStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const
00281 {
00282     out << "text=\"" << this->getText()
00283         << "\" type=\"" << this->getType() << "\"";
00284 
00285     return false;
00286 }
00287 
00288 void BaseAST::toStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const
00289 {
00290     for( RefAST node = this; node != 0; node = node->getNextSibling() )
00291     {
00292         out << "<" << this->typeName() << " ";
00293 
00294         // Write out attributes and if there is extra data...
00295         bool need_close_tag = node->attributesToStream( out );
00296 
00297         if( need_close_tag )
00298         {
00299             // got children so write them...
00300             if( node->getFirstChild() != 0 )
00301                 node->getFirstChild()->toStream( out );
00302 
00303             // and a closing tag..
00304             out << "</" << node->typeName() << ">" << endl;
00305         }
00306     }
00307 }
00308 #endif
00309 
00310 // this is nasty, but it makes the code generation easier
00311 ANTLR_API RefAST nullAST;
00312 ANTLR_API AST* const nullASTptr=0;
00313 
00314 #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
00315 }
00316 #endif
KDE Logo
This file is part of the documentation for KDevelop Version 3.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 23 00:03:50 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003