//This function takes in the iterator, and rewrite both sides of the sum expression in postFix //Pre- The position is at a symbol +,-,*,/,% //Post- It will change postFix and the iterator void addOp(ListIterator &iter, TokenList &postFix) { int pos; Token saveToken; bool solved = false; while(solved == false) { if (iter.tokenChar() == '*' || iter.tokenChar() == '/' || iter.tokenChar() == '%') { //This means that a product operation was encountered immediately so the prgoram can finish the expression and return without multOp(iter, postFix); } else if (iter.tokenChar() == '+' || iter.tokenChar() == '-') { //We advance to save the next number and then again to check the next character saveToken = iter.token(); iter.advance(); getValue(iter, postFix); iter.advance(); if (iter.tokenChar() == '*' || iter.tokenChar() == '/' || iter.tokenChar() == '%') { //If a product expression is found it will calculate the entirety of that multOp(iter, postFix); } postFix.push_back(saveToken); } else { solved = true; } } }
// getValue // Gets the value of the number/expression at the current position // If the current value is an integer, return it // If it's a parenthetical expression, evaluate, and return // evalMultiplication is a flag used to ensure multiplication happens before addition // If true, it will handle any multiplication that is applied to the current value // That way, what is returned to the addition function is what we actually want to add // Parameters: // iter - the iterator for the list of tokens // postExpr - the postfix expression we are converting to // evalMultiplication (input boolean) whether to evaluate multiplication, see above // Pre-condition: expr[pos] is an int or parenthesis // Post-condition: expr[pos] is the end of the value // If it was an int, it's on the int // If it was a parenthesis, it's on the end parenthesis // If handling multiplication, it's on the last multiplied int // postExpr has the values handled here pushed to it void getValue(ListIterator& iter, TokenList& postExpr, bool evalMultiplication) { bool negative = false; if (!iter.currentIsInteger() && iter.tokenChar() == '-') { negative = true; iter.advance(); } if (iter.currentIsInteger()) { postExpr.push_back(iter.integerValue()); if (negative) { postExpr.push_back(Token('~')); } while (evalMultiplication && isNextOperatorMultiplication(iter)) { iter.advance(); handleMultiplyLevelOperation(iter, postExpr); } } else { handleParenthesis(iter, postExpr); if (negative) { postExpr.push_back(Token('~')); } } }
//This function takes in the iterator, and the TokeList, and will rewrite any product expressions //Pre- The position will be on a operation symbol that is either *, /, % //Post- It will rewrite the infix to postFix product expression void multOp(ListIterator &iter, TokenList &postFix) { Token saveToken; //This loop will run indefinately and rewrite to postFix until the product expression ends while (iter.tokenChar() == '*' || iter.tokenChar() == '/' || iter.tokenChar() == '%') { saveToken = iter.token(); iter.advance(); getValue(iter, postFix); iter.advance(); postFix.push_back(saveToken); } }
// handleParenthesis // Helper function to handle evaluating parenthesis // Parameters: // iter - the iterator for the list of tokens // postExpr - the postfix expression we are converting to // Pre-condition: iter.tokenChar() == '(' // Post-condition: iter.tokenChar() == ')' // postExpr has everything inside the parenthesis pushed to it void handleParenthesis(ListIterator& iter, TokenList& postExpr) { iter.advance(); getValue(iter, postExpr, false); while (iter.tokenChar() != ')') { evalStep(iter, postExpr); } }
// evalStep // Evaluates the current operator // Parameters: // iter - the iterator for the list of tokens // postExpr - the postfix expression we are converting to // Pre-condition: Next token is an operator (although, it will just advance if it isn't) // Post-condition: All values related to this operation pushed to postExpr in the order dictated by postfix // Iter is on the last token evaluated in this step (so iter.advance() next time will // bring it to the next thing to be evaluated) void evalStep(ListIterator& iter, TokenList& postExpr) { iter.advance(); switch (iter.tokenChar()) { case '*': case '/': case '%': handleMultiplyLevelOperation(iter, postExpr); break; case '+': case '-': handleAdditionLevelOperation(iter, postExpr); break; } }
//The function takes in an iterator and TokenList and will rewrite numbers at the iterator's //Pre- The position is located at a number or a parethesis //Post- It will write to the postFix TokenList and update the iterator void getValue(ListIterator &iter, TokenList &postFix) { //If parethesis are found this else if will rewrite the parenthesis in postFix if (iter.tokenChar() == '(') { iter.advance(); getValue(iter, postFix); iter.advance(); assignOp(iter, postFix); } //If the current position is an integer else { postFix.push_back(iter.token()); } }
// isNextOperatorMultiplication // Checks if the next operation in the expression has multiplication precedence // This is used to ensure multiplication is handled before addition // Parameters: // iter - the iterator for the list of tokens - not sent by reference, as in the other // functions, so that we can look ahead without having to go back again. // Pre-condition: Next token is an operator (although, if it's not, I suppose the next operation isn't // technically multiplication) // Return: whether the next operation is multiplication bool isNextOperatorMultiplication(ListIterator iter) { bool isMultiplication; iter.advance(); switch (iter.tokenChar()) { case '*': case '/': case '%': isMultiplication = true; break; default: isMultiplication = false; break; } return isMultiplication; }
//This function will solve a postFix notation TokenList. //Pre- This function takes in an iterator for a postFix TokenList and a TokenList in postFix notation. //Post- It will return the result of the entire postFix notation. int evalPost(ListIterator &iter, TokenList &postFix, VarTree &vt) { Token v1, v2; int value = 0, n1, n2; bool solved = false, solvedI = false; char saveChar; //Making the stack TokenList toSolve; //Runs until the equation is determined to be solved. while (solved == false) { //Will add all the consecutive integers onto the stack while (iter.tokenChar() != '=' && iter.tokenChar() != '+' && iter.tokenChar() != '-' && iter.tokenChar() != '*' && iter.tokenChar() != '/' && iter.tokenChar() != '%') { //Actually pushing onto the stack toSolve.push_front(iter.token()); iter.advance(); } //Getting 2 numbers from the stack v2 = toSolve.pop_front(); v1 = toSolve.pop_front(); //If it a normal integer if(v2.isInteger()) { n2 = v2.integerValue(); } //If it is a variable find it else { n2 = vt.lookup(v2.tokenText()); } //If it a normal integer if(v1.isInteger()) { n1 = v1.integerValue(); } //If it is a variable find it else { n1 = vt.lookup(v1.tokenText()); } //Grabbing the character operation from the originol TokenList saveChar = iter.tokenChar(); iter.advance(); if(saveChar == '+') { value = n1 + n2; } else if(saveChar == '-') { value = n1 - n2; } else if(saveChar == '*') { value = n1 * n2; } else if(saveChar == '/') { value = n1 / n2; } else if(saveChar == '%') { value = n1 % n2; } else if(saveChar == '=') { vt.assign(v1.tokenText(), n2); value = n2; } //Checks if the equation is done if(toSolve.empty() && !(iter != postFix.end())) { solved = true; } //If the equation is not done you push the current result and loop else { toSolve.push_front(Token(value)); } } return value; }