vimix

ASTree part 1 and 2

May 23rd, 2013
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.54 KB | None | 0 0
  1. /*
  2. * ASTree.cpp
  3. * Abstract Syntax Tree
  4. *
  5. * Created by Jonathan Maletic on 11/8/11.
  6. * Copyright 2013 Kent State University. All rights reserved.
  7. *
  8. * Modified by: Venix Cador
  9. *
  10. */
  11.  
  12. #include "ASTree.hpp"
  13.  
  14. /////////////////////////////////////////////////////////////////////
  15. // Copy constructor for srcML
  16. //
  17. srcML::srcML(const srcML& actual) {
  18. tree = new ASTree(*(actual.tree));
  19. }
  20.  
  21. /////////////////////////////////////////////////////////////////////
  22. // Constant time swap for srcML
  23. //
  24. void srcML::swap(srcML& b) {
  25. std::string t_header = header;
  26. header = b.header;
  27. b.header = t_header;
  28.  
  29. ASTree *temp = tree;
  30. tree = b.tree;
  31. b.tree = temp;
  32. }
  33.  
  34. /////////////////////////////////////////////////////////////////////
  35. // Assignment for srcML
  36. //
  37. srcML& srcML::operator=(srcML rhs) {
  38. swap(rhs);
  39. return *this;
  40. }
  41.  
  42. /////////////////////////////////////////////////////////////////////
  43. // Reads in and constructs a srcML object.
  44. //
  45. std::istream& operator>>(std::istream& in, srcML& src){
  46. char ch;
  47. if (!in.eof()) in >> ch;
  48. src.header = readUntil(in, '>');
  49. if (!in.eof()) in >> ch;
  50. if (src.tree) delete src.tree;
  51. src.tree = new ASTree(category, readUntil(in, '>'));
  52. src.tree->read(in);
  53. return in;
  54. }
  55.  
  56.  
  57. /////////////////////////////////////////////////////////////////////
  58. // Prints out a srcML object
  59. //
  60. std::ostream& operator<<(std::ostream& out, const srcML& src){
  61. if (TAGS) out << "<" << src.header << ">" << std::endl;
  62. src.tree->print(out, 0);
  63. return out;
  64. }
  65.  
  66.  
  67.  
  68.  
  69. /////////////////////////////////////////////////////////////////////
  70. // Adds in the includes and profile variables
  71. //
  72. void srcML::mainHeader(std::vector<std::string>& profileNames) {
  73. tree->mainHeader(profileNames);
  74. }
  75.  
  76. /////////////////////////////////////////////////////////////////////
  77. // Adds in the includes and profile variables
  78. //
  79. void srcML::fileHeader(std::vector<std::string>& profileNames) {
  80. tree->fileHeader(profileNames);
  81. }
  82.  
  83.  
  84. /////////////////////////////////////////////////////////////////////
  85. // Adds in the report to the main.
  86. //
  87. void srcML::mainReport(std::vector<std::string>& profileNames) {
  88. tree->mainReport(profileNames);
  89. }
  90.  
  91. /////////////////////////////////////////////////////////////////////
  92. // Inserts a function.count() into each function body.
  93. //
  94. void srcML::funcCount() {
  95. tree->funcCount();
  96. }
  97.  
  98. /////////////////////////////////////////////////////////////////////
  99. // Inserts a filename.count() for each statement.
  100. //
  101. void srcML::lineCount(const std::string& profilename) {
  102. tree->lineCount(profilename);
  103. }
  104.  
  105.  
  106.  
  107.  
  108. /////////////////////////////////////////////////////////////////////
  109. // Constructs a category, token, or whitespace node for the tree.
  110. //
  111. ASTree::ASTree(nodes t, const std::string& s) {
  112. nodeType = t;
  113. switch (nodeType) {
  114. case category:
  115. tag = s;
  116. break;
  117. case token:
  118. text = unEscape(s);
  119. break;
  120. case whitespace:
  121. text = s;
  122. break;
  123. }
  124. }
  125.  
  126. ///
  127. /// NOTE: Can implement destructor implemented in .h file or here.
  128. ///
  129. ASTree::~ASTree()
  130. {
  131. if (!child.empty()){
  132. std::list<ASTree*>::iterator item = child.begin();
  133.  
  134. while (item != child.end()) { // while item is not equal to the end go end delete the node
  135. delete *item++;
  136. }
  137. }
  138. }
  139.  
  140.  
  141.  
  142. /////////////////////////////////////////////////////////////////////
  143. // Copy Constructor for ASTree
  144. //
  145. ASTree::ASTree(const ASTree& actual) {
  146.  
  147. nodeType = actual.nodeType;
  148. tag = actual.tag;
  149. closeTag = actual.closeTag;
  150. text = actual.text;
  151.  
  152. //copy a child recursively
  153. for (std::list<ASTree*>:: const_iterator i = child.begin(); i !=child.end(); ++i){
  154. child.push_back((*i)->copyASTree());
  155. }
  156.  
  157. }
  158.  
  159. ASTree* ASTree::copyASTree(){
  160.  
  161.  
  162. //the new object, fill in to make it a copy of this object
  163. ASTree* result = new ASTree;
  164.  
  165. //copy non container data members
  166. result->nodeType = nodeType;
  167. result->tag = tag;
  168. result->closeTag = closeTag;
  169. result->text = text;
  170.  
  171. //copy a child recursively
  172. for (std::list<ASTree*>:: const_iterator i = child.begin(); i !=child.end(); ++i){
  173. child.push_back((*i)->copyASTree());
  174. }
  175.  
  176. return result;
  177. }
  178.  
  179. /////////////////////////////////////////////////////////////////////
  180. // Constant time swap for ASTree
  181. //
  182. void ASTree::swap(ASTree& b) {
  183. //swap the non-container member
  184. std::swap(nodeType, b.nodeType);
  185. std::swap(tag, b.tag);
  186. std::swap(closeTag, b.closeTag);
  187. std::swap(text, b.text);
  188.  
  189. //use list to call the function recursively
  190. child.swap(b.child);
  191. }
  192.  
  193. /////////////////////////////////////////////////////////////////////
  194. // Assignment for ASTree
  195. //
  196. ASTree& ASTree::operator=(ASTree rhs) {
  197. swap(rhs);
  198. return *this;
  199. }
  200.  
  201.  
  202.  
  203.  
  204. /////////////////////////////////////////////////////////////////////
  205. // Returns an this->child[i] where (this->child[i]->tag == tagName)
  206. //
  207. ASTree* ASTree::getChild(std::string tagName) {
  208. std::list<ASTree*>::iterator ptr = child.begin();
  209. while (((*ptr)->tag != tagName) && (ptr != child.end())) {
  210. ++ptr;
  211. }
  212. return *ptr;
  213. }
  214.  
  215.  
  216.  
  217. /////////////////////////////////////////////////////////////////////
  218. // Returns the full name of a <name> node.
  219. //
  220. std::string ASTree::getName() const {
  221. std::string result;
  222. if (child.front()->tag != "name") {
  223. result = child.front()->text; //A simple name (e.g., main)
  224. } else { //A complex name (e.g., stack::push).
  225. result = child.front()->child.front()->text;
  226. result += "::";
  227. result += child.back()->child.front()->text;
  228. }
  229. return result;
  230. }
  231.  
  232.  
  233.  
  234.  
  235. /////////////////////////////////////////////////////////////////////
  236. // Adds in the includes and profile variables in a main file.
  237. //
  238. void ASTree::mainHeader(std::vector<std::string>& profileNames) {
  239. // iterate until reaching function tag
  240.  
  241. for(std::list<ASTree*>::iterator itr = child.begin(); itr != child.end(); ++i){
  242. if((*itr)->tag != "function"){
  243. ++itr;
  244. }
  245. // creates string to insert
  246.  
  247. std::string profileString("#include\"profile.hpp\"\nprofile functions;\n");
  248.  
  249. for(std::vector<std::string>::iterator nameItr = profileNames.begin();
  250. nameItr < profileNames.end(); ++nameItr){
  251. profileString = profileString + "profile" +*nameItr + ";\n";
  252. }
  253.  
  254. profilrString += "\n";
  255.  
  256. //insert new child ASTree
  257.  
  258.  
  259. child.insert(itr, new ASTree(token, profileString));
  260. break;
  261. }
  262. }
  263. }
  264.  
  265.  
  266. /////////////////////////////////////////////////////////////////////
  267. // Adds in the includes and profile variables for non-main files
  268. //
  269. void ASTree::fileHeader(std::vector<std::string>& profileNames) {
  270. //iterator until reach function tag
  271. std::list<ASTree*>::iterator itr = child.begin();
  272. while((*itr) ->tag != "function"){
  273. ++i;
  274. }
  275.  
  276. // creates string to insert
  277.  
  278. std::string profileString("#include \"profile.hpp\"\n extern profile functions;\n");
  279.  
  280. for(std::vector<std::string>::iterator nameItr = profileNames.begins();
  281. nameItr<profileNames.end(); ++nameItr){
  282.  
  283. profileSring = profileString + " extertn profile " + *nameItr + ";\n";
  284. }
  285.  
  286. profileString += "\n";
  287. // insert new child AStree
  288.  
  289. child.insert(itr, new ASTree(token, profileString));
  290.  
  291. }
  292.  
  293.  
  294. /////////////////////////////////////////////////////////////////////
  295. // Adds in the report to the main.
  296. // Assumes only one return at end of main body.
  297. //
  298. void ASTree::mainReport(std::vector<std::string>& profileNames) {
  299.  
  300. //NEED TO IMPLEMENT
  301.  
  302. //Find the function with name main and then start from the end.
  303. //Find the main - function with name of "main"
  304. //Then start from the end() of this function and iterate
  305. // backwards until you find a return stmt. You'll want
  306. // to insert the report statements before this return.
  307.  
  308.  
  309. }
  310.  
  311.  
  312. /////////////////////////////////////////////////////////////////////
  313. // Adds in a line to count the number of times each function is executed.
  314. // Assumes no nested functions.
  315. //
  316. void ASTree::funcCount() {
  317.  
  318. //NEED TO IMPLEMENT
  319.  
  320. // Check for function, constructor, destructor.
  321. // Find the function name and insert the count.
  322.  
  323. }
  324.  
  325. /////////////////////////////////////////////////////////////////////
  326. // Adds in a line to count the number of times each statement is executed.
  327. // No breaks, returns, throw etc.
  328. // Assumes all construts (for, while, if) have { }.
  329. //
  330. void ASTree::lineCount(const std::string& profileNames) {
  331.  
  332. //NEED TO IMPLEMENT
  333.  
  334. // Check for expr_stmt and call
  335.  
  336.  
  337. }
  338.  
  339.  
  340. /////////////////////////////////////////////////////////////////////
  341. // Read in and construct ASTree
  342. // REQUIRES: '>' was previous charater read
  343. // && this == new ASTree(category, "TagName")
  344. //
  345. //
  346. std::istream& ASTree::read(std::istream& in) {
  347. ASTree *subtree;
  348. std::string temp, Lws, Rws;
  349. char ch;
  350. if (!in.eof()) in.get(ch);
  351. while (!in.eof()) {
  352. if (ch == '<') { //Found a tag
  353. temp = readUntil(in, '>');
  354. if (temp[0] == '/') {
  355. closeTag = temp;
  356. break; //Found close tag, stop recursion
  357. }
  358. subtree = new ASTree(category, temp); //New subtree
  359. subtree->read(in); //Read it in
  360. in.get(ch);
  361. child.push_back(subtree); //Add it to child
  362. } else { //Found a token
  363. temp = std::string(1, ch) + readUntil(in, '<'); //Read it in.
  364. std::vector<std::string> tokenList = tokenize(temp);
  365. for (std::vector<std::string>::const_iterator i = tokenList.begin(); i != tokenList.end(); ++i) {
  366. if (isspace((*i)[0])) {
  367. subtree = new ASTree(whitespace, *i);
  368. } else {
  369. subtree = new ASTree(token, *i);
  370. }
  371. child.push_back(subtree);
  372. }
  373. ch = '<';
  374. }
  375. }
  376. return in;
  377. }
  378.  
  379.  
  380. /////////////////////////////////////////////////////////////////////
  381. // Print an ASTree
  382. // REQUIRES: indent >= 0
  383. //
  384. std::ostream& ASTree::print(std::ostream& out, int indent) const {
  385. if (TAGS) out << std::setw(indent) << " ";
  386. if (TAGS) out << "<" << tag << ">" << std::endl;
  387. for (std::list<ASTree*>::const_iterator i = child.begin(); i != child.end(); ++i) {
  388. switch ((*i)->nodeType) {
  389. case category:
  390. (*i)->print(out, indent + 4);
  391. break;
  392. case token:
  393. //out << std::setw(indent) << " ";
  394. out << (*i)->text; // << std::endl;
  395. break;
  396. case whitespace:
  397. out << (*i)->text;
  398. break;
  399. }
  400. }
  401. if (TAGS) out << std::setw(indent) << " ";
  402. if (TAGS) out << "<" << closeTag << ">" << std::endl;
  403. return out;
  404. }
  405.  
  406.  
  407.  
  408.  
  409.  
  410. /////////////////////////////////////////////////////////////////////
  411. // Utilities
  412. //
  413.  
  414. bool isStopTag(std::string tag) {
  415. if (tag == "decl_stmt") return true;
  416. if (tag == "argument_list") return true;
  417. if (tag == "init") return true;
  418. if (tag == "condition") return true;
  419. if (tag == "cpp:include") return true;
  420. if (tag == "comment type\"block\"") return true;
  421. if (tag == "comment type\"line\"") return true;
  422. if (tag == "macro") return true;
  423.  
  424. return false;
  425. }
  426.  
  427. /////////////////////////////////////////////////////////////////////
  428. // Reads until a key is encountered. Does not include ch.
  429. // REQUIRES: in.open()
  430. // ENSURES: RetVal[i] != key for all i.
  431. //
  432. std::string readUntil(std::istream& in, char key) {
  433. std::string result;
  434. char ch;
  435. in.get(ch);
  436. while (!in.eof() && (ch != key)) {
  437. result += ch;
  438. in.get(ch);
  439. }
  440. return result;
  441. }
  442.  
  443. /////////////////////////////////////////////////////////////////////
  444. // Converts escaped XML charaters back to charater form
  445. // REQUIRES: s == "&lt;"
  446. // ENSURES: RetVal == "<"
  447. //
  448. std::string unEscape(std::string s) {
  449. unsigned pos = 0;
  450. while ((pos = s.find("&gt;")) != s.npos) { s.replace(pos, 4, ">");}
  451. while ((pos = s.find("&lt;")) != s.npos) { s.replace(pos, 4, "<");}
  452. while ((pos = s.find("&amp;")) != s.npos){ s.replace(pos, 5, "&");}
  453. return s;
  454. }
  455.  
  456.  
  457. /////////////////////////////////////////////////////////////////////
  458. // Given: s == " a + c "
  459. // RetVal == {" ", "a", " ", "+", "c", " "}
  460. //
  461. std::vector<std::string> tokenize(const std::string& s) {
  462. std::vector<std::string> result;
  463. std::string temp = "";
  464. unsigned i = 0;
  465. while (i < s.length()) {
  466. while (isspace(s[i]) && (i < s.length())) {
  467. temp.push_back(s[i]);
  468. ++i;
  469. }
  470. if (temp != "") {
  471. result.push_back(temp);
  472. temp = "";
  473. }
  474. while (!isspace(s[i]) && (i < s.length())) {
  475. temp.push_back(s[i]);
  476. ++i;
  477. }
  478. if (temp != "") {
  479. result.push_back(temp);
  480. temp = "";
  481. }
  482. }
  483. return result;
  484. }
Advertisement
Add Comment
Please, Sign In to add comment