antlr3commontree.inl 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. namespace antlr3 {
  2. template<class ImplTraits>
  3. CommonTree<ImplTraits>::CommonTree()
  4. {
  5. m_startIndex = -1;
  6. m_stopIndex = -1;
  7. m_childIndex = -1;
  8. m_token = NULL;
  9. m_parent = NULL;
  10. }
  11. template<class ImplTraits>
  12. CommonTree<ImplTraits>::CommonTree( const CommonTree& ctree )
  13. :m_children( ctree.m_children)
  14. ,UserData(ctree.UserData)
  15. {
  16. m_startIndex = ctree.m_startIndex;
  17. m_stopIndex = ctree.m_stopIndex;
  18. m_childIndex = ctree.m_childIndex;
  19. m_token = ctree.m_token;
  20. m_parent = ctree.m_parent;
  21. }
  22. template<class ImplTraits>
  23. CommonTree<ImplTraits>::CommonTree( const CommonTokenType* token )
  24. {
  25. m_startIndex = -1;
  26. m_stopIndex = -1;
  27. m_childIndex = -1;
  28. m_token = token;
  29. m_parent = NULL;
  30. }
  31. template<class ImplTraits>
  32. CommonTree<ImplTraits>::CommonTree( const CommonTree* tree )
  33. :UserData(tree->UserData)
  34. {
  35. m_startIndex = tree->get_startIndex();
  36. m_stopIndex = tree->get_stopIndex();
  37. m_childIndex = -1;
  38. m_token = tree->get_token();
  39. m_parent = NULL;
  40. }
  41. template<class ImplTraits>
  42. const typename CommonTree<ImplTraits>::CommonTokenType* CommonTree<ImplTraits>::get_token() const
  43. {
  44. return m_token;
  45. }
  46. template<class ImplTraits>
  47. void CommonTree<ImplTraits>::set_token(typename CommonTree<ImplTraits>::CommonTokenType const* token)
  48. {
  49. m_token = token;
  50. }
  51. template<class ImplTraits>
  52. typename CommonTree<ImplTraits>::ChildrenType& CommonTree<ImplTraits>::get_children()
  53. {
  54. return m_children;
  55. }
  56. template<class ImplTraits>
  57. const typename CommonTree<ImplTraits>::ChildrenType& CommonTree<ImplTraits>::get_children() const
  58. {
  59. return m_children;
  60. }
  61. template<class ImplTraits>
  62. void CommonTree<ImplTraits>::addChild(TreeTypePtr& child)
  63. {
  64. if (child == NULL)
  65. return;
  66. ChildrenType& child_children = child->get_children();
  67. //ChildrenType& tree_children = this->get_children();
  68. if (child->isNilNode() == true)
  69. {
  70. if ( !child_children.empty() && child_children == m_children )
  71. {
  72. // TODO: Change to exception rather than ANTLR3_FPRINTF?
  73. fprintf(stderr, "ANTLR3: An attempt was made to add a child list to itself!\n");
  74. return;
  75. }
  76. // Add all of the children's children to this list
  77. //
  78. if ( !child_children.empty() )
  79. {
  80. if (!m_children.empty())
  81. {
  82. // Need to copy(append) the children
  83. for(auto i = child_children.begin(); i != child_children.end(); ++i)
  84. {
  85. // ANTLR3 lists can be sparse, unlike Array Lists (TODO: really?)
  86. if ((*i) != NULL)
  87. {
  88. m_children.push_back(std::move(*i));
  89. // static_cast to possible subtype (if TreeType trait defined)
  90. TreeType* tree = static_cast<TreeType*>(this);
  91. m_children.back()->set_parent(tree);
  92. m_children.back()->set_childIndex(m_children.size() - 1);
  93. }
  94. }
  95. } else {
  96. // We are build ing the tree structure here, so we need not
  97. // worry about duplication of pointers as the tree node
  98. // factory will only clean up each node once. So we just
  99. // copy in the child's children pointer as the child is
  100. // a nil node (has not root itself).
  101. //
  102. m_children.swap( child_children );
  103. this->freshenParentAndChildIndexes();
  104. }
  105. }
  106. }
  107. else
  108. {
  109. // Tree we are adding is not a Nil and might have children to copy
  110. m_children.push_back( std::move(child) );
  111. // static_cast to possible subtype (if TreeType trait defined)
  112. TreeType* tree = static_cast<TreeType*>(this);
  113. m_children.back()->set_parent(tree);
  114. m_children.back()->set_childIndex(m_children.size() - 1);
  115. }
  116. }
  117. template<class ImplTraits>
  118. void CommonTree<ImplTraits>::addChildren(const ChildListType& kids)
  119. {
  120. for( typename ChildListType::const_iterator iter = kids.begin();
  121. iter != kids.end(); ++iter )
  122. {
  123. this->addChild( *iter );
  124. }
  125. }
  126. template<class ImplTraits>
  127. typename CommonTree<ImplTraits>::TreeTypePtr CommonTree<ImplTraits>::deleteChild(ANTLR_UINT32 i)
  128. {
  129. if( m_children.empty() )
  130. return NULL;
  131. TreeTypePtr killed = m_children.erase( m_children.begin() + i);
  132. this->freshenParentAndChildIndexes(i);
  133. return killed;
  134. }
  135. template<class ImplTraits>
  136. void CommonTree<ImplTraits>::replaceChildren(ANTLR_INT32 startChildIndex, ANTLR_INT32 stopChildIndex, TreeTypePtr newTree)
  137. {
  138. ANTLR_INT32 numNewChildren; // Tracking variable
  139. ANTLR_INT32 delta; // Difference in new vs existing count
  140. if ( m_children.empty() )
  141. {
  142. fprintf(stderr, "replaceChildren call: Indexes are invalid; no children in list for %s", this->get_text().c_str() );
  143. // TODO throw here
  144. return;
  145. }
  146. // How many nodes will go away
  147. ANTLR_INT32 replacingHowMany = stopChildIndex - startChildIndex + 1;
  148. ANTLR_INT32 replacingWithHowMany; // How many nodes will replace them
  149. // Either use the existing list of children in the supplied nil node, or build a vector of the
  150. // tree we were given if it is not a nil node, then we treat both situations exactly the same
  151. //
  152. ChildrenType newChildren;
  153. ChildrenType &newChildrenRef(newChildren);
  154. if (newTree->isNilNode())
  155. {
  156. newChildrenRef = newTree->get_children();
  157. } else {
  158. newChildrenRef.push_back(newTree);
  159. }
  160. // Initialize
  161. replacingWithHowMany = newChildrenRef.size();
  162. numNewChildren = newChildrenRef.size();
  163. delta = replacingHowMany - replacingWithHowMany;
  164. // If it is the same number of nodes, then do a direct replacement
  165. //
  166. if (delta == 0)
  167. {
  168. ANTLR_INT32 j = 0;
  169. for (ANTLR_INT32 i = startChildIndex; i <= stopChildIndex; i++)
  170. {
  171. TreeType *child = newChildrenRef.at(j);
  172. m_children[i] = child;
  173. TreeType* tree = static_cast<TreeType*>(this);
  174. child->set_parent(tree);
  175. child->set_childIndex(i);
  176. j++;
  177. }
  178. }
  179. else if (delta > 0)
  180. {
  181. // Less nodes than there were before
  182. // reuse what we have then delete the rest
  183. for (ANTLR_UINT32 j = 0; j < numNewChildren; j++)
  184. {
  185. m_children[ startChildIndex + j ] = newChildrenRef.at(j);
  186. }
  187. // We just delete the same index position until done
  188. ANTLR_UINT32 indexToDelete = startChildIndex + numNewChildren;
  189. for (ANTLR_UINT32 j = indexToDelete; j <= stopChildIndex; j++)
  190. {
  191. m_children.erase( m_children.begin() + indexToDelete);
  192. }
  193. this->freshenParentAndChildIndexes(startChildIndex);
  194. }
  195. else
  196. {
  197. // More nodes than there were before
  198. // Use what we can, then start adding
  199. for (ANTLR_UINT32 j = 0; j < replacingHowMany; j++)
  200. {
  201. m_children[ startChildIndex + j ] = newChildrenRef.at(j);
  202. }
  203. for (ANTLR_UINT32 j = replacingHowMany; j < replacingWithHowMany; j++)
  204. {
  205. m_children.push_back( newChildrenRef.at(j) );
  206. }
  207. this->freshenParentAndChildIndexes(startChildIndex);
  208. }
  209. }
  210. template<class ImplTraits>
  211. CommonTree<ImplTraits>* CommonTree<ImplTraits>::dupNode() const
  212. {
  213. return new CommonTree<ImplTraits>(this);
  214. }
  215. template<class ImplTraits>
  216. CommonTree<ImplTraits>* CommonTree<ImplTraits>::dupNode(void *p) const
  217. {
  218. return new (p) CommonTree<ImplTraits>(this);
  219. }
  220. template<class ImplTraits>
  221. ANTLR_UINT32 CommonTree<ImplTraits>::get_charPositionInLine() const
  222. {
  223. if(m_token == NULL || (m_token->get_charPositionInLine() == 0) )
  224. {
  225. if(m_children.empty())
  226. return 0;
  227. if(m_children.front())
  228. return m_children.front()->get_charPositionInLine();
  229. return 0;
  230. }
  231. return m_token->get_charPositionInLine();
  232. }
  233. template<class ImplTraits>
  234. typename CommonTree<ImplTraits>::TreeTypePtr& CommonTree<ImplTraits>::getChild(ANTLR_UINT32 i)
  235. {
  236. static TreeTypePtr nul;
  237. if ( m_children.empty() || i >= m_children.size() )
  238. {
  239. // TODO throw here should not happen
  240. return nul;
  241. }
  242. return m_children.at(i);
  243. }
  244. template<class ImplTraits>
  245. void CommonTree<ImplTraits>::set_childIndex( ANTLR_INT32 i)
  246. {
  247. m_childIndex = i;
  248. }
  249. template<class ImplTraits>
  250. ANTLR_INT32 CommonTree<ImplTraits>::get_childIndex() const
  251. {
  252. return m_childIndex;
  253. }
  254. template<class ImplTraits>
  255. ANTLR_UINT32 CommonTree<ImplTraits>::getChildCount() const
  256. {
  257. return static_cast<ANTLR_UINT32>( m_children.size() );
  258. }
  259. template<class ImplTraits>
  260. typename CommonTree<ImplTraits>::TreeType* CommonTree<ImplTraits>::get_parent() const
  261. {
  262. return m_parent;
  263. }
  264. template<class ImplTraits>
  265. void CommonTree<ImplTraits>::set_parent( TreeType* parent)
  266. {
  267. m_parent = parent;
  268. }
  269. template<class ImplTraits>
  270. ANTLR_MARKER CommonTree<ImplTraits>::get_startIndex() const
  271. {
  272. if( m_startIndex==-1 && m_token!=NULL)
  273. return m_token->get_tokenIndex();
  274. return m_startIndex;
  275. }
  276. template<class ImplTraits>
  277. void CommonTree<ImplTraits>::set_startIndex( ANTLR_MARKER index)
  278. {
  279. m_startIndex = index;
  280. }
  281. template<class ImplTraits>
  282. ANTLR_MARKER CommonTree<ImplTraits>::get_stopIndex() const
  283. {
  284. if( m_stopIndex==-1 && m_token!=NULL)
  285. return m_token->get_tokenIndex();
  286. return m_stopIndex;
  287. }
  288. template<class ImplTraits>
  289. void CommonTree<ImplTraits>::set_stopIndex( ANTLR_MARKER index)
  290. {
  291. m_stopIndex = index;
  292. }
  293. template<class ImplTraits>
  294. ANTLR_UINT32 CommonTree<ImplTraits>::getType()
  295. {
  296. if (m_token == NULL)
  297. return CommonTokenType::TOKEN_INVALID;
  298. else
  299. return m_token->get_type();
  300. }
  301. template<class ImplTraits>
  302. typename CommonTree<ImplTraits>::TreeTypePtr& CommonTree<ImplTraits>::getFirstChildWithType(ANTLR_UINT32 type)
  303. {
  304. ANTLR_UINT32 i;
  305. std::size_t cs;
  306. TreeTypePtr t;
  307. if ( !m_children.empty() )
  308. {
  309. cs = m_children.size();
  310. for (i = 0; i < cs; i++)
  311. {
  312. t = m_children[i];
  313. if (t->getType() == type)
  314. {
  315. return t;
  316. }
  317. }
  318. }
  319. return NULL;
  320. }
  321. template<class ImplTraits>
  322. ANTLR_UINT32 CommonTree<ImplTraits>::get_line() const
  323. {
  324. if(m_token == NULL || m_token->get_line() == 0)
  325. {
  326. if ( m_children.empty())
  327. return 0;
  328. if ( m_children.front())
  329. return m_children.front()->get_line();
  330. return 0;
  331. }
  332. return m_token->get_line();
  333. }
  334. template<class ImplTraits>
  335. typename CommonTree<ImplTraits>::StringType CommonTree<ImplTraits>::getText()
  336. {
  337. return this->toString();
  338. }
  339. template<class ImplTraits>
  340. bool CommonTree<ImplTraits>::isNilNode()
  341. {
  342. // This is a Nil tree if it has no payload (Token in our case)
  343. if(m_token == NULL)
  344. return true;
  345. else
  346. return false;
  347. }
  348. template<class ImplTraits>
  349. void CommonTree<ImplTraits>::setChild(ANTLR_UINT32 i, TreeTypePtr child)
  350. {
  351. if( child==NULL)
  352. return;
  353. if( child->isNilNode())
  354. {
  355. // TODO: throw IllegalArgumentException
  356. return;
  357. }
  358. if( m_children.size() <= i )
  359. m_children.resize(i+1);
  360. m_children[i] = child;
  361. TreeType* tree = static_cast<TreeType*>(this);
  362. child->set_parent(tree);
  363. child->set_childIndex(i);
  364. }
  365. template<class ImplTraits>
  366. typename CommonTree<ImplTraits>::StringType CommonTree<ImplTraits>::toStringTree()
  367. {
  368. StringType retval;
  369. if( m_children.empty() )
  370. return this->toString();
  371. /* Need a new string with nothing at all in it.
  372. */
  373. if(this->isNilNode() == false)
  374. {
  375. retval.append("(");
  376. retval.append(this->toString());
  377. retval.append(" ");
  378. }
  379. if ( !m_children.empty())
  380. {
  381. retval.append( m_children.front()->toStringTree());
  382. for (auto i = std::next(m_children.begin()); i != m_children.end(); ++i)
  383. {
  384. retval.append(" ");
  385. retval.append((*i)->toStringTree());
  386. }
  387. }
  388. if (this->isNilNode() == false)
  389. {
  390. retval.append(")");
  391. }
  392. return retval;
  393. }
  394. template<class ImplTraits>
  395. typename CommonTree<ImplTraits>::StringType CommonTree<ImplTraits>::toString()
  396. {
  397. if( this->isNilNode())
  398. return StringType("nil");
  399. return m_token->toString();
  400. }
  401. template<class ImplTraits>
  402. void CommonTree<ImplTraits>::freshenParentAndChildIndexes()
  403. {
  404. this->freshenParentAndChildIndexes(0);
  405. }
  406. template<class ImplTraits>
  407. void CommonTree<ImplTraits>::freshenParentAndChildIndexes(ANTLR_UINT32 offset)
  408. {
  409. // ANTLR_UINT32 count = this->getChildCount();
  410. // Loop from the supplied index and set the indexes and parent
  411. // for (ANTLR_UINT32 c = offset; c < count; c++)
  412. // {
  413. // TreeTypePtr child = this->getChild(c);
  414. // child->set_childIndex(c);
  415. // child->set_parent(this);
  416. // }
  417. // Loop from the supplied index and set the indexes and parent
  418. auto i = m_children.begin();
  419. int c = offset;
  420. if(offset)
  421. std::advance( i, offset );
  422. for(; i != m_children.end(); ++i, ++c)
  423. {
  424. (*i)->set_childIndex(c);
  425. TreeType* tree = static_cast<TreeType*>(this);
  426. (*i)->set_parent(tree);
  427. }
  428. }
  429. template<class ImplTraits>
  430. void CommonTree<ImplTraits>::freshenParentAndChildIndexesDeeply()
  431. {
  432. this->freshenParentAndChildIndexes(0);
  433. }
  434. template<class ImplTraits>
  435. void CommonTree<ImplTraits>::freshenParentAndChildIndexesDeeply(ANTLR_UINT32 offset)
  436. {
  437. ANTLR_UINT32 count = this->getChildCount();
  438. for (ANTLR_UINT32 c = offset; c < count; c++) {
  439. TreeTypePtr child = getChild(c);
  440. child->set_childIndex(c);
  441. child->set_parent(this);
  442. child->freshenParentAndChildIndexesDeeply();
  443. }
  444. }
  445. template<class ImplTraits>
  446. void CommonTree<ImplTraits>::reuse()
  447. {
  448. m_startIndex = -1;
  449. m_stopIndex = -1;
  450. m_childIndex = -1;
  451. m_token = NULL;
  452. m_parent = NULL;
  453. ChildrenType empty;
  454. m_children.swap(empty);
  455. }
  456. template<class ImplTraits>
  457. CommonTree<ImplTraits>::~CommonTree()
  458. {
  459. }
  460. }