void PrintTokenVector(const TokenVector & tokens) { TokenVector::const_iterator it = tokens.begin(); for (; it != tokens.end(); ++it) { PrintToken(*it); } }
// 把解析好的表达式转换成逆波兰式 bool ConvertExpr(const TokenVector & input, TokenVector & output) { TokenStack stack; output.clear(); TokenVector::const_iterator it = input.begin(); for (; it != input.end(); ++it) { if (it->type == OP) { // 左括号,直接压进操作符栈 if (it->value.op == LEFT) { stack.push(*it); } // 右括号,从栈里弹出操作符,直到碰到右括号 else if (it->value.op == RIGHT) { bool find_left = false; while (!stack.empty()) { if (stack.top().value.op == LEFT) { find_left = true; stack.pop(); break; } else { output.push_back(stack.top()); stack.pop(); } } if (!find_left) return false; } // 其它操作符,和栈顶操作符比较优先级 else { while (!stack.empty() && stack.top().value.op != LEFT && OPPriority(stack.top().value.op) >= OPPriority(it->value.op)) { output.push_back(stack.top()); stack.pop(); } stack.push(*it); } } // 非操作符直接输出 else { output.push_back(*it); } } while (!stack.empty()) { output.push_back(stack.top()); stack.pop(); } return true; }
// 逆波兰式计算求值 bool CalcExpr(const TokenVector & input, const TokenVector & expr, Token & result) { TokenStack stack; TokenVector::const_iterator it = expr.begin(); for (; it != expr.end(); ++it) { if (it->type == INT || it->type == FLOAT || it->type == BOOL) { stack.push(*it); } else if (it->type == ARG) { if (it->value.index >= input.size()) return false; const Token & a = input[it->value.index]; if (a.type == INT || a.type == FLOAT || a.type == BOOL) { stack.push(a); } else { return false; } } else if (it->type == RAND) { Token a; a.type = INT; a.value.i = rand(); stack.push(a); } else if (it->type == OP) { if (stack.size() < 2) return false; Token a = stack.top(); stack.pop(); Token b = stack.top(); stack.pop(); Token c; if (GetValue(it->value.op, b, a, c)) { stack.push(c); } else { return false; } } } if (!stack.empty()) { result = stack.top(); return true; } else { return false; } }
/** * Vrati XML se stavem simulace. * * @return XML se stavem simulace */ QString SimState::getState() { QString result; //vysledne XML QXmlStreamWriter doc(&result); doc.setAutoFormatting(true); doc.writeStartDocument(); doc.writeStartElement("petrinet"); //zapisi informace o siti doc.writeAttribute("author",author); doc.writeAttribute("name",name); doc.writeAttribute("version",QString::number(version)); doc.writeAttribute("info",info); //nejprve zapisi mista doc.writeStartElement("places"); PlaceVector::iterator pit; for (pit = places.begin(); pit != places.end(); pit++) { //zapisi misto a informace o nem doc.writeStartElement("place"); PNPlace *place = (*pit); doc.writeAttribute("id",place->id); doc.writeAttribute("posx",place->x); doc.writeAttribute("posy",place->y); TokenVector::iterator tit; TokenVector tokens = place->getTokens(); //zapisi tokeny for (tit = tokens.begin(); tit < tokens.end(); tit++) { doc.writeTextElement("token",QString::number(*tit)); } doc.writeEndElement(); } doc.writeEndElement(); //pote zapisi prechody doc.writeStartElement("transitions"); TransVector::iterator trit; for (trit = transits.begin(); trit != transits.end(); trit++) { doc.writeStartElement("transition"); //zapisi informace o prechodu PNTrans *transit = (*trit); doc.writeAttribute("id",transit->id); doc.writeAttribute("posx",transit->x); doc.writeAttribute("posy",transit->y); ConstraintVector::iterator cvit; for (cvit = transit->constraints.begin(); cvit != transit->constraints.end(); cvit++) { //zapisi podminku Constraint *constraint = (*cvit); bool isNum = false; constraint->first.toInt(&isNum); if (isNum) continue; doc.writeEmptyElement("constraint"); if (constraint -> type == TYPENONE) { doc.writeAttribute("type","none"); } else if (constraint -> type == TYPEANYTHING) { doc.writeAttribute("type","anything"); } else { doc.writeAttribute("var1",constraint->first); doc.writeAttribute("op",QString::number(int(constraint->op))); if (constraint -> type == TYPEVAR) { doc.writeAttribute("type","var"); doc.writeAttribute("var2",constraint->second_var); } else if (constraint -> type == TYPECONST) { doc.writeAttribute("type","const"); doc.writeAttribute("const",QString::number(constraint->second_const)); } } } //zapisi vstupni a vystupni mista prechodu StringToPnplaceMap::iterator placeit; for (placeit = transit->in_names.begin(); placeit != transit->in_names.end(); placeit++) { doc.writeStartElement("inplace"); PNPlace *place = (*placeit).second; doc.writeAttribute("name",(*placeit).first); doc.writeCharacters(place->id); doc.writeEndElement(); } for (placeit = transit->out_names.begin(); placeit != transit->out_names.end(); placeit++) { doc.writeStartElement("outplace"); doc.writeAttribute("name",(*placeit).first); PNPlace *place = (*placeit).second; doc.writeCharacters(place->id); doc.writeEndElement(); } OutputOperations::iterator oit; //nakonec zapisi operace for (oit = transit->operations.begin(); oit != transit->operations.end(); oit++) { doc.writeStartElement("operation"); doc.writeAttribute("output",(*oit).output); OperationVector::iterator opit; //a jednotlive kroky dane operace for (opit = (*oit).operations.begin(); opit != (*oit).operations.end(); opit++) { Operation operation = (*opit); if (operation.op == ADD) doc.writeEmptyElement("plus"); else if (operation.op == SUB) doc.writeEmptyElement("minus"); else { qCritical() << "Error: unknown operation during saving XML"; } doc.writeAttribute("id",operation.var); } doc.writeEndElement(); } doc.writeEndElement(); } doc.writeEndElement(); doc.writeEndElement(); doc.writeEndDocument(); return result; }