Advertisement
Guest User

Untitled

a guest
Sep 17th, 2019
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 44.69 KB | None | 0 0
  1. #include <fstream>
  2. #include <iostream>
  3. #include <sstream>
  4. #include <stdio.h>
  5. #include <string>
  6. #include "Parser.h"
  7. #include "PKB.h"
  8. #include "TNode.h"
  9.  
  10. using namespace std;
  11.  
  12. bool Parser::hasAddedFirstProcedure;
  13. string Parser::currentProcedure;
  14. vector<string> Parser::varTable;
  15. vector<string> Parser::procTable;
  16. vector<string> Parser::statementTable;
  17. vector<string> Parser::statementType;
  18. vector<int> Parser::parentStack;
  19. vector<pair<string, string>> Parser::followTable;
  20. vector<pair<string, string>> Parser::parentTable;
  21. map<string, string> Parser::usesRelationshipMap;
  22. map<string, string> Parser::modifiesRelationshipMap;
  23. map<string, vector<string>> Parser::assignPatternMap;
  24. map<string, vector<int>> Parser::procedureStatementsMap;
  25. map<string, vector<string>> Parser::procedureSequenceMap;
  26. map<Parser::Symbol, string> Parser::symbolToStringMap;
  27.  
  28. Parser::Parser() {
  29.     hasAddedFirstProcedure = false;
  30.     currentProcedure = "";
  31.     symbolToStringMap[leftParenthesis] = "(";
  32.     symbolToStringMap[rightParenthesis] = ")";
  33.     symbolToStringMap[leftCurlyBracket] = "{";
  34.     symbolToStringMap[rightCurlyBracket] = "}";
  35.     symbolToStringMap[timesSymbol] = "*";
  36.     symbolToStringMap[divideSymbol] = "/";
  37.     symbolToStringMap[plusSymbol] = "+";
  38.     symbolToStringMap[minusSymbol] = "-";
  39.     symbolToStringMap[moduloSymbol] = "%";
  40.     symbolToStringMap[equalToSymbol] = "==";
  41.     symbolToStringMap[notEqualToSymbol] = "!=";
  42.     symbolToStringMap[greaterThanSymbol] = ">";
  43.     symbolToStringMap[greaterThanEqualToSymbol] = ">=";
  44.     symbolToStringMap[lessThanSymbol] = "<";
  45.     symbolToStringMap[lessThanEqualToSymbol] = "<=";
  46.     symbolToStringMap[semiColon] = ";";
  47.     symbolToStringMap[comma] = ",";
  48.     symbolToStringMap[whileSymbol] = "while";
  49.     symbolToStringMap[ifSymbol] = "if";
  50.     symbolToStringMap[thenSymbol] = "then";
  51.     symbolToStringMap[elseSymbol] = "else";
  52.     symbolToStringMap[procedureSymbol] = "procedure";
  53.     symbolToStringMap[callSymbol] = "call";
  54.     symbolToStringMap[readSymbol] = "read";
  55.     symbolToStringMap[printSymbol] = "print";
  56.     symbolToStringMap[assignSymbol] = "=";
  57.     symbolToStringMap[notConditionSymbol] = "!";
  58.     symbolToStringMap[andConditionSymbol] = "&&";
  59.     symbolToStringMap[orConditionSymbol] = "||";
  60. }
  61.  
  62. // Description: Function opens a file named "filename" and process the information inside
  63. // Parameters:
  64. // - filename: a non-empty string containing the location of the file
  65. // Return:
  66. // - string with the contents of the file
  67. string Parser::getInformationFromFile(string filename) {
  68.     string contents;
  69.     ifstream inFile(filename);
  70.  
  71.     if (inFile) {
  72.         ostringstream ss;
  73.         ss << inFile.rdbuf();
  74.         contents = ss.str();
  75.         inFile.close();
  76.     }
  77.     return contents;
  78. }
  79.  
  80. // Description: Function takes in a string, and remove any leading whitespace, tab, and newline
  81. // Parameters:
  82. // - inputString: a non-empty string
  83. // Return:
  84. // - string with no leading spaces (whitespace, tab, newline)
  85. string Parser::removeLeadingSpacesFromString(string inputString) {
  86.     string resultString = inputString;
  87.     string spaceDelimiter = " ";
  88.     string tabDelimiter = "\t";
  89.     string newLineDelimiter = "\n";
  90.     size_t position;
  91.  
  92.     do {
  93.         position = resultString.find(spaceDelimiter);
  94.         if (position != 0) {
  95.             position = resultString.find(tabDelimiter);
  96.             if (position != 0) {
  97.                 position = resultString.find(newLineDelimiter);
  98.                 if (position != 0) {
  99.                     return resultString;
  100.                 }
  101.                 else {
  102.                     resultString.erase(0, newLineDelimiter.length());
  103.                 }
  104.             }
  105.             else {
  106.                 resultString.erase(0, tabDelimiter.length());
  107.             }
  108.         }
  109.         else {
  110.             resultString.erase(0, spaceDelimiter.length());
  111.         }
  112.     } while (position == 0);
  113. }
  114.  
  115. // Description: Function takes in a string, and remove any trailing whitespace, tab, and newline
  116. // Parameters:
  117. // - inputString: a non-empty string
  118. // Return:
  119. // - string with no trailing spaces (whitespace, tab)
  120. string Parser::removeTrailingSpacesFromString(string inputString) {
  121.     string lastCharacterString;
  122.     string spaceDelimiter = " ";
  123.     string tabDelimiter = "\t";
  124.     size_t spacePosition;
  125.     size_t tabPosition;
  126.  
  127.     lastCharacterString = inputString[inputString.length() - 1];
  128.  
  129.     while (lastCharacterString == spaceDelimiter || lastCharacterString == tabDelimiter) {
  130.         lastCharacterString = inputString[inputString.length() - 1];
  131.         if (lastCharacterString == spaceDelimiter) {
  132.             inputString = inputString.substr(0, inputString.length() - 1);
  133.         }
  134.         else if (lastCharacterString == tabDelimiter) {
  135.             inputString = inputString.substr(0, inputString.length() - 1);
  136.         }
  137.     }
  138.     return inputString;
  139. }
  140.  
  141. // Description: Function checks if an input string of file contents is a valid SIMPLE program
  142. // Concrete Syntax Grammar Rule:
  143. // program: procedure+
  144. // Parameters:
  145. // - contents: a non-empty string containing the file contents
  146. // Return:
  147. // - true if the file contents is a valid SIMPLE program
  148. // - false if the file contents is an invalid SIMPLE program
  149. bool Parser::program(string contents) {
  150.     while (contents != "INVALID" && expect(procedureSymbol, contents)) {
  151.         contents = procedure(contents);
  152.     }
  153.  
  154.     if (contents == "INVALID") {
  155.         return false;
  156.     }
  157.  
  158.     // Check for non-existing procedure calls
  159.     for (map<string, vector<string>>::iterator it = procedureSequenceMap.begin(); it != procedureSequenceMap.end(); it++) {
  160.         for (int i = 0; i < it->second.size(); i++) {
  161.             if (find(procTable.begin(), procTable.end(), it->second[i]) == procTable.end()) {
  162.                 return false;
  163.             }
  164.         }
  165.     }
  166.  
  167.     // Check for recursive or cyclic procedure calls
  168.     for (map<string, vector<string>>::iterator it = procedureSequenceMap.begin(); it != procedureSequenceMap.end(); it++) {
  169.         for (int i = 0; i < it->second.size(); i++) {
  170.             if (it->first == it->second[i]) {
  171.                 return false;
  172.             }
  173.             map<string, vector<string>>::iterator checkIterator = it;
  174.             checkIterator++;
  175.             for (checkIterator; checkIterator != procedureSequenceMap.end(); checkIterator++) {
  176.                 if (checkIterator->first == it->second[i]) {
  177.                     for (int j = 0; j < checkIterator->second.size(); j++) {
  178.                         if (checkIterator->second[j] == it->first) {
  179.                             return false;
  180.                         }
  181.                     }
  182.                 }
  183.             }
  184.         }
  185.     }
  186.  
  187.     processAssignStatementPatterns();
  188.     processModifiesRelationships();
  189.     processUsesRelationships();
  190.     return true;
  191. }
  192.  
  193. // Description: Function checks for the grammar rule for procedure
  194. // Concrete Syntax Grammar Rule:
  195. // procedure: 'procedure' proc_name '{' stmtLst '}'
  196. // Parameters:
  197. // - contents: a non-empty string containing the file contents
  198. // Return:
  199. // - string containing remaining file contents if the grammar rule for procedure is valid
  200. // - "INVALID" if the grammar rule for procedure is invalid
  201. string Parser::procedure(string contents) {
  202.     if (expect(procedureSymbol, contents)) {
  203.         contents = accept(procedureSymbol, contents);
  204.         string leftCurlyBracesTerminal = "{";
  205.         size_t position = contents.find(leftCurlyBracesTerminal);
  206.         if (position != string::npos) {
  207.             string extractedProcedureName = contents.substr(0, position);
  208.             extractedProcedureName = removeTrailingSpacesFromString(extractedProcedureName);
  209.             if (isValidNameIdentifier(extractedProcedureName)) {
  210.                 if (find(procTable.begin(), procTable.end(), extractedProcedureName) == procTable.end()) {
  211.                     procTable.push_back(extractedProcedureName);
  212.                 }
  213.                 else {
  214.                     return "INVALID";
  215.                 }
  216.                 currentProcedure = extractedProcedureName;
  217.                 vector<int> emptyIntegerVector;
  218.                 vector<string> emptyStringVector;
  219.                 procedureSequenceMap[currentProcedure] = emptyStringVector;
  220.                 procedureStatementsMap[currentProcedure] = emptyIntegerVector;
  221.                 contents = eraseStringFromStartToPosition(contents, position);
  222.                 if (expect(leftCurlyBracket, contents)) {
  223.                     contents = accept(leftCurlyBracket, contents);
  224.                 }
  225.                 contents = statementList(contents);
  226.                 if (contents != "INVALID") {
  227.                     if (expect(rightCurlyBracket, contents)) {
  228.                         contents = accept(rightCurlyBracket, contents);
  229.                         return contents;
  230.                     }
  231.                 }
  232.             }
  233.         }
  234.     }
  235.     return "INVALID";
  236. }
  237.  
  238. // Description: Function checks for the grammar rule for statement list
  239. // Concrete Syntax Grammar Rule:
  240. // stmtLst: stmt+
  241. // Parameters:
  242. // - contents: a non-empty string representing the remaining file contents
  243. // Returns:
  244. // - string of remaining file contents if the grammar rule for statement list is valid
  245. // - "INVALID" if the grammar rule for statement list is invalid
  246. string Parser::statementList(string contents) {
  247.     // This is to check for at least one statement. If there isn't, the SIMPLE program is invalid.
  248.     if (expect(rightCurlyBracket, contents)) {
  249.         return "INVALID";
  250.     }
  251.     size_t i = statementTable.size() + 1;
  252.     //followTable.push_back(make_pair(to_string(statementTable.size() - 1), to_string(statementTable.size())));
  253.     string contentStatus = statement(contents);
  254.     while (contentStatus != "INVALID" && !expect(rightCurlyBracket, contentStatus)) {
  255.         followTable.push_back(make_pair(to_string(i), to_string(statementTable.size() + 1)));
  256.         i = statementTable.size() + 1;
  257.         contentStatus = statement(contentStatus);
  258.     }
  259.     return contentStatus;
  260. }
  261.  
  262. // Description: Function checks for the grammar rule for statement
  263. // Concrete Syntax Grammar Rule:
  264. // read: 'read' var_name ';'
  265. // print: 'print' var_name ';'
  266. // call: 'call' proc_name ';'
  267. // while: 'while' '(' cond_expr ')' '{' stmtLst '}'
  268. // if: 'if' '(' cond_expr ')' 'then' '{' stmtLst '}' else '{' stmtLst '}'
  269. // assign: var_name '=' expr ';'
  270. // Parameters:
  271. // - contents: a non-empty string representing the remaining file contents
  272. // Returns:
  273. // - string of remaining file contents if the grammar rule for statement is valid
  274. // - "INVALID" if the grammar rule for statement is invalid
  275. string Parser::statement(string contents) {
  276.     size_t rightCurlyBracketPosition = contents.find(symbolToStringMap[rightCurlyBracket]);
  277.     if (rightCurlyBracketPosition == 0) {
  278.         return contents;
  279.     }
  280.  
  281.     size_t semiColonPosition = contents.find(symbolToStringMap[semiColon]);
  282.     size_t assignPosition = contents.find(symbolToStringMap[assignSymbol]);
  283.  
  284.     if (expect(readSymbol, contents)) {
  285.         contents = accept(readSymbol, contents);
  286.         string readStatement = symbolToStringMap[readSymbol] + " ";
  287.         size_t semiColonPosition = contents.find(symbolToStringMap[semiColon]);
  288.         string varName = contents.substr(0, semiColonPosition);
  289.         varName = removeTrailingSpacesFromString(varName);
  290.         if (isValidNameIdentifier(varName)) {
  291.             readStatement = readStatement + varName;
  292.             if (find(varTable.begin(), varTable.end(), varName) == varTable.end()) {
  293.                 varTable.push_back(varName);
  294.             }
  295.             contents.erase(0, semiColonPosition);
  296.             contents = removeLeadingSpacesFromString(contents);
  297.             if (expect(semiColon, contents)) {
  298.                 contents = accept(semiColon, contents);
  299.                 readStatement = readStatement + symbolToStringMap[semiColon];
  300.                 statementTable.push_back(readStatement);
  301.                 addParent();
  302.                 statementType.push_back(symbolToStringMap[readSymbol]);
  303.                 procedureStatementsMap[currentProcedure].push_back(statementTable.size());
  304.                 return contents;
  305.             }
  306.         }
  307.     }
  308.     else if (expect(printSymbol, contents)) {
  309.         contents = accept(printSymbol, contents);
  310.         string printStatement = symbolToStringMap[printSymbol] + " ";
  311.         size_t semiColonPosition = contents.find(symbolToStringMap[semiColon]);
  312.         string varName = contents.substr(0, semiColonPosition);
  313.         varName = removeTrailingSpacesFromString(varName);
  314.         if (isValidNameIdentifier(varName)) {
  315.             printStatement = printStatement + varName;
  316.             if (find(varTable.begin(), varTable.end(), varName) == varTable.end()) {
  317.                 varTable.push_back(varName);
  318.             }
  319.             contents.erase(0, semiColonPosition);
  320.             contents = removeLeadingSpacesFromString(contents);
  321.             if (expect(semiColon, contents)) {
  322.                 contents = accept(semiColon, contents);
  323.                 printStatement = printStatement + symbolToStringMap[semiColon];
  324.                 statementTable.push_back(printStatement);
  325.                 addParent();
  326.                 statementType.push_back(symbolToStringMap[printSymbol]);
  327.                 procedureStatementsMap[currentProcedure].push_back(statementTable.size());
  328.                 return contents;
  329.             }
  330.         }
  331.     }
  332.     else if (expect(callSymbol, contents)) {
  333.         contents = accept(callSymbol, contents);
  334.         string callStatement = symbolToStringMap[callSymbol] + " ";
  335.         size_t semiColonPosition = contents.find(symbolToStringMap[semiColon]);
  336.         string procName = contents.substr(0, semiColonPosition);
  337.         procName = removeTrailingSpacesFromString(procName);
  338.         if (isValidNameIdentifier(procName)) {
  339.             callStatement = callStatement + procName;
  340.             procedureSequenceMap[currentProcedure].push_back(procName);
  341.             contents.erase(0, semiColonPosition);
  342.             contents = removeLeadingSpacesFromString(contents);
  343.             if (expect(semiColon, contents)) {
  344.                 contents = accept(semiColon, contents);
  345.                 callStatement = callStatement + symbolToStringMap[semiColon];
  346.                 statementTable.push_back(callStatement);
  347.                 addParent();
  348.                 statementType.push_back(symbolToStringMap[callSymbol]);
  349.                 procedureStatementsMap[currentProcedure].push_back(statementTable.size());
  350.                 return contents;
  351.             }
  352.         }
  353.     }
  354.     else if (expect(whileSymbol, contents)) {
  355.         contents = accept(whileSymbol, contents);
  356.         string whileStatement = symbolToStringMap[whileSymbol] + " ";
  357.         if (expect(leftParenthesis, contents)) {
  358.             contents = accept(leftParenthesis, contents);
  359.             whileStatement = whileStatement + symbolToStringMap[leftParenthesis];
  360.             contents = conditionExpression(contents, &whileStatement);
  361.             if (contents != "INVALID") {
  362.                 if (expect(rightParenthesis, contents)) {
  363.                     contents = accept(rightParenthesis, contents);
  364.                     whileStatement = whileStatement + symbolToStringMap[rightParenthesis] + " ";
  365.                     if (expect(leftCurlyBracket, contents)) {
  366.                         contents = accept(leftCurlyBracket, contents);
  367.                         whileStatement = whileStatement + symbolToStringMap[leftCurlyBracket];
  368.                         statementTable.push_back(whileStatement);
  369.                         addParent();
  370.                         parentStack.push_back(statementTable.size());
  371.                         statementType.push_back(symbolToStringMap[whileSymbol]);
  372.                         procedureStatementsMap[currentProcedure].push_back(statementTable.size());
  373.                         whileStatement.clear();
  374.                         contents = statementList(contents);
  375.                         if (contents != "INVALID") {
  376.                             if (expect(rightCurlyBracket, contents)) {
  377.                                 contents = accept(rightCurlyBracket, contents);
  378.                                 parentStack.pop_back();
  379.                                 return contents;
  380.                             }
  381.                         }
  382.                     }
  383.                 }
  384.             }
  385.         }
  386.     }
  387.     else if (expect(ifSymbol, contents)) {
  388.         contents = accept(ifSymbol, contents);
  389.         string ifStatement = symbolToStringMap[ifSymbol] + " ";
  390.         if (expect(leftParenthesis, contents)) {
  391.             contents = accept(leftParenthesis, contents);
  392.             ifStatement = ifStatement + symbolToStringMap[leftParenthesis];
  393.             contents = conditionExpression(contents, &ifStatement);
  394.             if (contents != "INVALID") {
  395.                 if (expect(rightParenthesis, contents)) {
  396.                     contents = accept(rightParenthesis, contents);
  397.                     ifStatement = ifStatement + symbolToStringMap[rightParenthesis] + " ";
  398.                     if (expect(thenSymbol, contents)) {
  399.                         contents = accept(thenSymbol, contents);
  400.                         ifStatement = ifStatement + symbolToStringMap[thenSymbol] + " ";
  401.                         if (expect(leftCurlyBracket, contents)) {
  402.                             contents = accept(leftCurlyBracket, contents);
  403.                             ifStatement = ifStatement + symbolToStringMap[leftCurlyBracket];
  404.                             statementTable.push_back(ifStatement);
  405.                             addParent();
  406.                             parentStack.push_back(statementTable.size());
  407.                             statementType.push_back(symbolToStringMap[ifSymbol]);
  408.                             procedureStatementsMap[currentProcedure].push_back(statementTable.size());
  409.                             contents = statementList(contents);
  410.                             if (contents != "INVALID") {
  411.                                 if (expect(rightCurlyBracket, contents)) {
  412.                                     contents = accept(rightCurlyBracket, contents);
  413.                                     if (expect(elseSymbol, contents)) {
  414.                                         contents = accept(elseSymbol, contents);
  415.                                         if (expect(leftCurlyBracket, contents)) {
  416.                                             contents = accept(leftCurlyBracket, contents);
  417.                                             contents = statementList(contents);
  418.                                             if (contents != "INVALID") {
  419.                                                 if (expect(rightCurlyBracket, contents)) {
  420.                                                     contents = accept(rightCurlyBracket, contents);
  421.                                                     parentStack.pop_back();
  422.                                                     return contents;
  423.                                                 }
  424.                                             }
  425.                                         }
  426.                                     }
  427.                                 }
  428.                             }
  429.                         }
  430.                     }
  431.                 }
  432.             }
  433.         }
  434.     }
  435.     else if (assignPosition != string::npos && semiColonPosition > assignPosition) {
  436.         string varName = contents.substr(0, assignPosition);
  437.         varName = removeTrailingSpacesFromString(varName);
  438.         if (isValidNameIdentifier(varName)) {
  439.             string assignStatement = varName + " ";
  440.             if (find(varTable.begin(), varTable.end(), varName) == varTable.end()) {
  441.                 varTable.push_back(varName);
  442.             }
  443.             contents = eraseStringFromStartToPosition(contents, assignPosition);
  444.             if (expect(assignSymbol, contents)) {
  445.                 contents = accept(assignSymbol, contents);
  446.                 assignStatement = assignStatement + symbolToStringMap[assignSymbol] + " ";
  447.                 semiColonPosition = contents.find(symbolToStringMap[semiColon]);
  448.                 string expr = contents.substr(0, semiColonPosition);
  449.                 expr = removeTrailingSpacesFromString(expr);
  450.                 if (expression(expr)) {
  451.                     assignStatement = assignStatement + expr;
  452.                     contents = eraseStringFromStartToPosition(contents, semiColonPosition);
  453.                     if (expect(semiColon, contents)) {
  454.                         contents = accept(semiColon, contents);
  455.                         assignStatement = assignStatement + symbolToStringMap[semiColon];
  456.                         statementTable.push_back(assignStatement);
  457.                         addParent();
  458.                         statementType.push_back("assign");
  459.                         procedureStatementsMap[currentProcedure].push_back(statementTable.size());
  460.                         return contents;
  461.                     }
  462.                 }
  463.             }
  464.         }
  465.     }
  466.  
  467.     return "INVALID";
  468. }
  469.  
  470. void Parser::addParent() {
  471.     if (parentStack.size() > 0) {
  472.         size_t par = parentStack.back();
  473.         parentTable.push_back(make_pair(to_string(par), to_string(statementTable.size())));
  474.     }
  475. }
  476.  
  477. // Description: Function checks for the grammar rule for condition expression
  478. // Concrete Syntax Grammar Rule:
  479. // cond_expr: rel_expr | '!' '(' cond_expr ')' | '(' cond_expr ')' '&&' '(' cond_expr ')' | '(' cond_expr ')' '||' '(' cond_expr ')'
  480. // Parameters:
  481. // - contents: a non-empty string representing the remaining file contents
  482. // - *statementString: a string pointer to a statement string that will be stored in the statement table
  483. // Returns:
  484. // - string of remaining file contents if the grammar rule for condition expression if valid
  485. // - "INVALID" if the grammar rule for condition expression is invalid
  486. string Parser::conditionExpression(string contents, string *statementString) {
  487.     if (expect(notConditionSymbol, contents)) {
  488.         contents = accept(notConditionSymbol, contents);
  489.         *statementString = *statementString + symbolToStringMap[notConditionSymbol];
  490.         if (expect(leftParenthesis, contents)) {
  491.             contents = accept(leftParenthesis, contents);
  492.             *statementString = *statementString + symbolToStringMap[leftParenthesis];
  493.             size_t rightParenthesisPosition = contents.find(symbolToStringMap[rightParenthesis]);
  494.             string anotherConditionExpression = contents.substr(0, rightParenthesisPosition);
  495.             anotherConditionExpression = removeTrailingSpacesFromString(anotherConditionExpression);
  496.             if (conditionExpression(anotherConditionExpression, statementString) != "INVALID") {
  497.                 contents = eraseStringFromStartToPosition(contents, rightParenthesisPosition);
  498.                 if (expect(rightParenthesis, contents)) {
  499.                     contents = accept(rightParenthesis, contents);
  500.                     *statementString = *statementString + symbolToStringMap[rightParenthesis];
  501.                     return contents;
  502.                 }
  503.             }
  504.         }
  505.     }
  506.     else if (expect(leftParenthesis, contents)) {
  507.         contents = accept(leftParenthesis, contents);
  508.         *statementString = *statementString + symbolToStringMap[leftParenthesis];
  509.         size_t rightParenthesisPosition = contents.find(symbolToStringMap[rightParenthesis]);
  510.         string anotherConditionExpression = contents.substr(0, rightParenthesisPosition);
  511.         anotherConditionExpression = removeTrailingSpacesFromString(anotherConditionExpression);
  512.         if (conditionExpression(anotherConditionExpression, statementString) != "INVALID") {
  513.             contents = eraseStringFromStartToPosition(contents, rightParenthesisPosition);
  514.             if (expect(rightParenthesis, contents)) {
  515.                 contents = accept(rightParenthesis, contents);
  516.                 *statementString = *statementString + symbolToStringMap[rightParenthesis];
  517.                 if (expect(andConditionSymbol, contents) || expect(orConditionSymbol, contents)) {
  518.                     if (expect(andConditionSymbol, contents)) {
  519.                         contents = accept(andConditionSymbol, contents);
  520.                         *statementString = *statementString + symbolToStringMap[andConditionSymbol];
  521.                     }
  522.                     else if (expect(orConditionSymbol, contents)) {
  523.                         contents = accept(orConditionSymbol, contents);
  524.                         *statementString = *statementString + symbolToStringMap[orConditionSymbol];
  525.                     }
  526.                     if (expect(leftParenthesis, contents)) {
  527.                         contents = accept(leftParenthesis, contents);
  528.                         *statementString = *statementString + symbolToStringMap[leftParenthesis];
  529.                         rightParenthesisPosition = contents.find(symbolToStringMap[rightParenthesis]);
  530.                         anotherConditionExpression = contents.substr(0, rightParenthesisPosition);
  531.                         anotherConditionExpression = removeTrailingSpacesFromString(anotherConditionExpression);
  532.                         contents = conditionExpression(contents, statementString);
  533.                         if (contents != "INVALID") {
  534.                             if (expect(rightParenthesis, contents)) {
  535.                                 contents = accept(rightParenthesis, contents);
  536.                                 *statementString = *statementString + symbolToStringMap[rightParenthesis];
  537.                                 return contents;
  538.                             }
  539.                         }
  540.                     }
  541.                 }
  542.             }
  543.         }
  544.     }
  545.    
  546.     size_t rightParenthesisPosition = contents.find(symbolToStringMap[rightParenthesis]);
  547.     string relExpr = contents.substr(0, rightParenthesisPosition);
  548.     relExpr = removeTrailingSpacesFromString(relExpr);
  549.     if (relationshipExpression(relExpr)) {
  550.         *statementString = *statementString + relExpr;
  551.         contents.erase(0, rightParenthesisPosition);
  552.         return contents;
  553.     }
  554.     return "INVALID";
  555. }
  556.  
  557. // Description: Function checks if the string token (based on the symbol) occurs from string length 0 onwards (of contents) and erase it
  558. // Parameters:
  559. // - symbol: symbol representing the string token to select
  560. // - contents: a non-empty string representing the remaining file contents
  561. // Returns:
  562. // - string of remaining file contents if the string token occurs from string length 0 of contents
  563. // - "INVALID" if the string token does not occur from string length 0 of contents
  564. string Parser::accept(Parser::Symbol symbol, string contents) {
  565.     string stringToSearch = symbolToStringMap[symbol];
  566.     size_t stringToSearchPosition = contents.find(stringToSearch);
  567.  
  568.     if (stringToSearchPosition == 0) {
  569.         contents.erase(0, stringToSearch.length());
  570.         contents = removeLeadingSpacesFromString(contents);
  571.         return contents;
  572.     }
  573.     return "INVALID";
  574. }
  575.  
  576. // Description: Function checks if the string token (based on the symbol) occurs from string length 0 onwards (of contents)
  577. // Parameters:
  578. // - symbol: symbol representing the string token to select
  579. // - contents: a non-empty string representing the remaining file contents
  580. // Returns:
  581. // - true if the string token occurs from string length 0 of contents
  582. // - false if the string token does not occur from string length 0 of contents
  583. bool Parser::expect(Parser::Symbol symbol, string contents) {
  584.     string stringToSearch = symbolToStringMap[symbol];
  585.     size_t stringToSearchPosition = contents.find(stringToSearch);
  586.  
  587.     if (stringToSearchPosition == 0) {
  588.         return true;
  589.     }
  590.     return false;
  591. }
  592.  
  593. // Description: Function erases a string from string length 0 to specified position and returns it
  594. // Parameters:
  595. // - stringToErase: a non-empty string to have its contents erased
  596. // - position: the string position to erase to
  597. // Returns:
  598. // - string of remaining contents if position is valid (less than length of string)
  599. string Parser::eraseStringFromStartToPosition(string stringToErase, size_t position) {
  600.     if (position < stringToErase.length()) {
  601.         stringToErase.erase(0, position);
  602.         stringToErase = removeLeadingSpacesFromString(stringToErase);
  603.     }
  604.     return stringToErase;
  605. }
  606.  
  607. // Description: Function checks for the grammar rule for relationship expression
  608. // Concrete Syntax Grammar Rule:
  609. // rel_expr: rel_factor '>' rel_factor | rel_factor '>=' rel_factor | rel_expr: rel_factor '<' rel_factor | rel_factor '<=' rel_factor | rel_factor '!=' rel_factor | rel_factor '==' rel_factor
  610. // Parameters:
  611. // - relExpr: a non-empty string representing the relationship expression to check
  612. // Returns:
  613. // - true if the grammar rule for relationship expression is valid
  614. // - false if the grammar rule for relationship expression is invalid
  615. bool Parser::relationshipExpression(string relExpr) {
  616.     size_t greaterThanPosition = relExpr.find(symbolToStringMap[greaterThanSymbol]);
  617.     size_t greaterThanEqualToPosition = relExpr.find(symbolToStringMap[greaterThanEqualToSymbol]);
  618.     size_t lessThanPosition = relExpr.find(symbolToStringMap[lessThanSymbol]);
  619.     size_t lessThanEqualToPosition = relExpr.find(symbolToStringMap[lessThanEqualToSymbol]);
  620.     size_t equalToPosition = relExpr.find(symbolToStringMap[equalToSymbol]);
  621.     size_t notEqualToPosition = relExpr.find(symbolToStringMap[notEqualToSymbol]);
  622.  
  623.     if (greaterThanEqualToPosition != string::npos) {
  624.         string relFactor = relExpr.substr(0, greaterThanEqualToPosition);
  625.         relFactor = removeTrailingSpacesFromString(relFactor);
  626.         if (relationshipFactor(relFactor)) {
  627.             relExpr = eraseStringFromStartToPosition(relExpr, greaterThanEqualToPosition);
  628.             if (expect(greaterThanEqualToSymbol, relExpr)) {
  629.                 relExpr = accept(greaterThanEqualToSymbol, relExpr);
  630.                 if (relationshipFactor(relExpr)) {
  631.                     return true;
  632.                 }
  633.             }
  634.         }
  635.     }
  636.     else if (lessThanEqualToPosition != string::npos) {
  637.         string relFactor = relExpr.substr(0, lessThanEqualToPosition);
  638.         relFactor = removeTrailingSpacesFromString(relFactor);
  639.         if (relationshipFactor(relFactor)) {
  640.             relExpr = eraseStringFromStartToPosition(relExpr, lessThanEqualToPosition);
  641.             if (expect(lessThanEqualToSymbol, relExpr)) {
  642.                 relExpr = accept(lessThanEqualToSymbol, relExpr);
  643.                 if (relationshipFactor(relExpr)) {
  644.                     return true;
  645.                 }
  646.             }
  647.         }
  648.     }
  649.     else if (greaterThanPosition != string::npos) {
  650.         string relFactor = relExpr.substr(0, greaterThanPosition);
  651.         relFactor = removeTrailingSpacesFromString(relFactor);
  652.         if (relationshipFactor(relFactor)) {
  653.             relExpr = eraseStringFromStartToPosition(relExpr, greaterThanPosition);
  654.             if (expect(greaterThanSymbol, relExpr)) {
  655.                 relExpr = accept(greaterThanSymbol, relExpr);
  656.                 if (relationshipFactor(relExpr)) {
  657.                     return true;
  658.                 }
  659.             }
  660.         }
  661.     }
  662.     else if (lessThanPosition != string::npos) {
  663.         string relFactor = relExpr.substr(0, lessThanPosition);
  664.         relFactor = removeTrailingSpacesFromString(relFactor);
  665.         if (relationshipFactor(relFactor)) {
  666.             relExpr = eraseStringFromStartToPosition(relExpr, lessThanPosition);
  667.             if (expect(lessThanSymbol, relExpr)) {
  668.                 relExpr = accept(lessThanSymbol, relExpr);
  669.                 if (relationshipFactor(relExpr)) {
  670.                     return true;
  671.                 }
  672.             }
  673.         }
  674.     }
  675.     else if (equalToPosition != string::npos) {
  676.         string relFactor = relExpr.substr(0, equalToPosition);
  677.         relFactor = removeTrailingSpacesFromString(relFactor);
  678.         if (relationshipFactor(relFactor)) {
  679.             relExpr = eraseStringFromStartToPosition(relExpr, equalToPosition);
  680.             if (expect(equalToSymbol, relExpr)) {
  681.                 relExpr = accept(equalToSymbol, relExpr);
  682.                 if (relationshipFactor(relExpr)) {
  683.                     return true;
  684.                 }
  685.             }
  686.         }
  687.     }
  688.     else if (notEqualToPosition != string::npos) {
  689.         string relFactor = relExpr.substr(0, notEqualToPosition);
  690.         relFactor = removeTrailingSpacesFromString(relFactor);
  691.         if (relationshipFactor(relFactor)) {
  692.             relExpr = eraseStringFromStartToPosition(relExpr, notEqualToPosition);
  693.             if (expect(notEqualToSymbol, relExpr)) {
  694.                 relExpr = accept(notEqualToSymbol, relExpr);
  695.                 if (relationshipFactor(relExpr)) {
  696.                     return true;
  697.                 }
  698.             }
  699.         }
  700.     }
  701.  
  702.     return false;
  703. }
  704.  
  705. // Description: Function checks for the grammar rule for relationship factor
  706. // Concrete Syntax Grammar Rule:
  707. // rel_factor: var_name | const_value | expr
  708. // Parameters:
  709. // - relExpr: a non-empty string representing the relationship expression to check
  710. // Returns:
  711. // - true if the grammar rule for relationship factor is valid
  712. // - false if the grammar rule for relationship factor is invalid
  713. bool Parser::relationshipFactor(string relFactor) {
  714.     if (isValidNameIdentifier(relFactor)) {
  715.         if (find(varTable.begin(), varTable.end(), relFactor) == varTable.end()) {
  716.             varTable.push_back(relFactor);
  717.         }
  718.         return true;
  719.     }
  720.     else if (constantValue(relFactor)) {
  721.         return true;
  722.     }
  723.     return expression(relFactor);
  724. }
  725.  
  726. // Description: Function checks for the grammar rule for expression
  727. // Concrete Syntax Grammar Rule:
  728. // expr: expr '+' term | expr '-' term | term
  729. // Parameters:
  730. // - expr: a non-empty string representing the expression to check
  731. // Returns:
  732. // - true if the grammar rule for expression is valid
  733. // - false if the grammar rule for expression is invalid
  734. bool Parser::expression(string expr) {
  735.     if (expect(leftParenthesis, expr)) {
  736.         return term(expr);
  737.     }
  738.  
  739.     size_t position = expr.find(symbolToStringMap[plusSymbol]);
  740.     string anotherExpression;
  741.     if (position != string::npos) {
  742.         size_t minusPosition = expr.find(symbolToStringMap[minusSymbol]);
  743.         if (position > minusPosition && minusPosition != string::npos) {
  744.             position = minusPosition;
  745.         }
  746.         anotherExpression = expr.substr(0, position);
  747.         anotherExpression = removeTrailingSpacesFromString(anotherExpression);
  748.         if (expression(anotherExpression)) {
  749.             expr = eraseStringFromStartToPosition(expr, position);
  750.             if (expect(plusSymbol, expr)) {
  751.                 expr = accept(plusSymbol, expr);
  752.                 return expression(expr);
  753.             }
  754.             else if (expect(minusSymbol, expr)) {
  755.                 expr = accept(minusSymbol, expr);
  756.                 return expression(expr);
  757.             }
  758.         }
  759.     }
  760.     else {
  761.         position = expr.find(symbolToStringMap[minusSymbol]);
  762.         if (position != string::npos) {
  763.             anotherExpression = expr.substr(0, position);
  764.             anotherExpression = removeTrailingSpacesFromString(anotherExpression);
  765.             if (expression(anotherExpression)) {
  766.                 expr = eraseStringFromStartToPosition(expr, position);
  767.                 if (expect(minusSymbol, expr)) {
  768.                     expr = accept(minusSymbol, expr);
  769.                     return expression(expr);
  770.                 }
  771.             }
  772.         }
  773.         return term(expr);
  774.     }
  775.  
  776.     return false;
  777. }
  778.  
  779. // Description: Function checks for the grammar rule for term
  780. // Concrete Syntax Grammar Rule:
  781. // term: term '*' factor | term '/' factor | term '%' factor | factor
  782. // Parameters:
  783. // - inputTerm: a non-empty string representing the term to check
  784. // Returns:
  785. // - true if the grammar rule for term is valid
  786. // - false if the grammar rule for term is invalid
  787. bool Parser::term(string inputTerm) {
  788.     if (expect(leftParenthesis, inputTerm)) {
  789.         return factor(inputTerm);
  790.     }
  791.    
  792.     size_t position = inputTerm.find(symbolToStringMap[timesSymbol]);
  793.     string anotherTerm;
  794.     if (position != string::npos) {
  795.         size_t anotherPosition = inputTerm.find(symbolToStringMap[divideSymbol]);
  796.         size_t moduloPosition = inputTerm.find(symbolToStringMap[moduloSymbol]);
  797.         if (anotherPosition > moduloPosition && moduloPosition != string::npos) {
  798.             anotherPosition = moduloPosition;
  799.         }
  800.         if (position > anotherPosition && anotherPosition != string::npos) {
  801.             position = anotherPosition;
  802.             anotherTerm = inputTerm.substr(0, position);
  803.             anotherTerm = removeTrailingSpacesFromString(anotherTerm);
  804.             if (term(anotherTerm)) {
  805.                 inputTerm = eraseStringFromStartToPosition(inputTerm, position);
  806.                 if (expect(divideSymbol, inputTerm)) {
  807.                     inputTerm = accept(divideSymbol, inputTerm);
  808.                 }
  809.                 else if (expect(moduloSymbol, inputTerm)) {
  810.                     inputTerm = accept(moduloSymbol, inputTerm);
  811.                 }
  812.                 return term(inputTerm);
  813.             }
  814.         }
  815.         else {
  816.             anotherTerm = inputTerm.substr(0, position);
  817.             anotherTerm = removeTrailingSpacesFromString(anotherTerm);
  818.             if (term(anotherTerm)) {
  819.                 inputTerm = eraseStringFromStartToPosition(inputTerm, position);
  820.                 if (expect(timesSymbol, inputTerm)) {
  821.                     inputTerm = accept(timesSymbol, inputTerm);
  822.                     return term(inputTerm);
  823.                 }
  824.             }
  825.         }
  826.     }
  827.     else {
  828.         position = inputTerm.find(symbolToStringMap[divideSymbol]);
  829.         if (position != string::npos) {
  830.             size_t moduloPosition = inputTerm.find(symbolToStringMap[moduloSymbol]);
  831.             if (position > moduloPosition && moduloPosition != string::npos) {
  832.                 position = moduloPosition;
  833.             }
  834.             anotherTerm = inputTerm.substr(0, position);
  835.             anotherTerm = removeTrailingSpacesFromString(anotherTerm);
  836.             if (term(anotherTerm)) {
  837.                 inputTerm = eraseStringFromStartToPosition(inputTerm, position);
  838.                 if (expect(divideSymbol, inputTerm)) {
  839.                     inputTerm = accept(divideSymbol, inputTerm);
  840.                 }
  841.                 else if (expect(moduloSymbol, inputTerm)) {
  842.                     inputTerm = accept(moduloSymbol, inputTerm);
  843.                 }
  844.                 return term(inputTerm);
  845.             }
  846.         }
  847.         else {
  848.             position = inputTerm.find(symbolToStringMap[moduloSymbol]);
  849.             if (position != string::npos) {
  850.                 anotherTerm = inputTerm.substr(0, position);
  851.                 anotherTerm = removeTrailingSpacesFromString(anotherTerm);
  852.                 if (term(anotherTerm)) {
  853.                     inputTerm = eraseStringFromStartToPosition(inputTerm, position);
  854.                     if (expect(moduloSymbol, inputTerm)) {
  855.                         inputTerm = accept(moduloSymbol, inputTerm);
  856.                     }
  857.                     return term(inputTerm);
  858.                 }
  859.             }
  860.             return factor(inputTerm);
  861.         }
  862.     }
  863.     return false;
  864. }
  865.  
  866. // Description: Function checks for the grammar rule for factor
  867. // Concrete Syntax Grammar Rule:
  868. // factor: var_name | const_value | '(' expr ')'
  869. // Parameters:
  870. // - inputFactor: a non-empty string representing the factor to check
  871. // Returns:
  872. // - true if the grammar rule for factor is valid
  873. // - false if the grammar rule for factor is invalid
  874. bool Parser::factor(string inputFactor) {
  875.     if (isValidNameIdentifier(inputFactor)) {
  876.         if (find(varTable.begin(), varTable.end(), inputFactor) == varTable.end()) {
  877.             varTable.push_back(inputFactor);
  878.         }
  879.         return true;
  880.     }
  881.     else if (constantValue(inputFactor)) {
  882.         return true;
  883.     }
  884.     else {
  885.         if (expect(leftParenthesis, inputFactor)) {
  886.             inputFactor = accept(leftParenthesis, inputFactor);
  887.             size_t position = inputFactor.find(symbolToStringMap[rightParenthesis]);
  888.             string expr = inputFactor.substr(0, position);
  889.             if (expression(expr)) {
  890.                 inputFactor = eraseStringFromStartToPosition(inputFactor, position);
  891.                 if (expect(rightParenthesis, inputFactor)) {
  892.                     inputFactor = accept(rightParenthesis, inputFactor);
  893.                     return true;
  894.                 }
  895.             }
  896.         }
  897.     }
  898.     return false;
  899. }
  900.  
  901. // Description: Function checks for the grammar rule for constant value
  902. // Concrete Syntax Grammar Rule:
  903. // const_value: DIGIT+
  904. // Parameters:
  905. // - constValue: a non-empty string representing the constant value to check
  906. // Returns:
  907. // - true if the grammar rule for constant value is valid
  908. // - false if the grammar rule for constant value is invalid
  909. bool Parser::constantValue(string constValue) {
  910.     return isValidIntegerToken(constValue);
  911. }
  912.  
  913. // Description: Function checks if a given string is a valid (variable/procedure) name identifer
  914. // Parameters:
  915. // - name: a non-empty string representing the (variable/procedure) name to check
  916. // Returns:
  917. // - true if the (variable/procedure) name is valid
  918. // - false if the (variable/procedure) name is invalid
  919. bool Parser::isValidNameIdentifier(string name) {
  920.     if (isNotStatementIdentifer(name)) {
  921.         if (isValidNameToken(name)) {
  922.             return true;
  923.         }
  924.     }
  925.     return false;
  926. }
  927.  
  928. // Description: Function checks if a given string is a valid (variable/procedure) name token
  929. // Lexical tokens:
  930. // NAME: LETTER (LETTER|DIGIT)* -- procedure names and variables are strings of letters, and digits, starting with a letter
  931. // Parameters:
  932. // - name: a non-empty string representing the (variable/procedure) name to check
  933. // Returns:
  934. // - true if the (variable/procedure) name is valid
  935. // - false if the (variable/procedure) name is invalid
  936. bool Parser::isValidNameToken(string name) {
  937.     for (string::size_type i = 0; i < name.size(); ++i) {
  938.         if (i == 0) {
  939.             if (!(isValidLetter(name[i]))) {
  940.                 return false;
  941.             }
  942.         }
  943.         else {
  944.             if (!(isValidLetter(name[i]) || isValidDigit(name[i]))) {
  945.                 return false;
  946.             }
  947.         }
  948.     }
  949.     return true;
  950. }
  951.  
  952. // Description: Function checks whether the input character is a valid letter
  953. // Lexical tokens:
  954. // LETTER: A-Z | a-z -- capital or small letter
  955. // Parameters:
  956. // - c: non-empty char
  957. // Return:
  958. // - true if letter is an alphabet
  959. // - false if letter is not an alphabet
  960. bool Parser::isValidLetter(char c) {
  961.     return isalpha(c);
  962. }
  963.  
  964. // Description: Function checks whether the input character is a valid digit
  965. // Lexical tokens:
  966. // DIGIT: 0-9
  967. // Parameters:
  968. // - c: non-empty char
  969. // Return:
  970. // - true if letter is a digit
  971. // - false if letter is not a digit
  972. bool Parser::isValidDigit(char c) {
  973.     return isdigit(c);
  974. }
  975.  
  976. // Description: Function checks whether the input string "constantValue" is a valid integer token
  977. // Lexical tokens:
  978. // INTEGER: DIGIT+ -- constants are sequences of digits
  979. // Parameters:
  980. // - constantValue: a non-empty string
  981. // Return:
  982. // - true if integer token format is valid
  983. // - false if integer token format is not valid
  984. bool Parser::isValidIntegerToken(string constantValue) {
  985.     for (string::size_type i = 0; i < constantValue.size(); ++i) {
  986.         if (!isValidDigit(constantValue[i])) {
  987.             return false;
  988.         }
  989.     }
  990.     return true;
  991. }
  992.  
  993. // Description: Function checks if a given string is a valid (variable/procedure) name identifer
  994. // Parameters:
  995. // - name: a non-empty string representing the (variable/procedure) name to check
  996. // Returns:
  997. // - true if the (variable/procedure) name is valid
  998. // - false if the (variable/procedure) name is one of the statement identifiers (e.g. if, while, etc.)
  999. bool Parser::isNotStatementIdentifer(string name) {
  1000.     if (name != symbolToStringMap[readSymbol] &&
  1001.         name != symbolToStringMap[printSymbol] &&
  1002.         name != symbolToStringMap[callSymbol] &&
  1003.         name != symbolToStringMap[whileSymbol] &&
  1004.         name != symbolToStringMap[ifSymbol]) {
  1005.         return true;
  1006.     }
  1007.     return false;
  1008. }
  1009.  
  1010. void Parser::processAssignStatementPatterns() {
  1011.     assignPatternMap.clear();
  1012.     for (int i = 0; i < statementType.size(); i++) {
  1013.         if (statementType[i] == "assign") {
  1014.             string assignStatement = statementTable[i];
  1015.             size_t position = assignStatement.find(symbolToStringMap[assignSymbol]);
  1016.             string leftOfAssignStatement = assignStatement.substr(0, position);
  1017.             leftOfAssignStatement = removeTrailingSpacesFromString(leftOfAssignStatement);
  1018.             assignStatement = eraseStringFromStartToPosition(assignStatement, position + symbolToStringMap[assignSymbol].length());
  1019.             position = assignStatement.find(symbolToStringMap[semiColon]);
  1020.             string rightOfAssignStatement = assignStatement.substr(0, position);
  1021.             rightOfAssignStatement = removeTrailingSpacesFromString(rightOfAssignStatement);
  1022.             vector<string> assignPattern;
  1023.             assignPattern.push_back(leftOfAssignStatement);
  1024.             assignPattern.push_back(rightOfAssignStatement);
  1025.             assignPatternMap[to_string(i+1)] = assignPattern;
  1026.         }
  1027.     }
  1028. }
  1029.  
  1030. void Parser::processUsesRelationships() {
  1031.     for (int i = 0; i < statementType.size(); i++) {
  1032.         if (statementType[i] == "assign") {
  1033.             string assignStatement = statementTable[i];
  1034.             size_t position = assignStatement.find(symbolToStringMap[assignSymbol]);
  1035.             assignStatement = eraseStringFromStartToPosition(assignStatement, position + symbolToStringMap[assignSymbol].length());
  1036.             position = assignStatement.find(symbolToStringMap[semiColon]);
  1037.             string rightOfAssignStatement = assignStatement.substr(0, position);
  1038.             for (int j = 0; j < varTable.size(); j++) {
  1039.                 position = rightOfAssignStatement.find(varTable[j]);
  1040.                 if (position != string::npos) {
  1041.                     usesRelationshipMap[to_string(i + 1)] = varTable[j];
  1042.                 }
  1043.             }
  1044.         }
  1045.         else if (statementType[i] == symbolToStringMap[printSymbol]) {
  1046.             for (int j = 0; j < varTable.size(); j++) {
  1047.                 size_t position = statementTable[i].find(varTable[j]);
  1048.                 if (position != string::npos) {
  1049.                     usesRelationshipMap[to_string(i + 1)] = varTable[j];
  1050.                 }
  1051.             }
  1052.         }
  1053.         else if (statementType[i] == symbolToStringMap[ifSymbol] || statementType[i] == symbolToStringMap[whileSymbol]) {
  1054.             for (int j = 0; j < varTable.size(); j++) {
  1055.                 size_t position = statementTable[i].find(varTable[j]);
  1056.                 if (position != string::npos) {
  1057.                     usesRelationshipMap[to_string(i + 1)] = varTable[j];
  1058.                 }
  1059.                 // there is a statement s1 in container such that Uses(s1, v) [See above 2 uses cases]
  1060.                 else {
  1061.                     // Use the Parent* relationship to determine if the next lines are in the container
  1062.                 }
  1063.             }
  1064.         }
  1065.     }
  1066.     // Uses (Procedure p, Variable v) holds if there is a statement s in p or
  1067.     // in a procedure called (directly or indirectly) from p such that Uses (s, v) holds.
  1068.     for (int i = 0; i < procTable.size(); i++) {
  1069.         for (map<string, vector<int>>::iterator it = procedureStatementsMap.begin(); it != procedureStatementsMap.end(); it++) {
  1070.             for (int j = 0; j < it->second.size(); j++) {
  1071.                 if (statementType[it->second[j]-1] != symbolToStringMap[callSymbol]) {
  1072.                     // Copy & Paste the Uses (s, v) into here
  1073.                 }
  1074.                 else {
  1075.  
  1076.                 }
  1077.             }
  1078.         }
  1079.     }
  1080. }
  1081.  
  1082. void Parser::processModifiesRelationships() {
  1083.     for (int i = 0; i < statementType.size(); i++) {
  1084.         if (statementType[i] == "assign") {
  1085.             string assignStatement = statementTable[i];
  1086.             size_t position = assignStatement.find(symbolToStringMap[assignSymbol]);
  1087.             string leftOfAssignStatement = assignStatement.substr(0, position);
  1088.             leftOfAssignStatement = removeTrailingSpacesFromString(leftOfAssignStatement);
  1089.             for (int j = 0; j < varTable.size(); j++) {
  1090.                 position = leftOfAssignStatement.find(varTable[j]);
  1091.                 if (position != string::npos) {
  1092.                     modifiesRelationshipMap[to_string(i + 1)] = varTable[j];
  1093.                 }
  1094.             }
  1095.         }
  1096.         else if (statementType[i] == symbolToStringMap[readSymbol]) {
  1097.             for (int j = 0; j < varTable.size(); j++) {
  1098.                 size_t position = statementTable[i].find(varTable[j]);
  1099.                 if (position != string::npos) {
  1100.                     modifiesRelationshipMap[to_string(i + 1)] = varTable[j];
  1101.                 }
  1102.             }
  1103.         }
  1104.         else if (statementType[i] == symbolToStringMap[ifSymbol] || statementType[i] == symbolToStringMap[whileSymbol]) {
  1105.             for (int j = 0; j < varTable.size(); j++) {
  1106.                 // there is a statement s1 in container such that Modifies(s1, v) [See above 2 uses cases]
  1107.             }
  1108.         }
  1109.         else if (statementType[i] == symbolToStringMap[callSymbol]) {
  1110.             // TODO...
  1111.         }
  1112.     }
  1113.     // Modifies (Procedure p, Variable v) holds if there is a statement s in p or
  1114.     // in a procedure called (directly or indirectly) from p such that Modifies (s, v) holds.
  1115.     for (int i = 0; i < procTable.size(); i++) {
  1116.         for (map<string, vector<int>>::iterator it = procedureStatementsMap.begin(); it != procedureStatementsMap.end(); it++) {
  1117.             for (int j = 0; j < it->second.size(); j++) {
  1118.                 if (statementType[it->second[j]-1] != symbolToStringMap[callSymbol]) {
  1119.                     // Copy & Paste the Modifies (s, v) into here
  1120.                 }
  1121.                 else {
  1122.  
  1123.                 }
  1124.             }
  1125.         }
  1126.     }
  1127. }
  1128.  
  1129. void Parser::printFollowTable() {
  1130.     for (auto& element : followTable) {
  1131.         cout << "Follows(" << element.first << "," << element.second << ")" << endl;
  1132.     }
  1133. }
  1134.  
  1135. void Parser::printParentTable() {
  1136.     for (auto& element : parentTable) {
  1137.         cout << "Parents(" << element.first << "," << element.second << ")" << endl;
  1138.     }
  1139. }
  1140.  
  1141. void Parser::printAllVariables() {
  1142.     cout << "Printing VarTable..." << endl;
  1143.     for (int i = 0; i < varTable.size(); i++) {
  1144.         cout << "index " << i << ": \"" << varTable[i] << "\"" << endl;
  1145.     }
  1146. }
  1147.  
  1148. void Parser::printAllProcedures() {
  1149.     cout << "Printing ProcTable..." << endl;
  1150.     for (int i = 0; i < procTable.size(); i++) {
  1151.         cout << "index " << i << ": \"" << procTable[i] << "\"" << endl;
  1152.     }
  1153. }
  1154.  
  1155. void Parser::printAllStatements() {
  1156.     cout << "Printing Statements..." << endl;
  1157.     for (int i = 0; i < statementTable.size(); i++) {
  1158.         cout << "stmt #" << i+1 << ": \"" << statementTable[i] << "\"" << endl;
  1159.     }
  1160.     cout << "Printing Statement Types..." << endl;
  1161.     for (int i = 0; i < statementType.size(); i++) {
  1162.         cout << "stmt #" << i + 1 << ": \"" << statementType[i] << "\"" << endl;
  1163.     }
  1164. }
  1165.  
  1166. void Parser::printAllAssignPatterns() {
  1167.     cout << "Printing Assign Patterns..." << endl;
  1168.     for (map<string, vector<string>>::iterator it = assignPatternMap.begin(); it != assignPatternMap.end(); it++) {
  1169.         cout << "stmtNum: \"" << it->first << "\", lhs: \"" << it->second[0] << "\", rhs: \"" << it->second[1] << "\"" << endl;
  1170.     }
  1171. }
  1172.  
  1173. void Parser::printAllUsesRelationships() {
  1174.     cout << "Printing Uses Relationships..." << endl;
  1175.     for (map<string, string>::iterator it = usesRelationshipMap.begin(); it != usesRelationshipMap.end(); it++) {
  1176.         cout << "Uses(\"" << it->first << "\", \"" << it->second << "\")" << endl;
  1177.     }
  1178. }
  1179.  
  1180. void Parser::printAllModifiesRelationships() {
  1181.     cout << "Printing Modifies Relationships..." << endl;
  1182.     for (map<string, string>::iterator it = modifiesRelationshipMap.begin(); it != modifiesRelationshipMap.end(); it++) {
  1183.         cout << "Modifies(\"" << it->first << "\", \"" << it->second << "\")" << endl;
  1184.     }
  1185. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement