vimix

ASTree part 1

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