void evaluatePostfix(Expression postfix, std::string& evaluation) { stack< std::string > evaluationStack; Token currentToken; std::string temp1; std::string temp2; std::string temp3; while(!postfix.isEmpty()) { currentToken = postfix.front(); postfix.pop(); if(currentToken.getTokenType() == OPERAND) { evaluationStack.push(currentToken.getSymbol()); } else { temp1 = evaluationStack.pop(); temp2 = evaluationStack.pop(); temp3 = "(" + temp2 + currentToken.getSymbol() + temp1 + ")"; evaluationStack.push(temp3); } } evaluation = evaluationStack.pop(); }
void convertToPostfix(Expression infix, Expression& postfix) { stack<Token> conversionStack; Token currentToken; //infix.print(std::cout); Token noopToken; noopToken.setTokenType(OPERATOR); noopToken.setOperatorType(NOOP); noopToken.setSymbol(""); conversionStack.push(noopToken); while(!infix.isEmpty()) { // postfix.print(std::cout); currentToken = infix.front(); infix.pop(); // currentToken.print(std::cout); if(currentToken.getTokenType() == OPERAND) { postfix.push(currentToken); } else { while(currentToken.getOperatorType() <= conversionStack.top().getOperatorType()) { postfix.push(conversionStack.pop()); } conversionStack.push(currentToken); } } while(!conversionStack.isEmpty()) { if(conversionStack.top().getOperatorType() != NOOP) { postfix.push(conversionStack.top()); } conversionStack.pop(); } }
//Evaluate an equation in post fix Cell* ExpParser::PostEval(Expression &post, bool bSymLoad) { static TexAnchor constAncs[4]; static bool ancsSet; if (!ancsSet) { constAncs[0] = TexAnchor(0,0); constAncs[1] = TexAnchor(1,0); constAncs[2] = TexAnchor(1,1); constAncs[3] = TexAnchor(0,1); } Expression temp;//a stack for operands while (!post.empty()) {//there are more terms to evaluate Cell *cell = post.front(); post.pop_front(); char Operator = cell->op(); if (Operator == 0)//if not operator temp.push_front(cell);//push it to the stack else if (Operator == 'C') { Vec c; for (int i = 2; i >= 0; --i) // they come in reverse order { if (temp.empty()) return NULL; // not enough arguments Cell *pc = temp.front(); if (pc->cval() != NULL) return NULL; // Coord in Coord c[i] = pc->val(); temp.pop_front(); } temp.push_front(new CoordCell(c)); } else if ((Operator == 'A') || (Operator == 'T')) { int n = (Operator == 'A')?4:3; SymCell *v[4] = {0}; // init to NULLs for (int i = n-1; i >= 0; --i) // they come in reverse order { if (temp.empty()) return NULL; // not enough arguments Cell *pc = temp.front(); if (pc->cval() == NULL) return NULL; // Coord in Coord temp.pop_front(); v[i] = static_cast<SymCell*>(pc); } MyPolygon *poly = m_obj->AddPoly(v[0]->point(), v[1]->point(), v[2]->point(), (v[3] != NULL)?(v[3]->point()):NULL, constAncs); *m_decompile += (n == 4)?QString("add4("):QString("add3("); for(int i = 0; i < n; ++i) { DefPoint &def = (*g_symbols)[v[i]->clval()]; def.used = true; // mark symbol as used poly->vtx[i]->col = def.color; *m_decompile += + v[i]->clval().c_str(); if (i < n - 1) *m_decompile += ","; } *m_decompile += ")\n"; temp.push_front(new NumCell(0)); } else if (Operator == 'U') // color { // get paramtete if (temp.empty()) return NULL; // not enough arguments Cell *pc = temp.front(); // don't pop it if (pc->clval().size() == 0) return NULL; // not L-value (color ref) static_cast<SymCell*>(pc)->setColorRef(true); } else {//evaluate the last two operands at the stack if (temp.empty()) return NULL; Cell *n2 = temp.front(); temp.pop_front(); if (temp.empty()) return NULL; Cell *n1 = temp.front(); temp.pop_front(); Cell *res; if ((cell->op() == '=') && (!bSymLoad)) // do not load symbol res = n2; // short circuit else res = Eval2(n1, cell, n2); if (res == NULL) return NULL; temp.push_front(res); } } if (temp.size() > 1) return NULL; return temp.front(); }
//next step is to change it into post fix bool ExpParser::In2Post(Expression &in, Expression &post) { Expression temp;// a temp stack for operators while (!in.empty()) {//there are more terms Cell *cell = in.front(); in.pop_front(); char Operator = cell->op(); if (Operator == 0)//this is number { post.push_back(cell);//add as is } else if (isFunc(Operator)) { temp.push_front(cell); } else if (Operator == ',') { while (!temp.empty() && (temp.front()->op() != '(')) {//pops to the open bracket post.push_back(temp.front()); temp.pop_front(); } if (temp.empty()) return false; // missing parens } else if (Operator == ')') { while (temp.front()->op() != '(') {//pops to the open bracket post.push_back(temp.front()); temp.pop_front(); } temp.pop_front(); // pop '(' if (!temp.empty() && (isFunc(temp.front()->op()))) { post.push_back(temp.front()); temp.pop_front(); } // we already checked that there are enough parens. } else if (Operator == '(') { temp.push_front(cell); } else {//need to pop some operaotrs before putting my one while ((!temp.empty()) && ( (isLeftAss(Operator) && (opPriority(Operator) <= stackPriority(temp))) || (!isLeftAss(Operator) && (opPriority(Operator) < stackPriority(temp))) )) { post.push_back(temp.front()); temp.pop_front(); } temp.push_front(cell); } } while (!temp.empty()) {//pops the rest of operators post.push_back(temp.front()); temp.pop_front(); } return true; }
int stackPriority(Expression &s) {//returns the priority of the element on the top 0 for an empty stack return s.empty()?0:opPriority(s.front()->op()); }