KDevelop API Documentation

lib/antlr/src/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.0.4.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Oct 19 08:01:47 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003