BaseAST.cpp
上传用户:afrynkmhm
上传日期:2007-01-06
资源大小:1262k
文件大小:8k
源码类别:

编译器/解释器

开发平台:

Others

  1. /**
  2.  * <b>SOFTWARE RIGHTS</b>
  3.  * <p>
  4.  * ANTLR 2.6.0 MageLang Insitute, 1998
  5.  * <p>
  6.  * We reserve no legal rights to the ANTLR--it is fully in the
  7.  * public domain. An individual or company may do whatever
  8.  * they wish with source code distributed with ANTLR or the
  9.  * code generated by ANTLR, including the incorporation of
  10.  * ANTLR, or its output, into commerical software.
  11.  * <p>
  12.  * We encourage users to develop software with ANTLR. However,
  13.  * we do ask that credit is given to us for developing
  14.  * ANTLR. By "credit", we mean that if you use ANTLR or
  15.  * incorporate any source code into one of your programs
  16.  * (commercial product, research project, or otherwise) that
  17.  * you acknowledge this fact somewhere in the documentation,
  18.  * research report, etc... If you like ANTLR and have
  19.  * developed a nice tool with the output, please mention that
  20.  * you developed it using ANTLR. In addition, we ask that the
  21.  * headers remain intact in our source code. As long as these
  22.  * guidelines are kept, we expect to continue enhancing this
  23.  * system and expect to make other tools available as they are
  24.  * completed.
  25.  * <p>
  26.  * The ANTLR gang:
  27.  * @version ANTLR 2.6.0 MageLang Insitute, 1998
  28.  * @author Terence Parr, <a href=http://www.MageLang.com>MageLang Institute</a>
  29.  * @author <br>John Lilley, <a href=http://www.Empathy.com>Empathy Software</a>
  30.  * @author <br><a href="mailto:pete@yamuna.demon.co.uk">Pete Wells</a>
  31.  */
  32. #include "antlr/BaseAST.hpp"
  33. #ifdef HAS_NOT_CASSERT_H
  34. #include <assert.h>
  35. #else
  36. #include <cassert>
  37. #endif
  38. ANTLR_BEGIN_NAMESPACE(antlr)
  39. //bool BaseAST::verboseStringConversion;
  40. //ANTLR_USE_NAMESPACE(std)vector<ANTLR_USE_NAMESPACE(std)string> BaseAST::tokenNames;
  41. void BaseAST::addChild(RefAST c)
  42. {
  43. if (!c)
  44. return;
  45. RefBaseAST tmp=down;
  46. if (tmp) {
  47. while (tmp->right)
  48. tmp=tmp->right;
  49. tmp->right=c;
  50. } else {
  51. down=c;
  52. }
  53. }
  54. void BaseAST::doWorkForFindAll(
  55. ANTLR_USE_NAMESPACE(std)vector<RefAST>& v,
  56. RefAST target,bool partialMatch)
  57. {
  58. // Start walking sibling lists, looking for matches.
  59. for (RefAST sibling=this;
  60. sibling;
  61. sibling=sibling->getNextSibling())
  62. {
  63. if ( (partialMatch && sibling->equalsTreePartial(target)) ||
  64. (!partialMatch && sibling->equalsTree(target)) ) {
  65. v.push_back(sibling);
  66. }
  67. // regardless of match or not, check any children for matches
  68. if ( sibling->getFirstChild() ) {
  69. RefBaseAST(sibling->getFirstChild())->doWorkForFindAll(v, target, partialMatch);
  70. }
  71. }
  72. }
  73. /** Is node t equal to this in terms of token type and text? */
  74. bool BaseAST::equals(RefAST t) const
  75. {
  76. if (!t)
  77. return false;
  78. return (getText() == t->getText()) && (getType() == t->getType());
  79. }
  80. /** Is t an exact structural and equals() match of this tree.  The
  81.  *  'this' reference is considered the start of a sibling list.
  82.  */
  83. bool BaseAST::equalsList(RefAST t) const
  84. {
  85. // the empty tree is not a match of any non-null tree.
  86. if (!t)
  87. return false;
  88. // Otherwise, start walking sibling lists.  First mismatch, return false.
  89. RefAST sibling=this;
  90. for (;sibling && t;
  91. sibling=sibling->getNextSibling(), t=t->getNextSibling()) {
  92. // as a quick optimization, check roots first.
  93. if (!sibling->equals(t))
  94. return false;
  95. // if roots match, do full list match test on children.
  96. if (sibling->getFirstChild()) {
  97. if (!sibling->getFirstChild()->equalsList(t->getFirstChild()))
  98. return false;
  99. }
  100. // sibling has no kids, make sure t doesn't either
  101. else if (t->getFirstChild())
  102. return false;
  103. }
  104. if (!sibling && !t)
  105. return true;
  106. // one sibling list has more than the other
  107. return false;
  108. }
  109. /** Is 'sub' a subtree of this list?
  110.  *  The siblings of the root are NOT ignored.
  111.  */
  112. bool BaseAST::equalsListPartial(RefAST sub) const
  113. {
  114. // the empty tree is always a subset of any tree.
  115. if (!sub)
  116. return true;
  117. // Otherwise, start walking sibling lists.  First mismatch, return false.
  118. RefAST sibling=this;
  119. for (;sibling && sub;
  120. sibling=sibling->getNextSibling(), sub=sub->getNextSibling()) {
  121. // as a quick optimization, check roots first.
  122. if (!sibling->equals(sub))
  123. return false;
  124. // if roots match, do partial list match test on children.
  125. if (sibling->getFirstChild())
  126. if (!sibling->getFirstChild()->equalsListPartial(sub->getFirstChild()))
  127. return false;
  128. }
  129. if (!sibling && sub)
  130. // nothing left to match in this tree, but subtree has more
  131. return false;
  132. // either both are null or sibling has more, but subtree doesn't
  133. return true;
  134. }
  135. /** Is tree rooted at 'this' equal to 't'?  The siblings
  136.  *  of 'this' are ignored.
  137.  */
  138. bool BaseAST::equalsTree(RefAST t) const
  139. {
  140. // check roots first
  141. if (!equals(t))
  142. return false;
  143. // if roots match, do full list match test on children.
  144. if (getFirstChild()) {
  145. if (!getFirstChild()->equalsList(t->getFirstChild()))
  146. return false;
  147. }
  148. // sibling has no kids, make sure t doesn't either
  149. else if (t->getFirstChild())
  150. return false;
  151. return true;
  152. }
  153. /** Is 'sub' a subtree of the tree rooted at 'this'?  The siblings
  154.  *  of 'this' are ignored.
  155.  */
  156. bool BaseAST::equalsTreePartial(RefAST sub) const
  157. {
  158. // the empty tree is always a subset of any tree.
  159. if (!sub)
  160. return true;
  161. // check roots first
  162. if (!equals(sub))
  163. return false;
  164. // if roots match, do full list partial match test on children.
  165. if (getFirstChild())
  166. if (!getFirstChild()->equalsListPartial(sub->getFirstChild()))
  167. return false;
  168. return true;
  169. }
  170. /** Walk the tree looking for all exact subtree matches.  Return
  171.  *  an ASTEnumerator that lets the caller walk the list
  172.  *  of subtree roots found herein.
  173.  */
  174. ANTLR_USE_NAMESPACE(std)vector<RefAST> BaseAST::findAll(RefAST target)
  175. {
  176. ANTLR_USE_NAMESPACE(std)vector<RefAST> roots;
  177. // the empty tree cannot result in an enumeration
  178. if (target) {
  179. doWorkForFindAll(roots,target,false); // find all matches recursively
  180. }
  181. return roots;
  182. }
  183. /** Walk the tree looking for all subtrees.  Return
  184.  *  an ASTEnumerator that lets the caller walk the list
  185.  *  of subtree roots found herein.
  186.  */
  187. ANTLR_USE_NAMESPACE(std)vector<RefAST> BaseAST::findAllPartial(RefAST target)
  188. {
  189. ANTLR_USE_NAMESPACE(std)vector<RefAST> roots;
  190. // the empty tree cannot result in an enumeration
  191. if (target) {
  192. doWorkForFindAll(roots,target,true); // find all matches recursively
  193. }
  194. return roots;
  195. }
  196. RefAST BaseAST::getFirstChild() const
  197. {
  198. return RefAST(down);
  199. }
  200. RefAST BaseAST::getNextSibling() const
  201. {
  202. return RefAST(right);
  203. }
  204. ANTLR_USE_NAMESPACE(std)string BaseAST::getText() const
  205. {
  206. return "";
  207. }
  208. int BaseAST::getType() const
  209. {
  210. return 0;
  211. }
  212. void BaseAST::removeChildren()
  213. {
  214. down=nullAST;
  215. }
  216. void BaseAST::setFirstChild(RefAST c)
  217. {
  218. down=c;
  219. }
  220. void BaseAST::setNextSibling(RefAST n)
  221. {
  222. right=n;
  223. }
  224. void BaseAST::setText(const ANTLR_USE_NAMESPACE(std)string& txt)
  225. {
  226. }
  227. void BaseAST::setType(int type)
  228. {
  229. }
  230. //void BaseAST::setVerboseStringConversion(bool verbose,
  231. // const ANTLR_USE_NAMESPACE(std)vector<ANTLR_USE_NAMESPACE(std)string>& names)
  232. //{
  233. // verboseStringConversion = verbose;
  234. // tokenNames = names;
  235. //}
  236. ANTLR_USE_NAMESPACE(std)string BaseAST::toString() const
  237. {
  238. // if ( verboseStringConversion &&
  239. // !getText().equalsIgnoreCase(tokenNames[getType()]) &&
  240. // !getText().equalsIgnoreCase(Tool.stripFrontBack(tokenNames[getType()],""",""")) ) {
  241. // b.append('[');
  242. // b.append(getText());
  243. // b.append(",<");
  244. // b.append(tokenNames[getType()]);
  245. // b.append(">]");
  246. // return b.toString();
  247. // }
  248. return getText();
  249. }
  250. ANTLR_USE_NAMESPACE(std)string BaseAST::toStringList() const
  251. {
  252. ANTLR_USE_NAMESPACE(std)string ts="";
  253. if (getFirstChild()) {
  254. ts+=" ( ";
  255. ts+=toString();
  256. ts+=getFirstChild()->toStringList();
  257. ts+=" )";
  258. } else {
  259. ts+=" ";
  260. ts+=toString();
  261. }
  262. if (getNextSibling())
  263. ts+=getNextSibling()->toStringList();
  264. return ts;
  265. }
  266. ANTLR_USE_NAMESPACE(std)string BaseAST::toStringTree() const
  267. {
  268. ANTLR_USE_NAMESPACE(std)string ts="";
  269. if (getFirstChild()) {
  270. ts+=" ( ";
  271. ts+=toString();
  272. ts+=getFirstChild()->toStringList();
  273. ts+=" )";
  274. } else {
  275. ts+=" ";
  276. ts+=toString();
  277. }
  278. return ts;
  279. }
  280. // this is nasty, but it makes the code generation easier
  281. RefAST nullAST;
  282. AST* const nullASTptr=0;
  283. ANTLR_END_NAMESPACE