QList<State> buildStateList(QJsonArray const &array) { QList<State> stateList; auto it = array.constBegin(); while (it != array.constEnd()) { stateList.append (buildState((*it).toObject())); ++it; } return stateList; }
//build LR(1) status int LRBuilder::build(const string& start) { auto& endToken = tokenManager.buildToken("_LR_END", "", LEFT, 0); string& startName = start + "_LR"; auto& production = productionManager.buildProduction(startName, { start },""); int id = productionManager.getProductionID(production);//查找产生式 没有则添加 int endId = tokenManager.getTokenId(endToken.name); LRProduction lrProduction{ id, 0, endId}; //S' -> .s, $ initFirst(); startState = buildState({lrProduction}); buildTable(start); return 0; }
int LRBuilder::buildState(const vector<LRProduction> initProduction) { //build Closure LRState state{ initProduction, {} }; cout << "build state; production size:"; cout << initProduction.size() << endl; while (true) { vector<LRProduction> newProduction; for (const auto& lrproduction : state.productions) { const auto& prooduction = productionManager.getProduction(lrproduction.productionId); if (lrproduction.pos < (int)prooduction.right.size()) { //dot is not at end const auto& nextToken = prooduction.right[lrproduction.pos]; if (!tokenManager.isTerminal(nextToken)) {//.后面是非终结符,开始展开 const auto& nextProdutions = productionManager.getProductions((NonterminalToken&)nextToken); for (const auto& nextProdution : nextProdutions) { int id = productionManager.getProductionID(nextProdution); vector<int> tokenids; if (lrproduction.pos + 1 < (int)prooduction.right.size()) { int tid = tokenManager.getTokenId(prooduction.right[lrproduction.pos + 1].name); tokenids.push_back(tid); } tokenids.push_back(lrproduction.lookAhead); const auto& nextFirsts = getFirst(tokenids); for (auto& nextFirst : nextFirsts) { LRProduction nextLR{ id, 0, nextFirst}; if (find(state.productions.begin(), state.productions.end(), nextLR) == state.productions.end()) { newProduction.push_back(nextLR); } } } } } } if (newProduction.size() == 0) { //不再增加新的产生式了。 break; } state.productions.insert(state.productions.end(), newProduction.begin(), newProduction.end());//将新增加的产生式插入状态末尾 } int sid = findState(state); if (sid != -1) { return sid; } int id = lrstatus.size(); lrstatus[state] = id; // build GOTO cout << "state id:" << id<<endl; map<Token, vector<LRProduction>> trans; for (const auto& lrproduction : state.productions) { const auto& prooduction = productionManager.getProduction(lrproduction.productionId); if (lrproduction.pos < (int)prooduction.right.size()) { const auto& nextToken = prooduction.right[lrproduction.pos]; auto& transInit = trans[nextToken]; auto newLR = lrproduction; newLR.pos++; if (find(transInit.begin(), transInit.end(), newLR) == transInit.end()) { trans[nextToken].push_back(newLR); } } } for (const auto& tran : trans) { const auto& token = tran.first; const auto& productions = tran.second; state.action[token] = buildState(productions); } lrstatus_id[id] = state; return id; }
Export int PathFind_Vector(FPoint *start, FPoint *end, FLine *obstructions, int obstructioncount, FPoint *pathbuffer, int pathbuffersize, Image* drawbuffer, drawcbk* drawcallback) { if (!start) return Failure; if (!end) return Failure; if (!obstructions) return Failure; //if (!pathbuffer) return Failure; //if (pathbuffersize < 2) return Failure; if (obstructioncount < 1) { pathbuffer[0] = *start; pathbuffer[1] = *end; return Trivial_Success; } treeNode *root = new treeNode(*start); treeNode *tail = new treeNode(*end); treeNode *current, *newnode; root->pushLeft(tail); FLine currentLine; FPoint where, newpoint; FPoint vector, newvector; float vector_length, vector_angle; int leaf = 0, closest_obstruction; float closest_obstruction_distance; stateStack stack; stack.push_front(buildState(root, Null)); drawbuffer->clear(); drawTree(drawbuffer, root); drawcallback(); while (stack.size() > 0) { leaf = stack.front().leaf; switch (leaf) { case 0: current = stack.front().node->left; stack.front().leaf++; break; case 1: current = stack.front().node->right; stack.front().leaf++; break; case 2: stack.pop_front(); continue; break; } if (current) { currentLine.Start = current->up->point; currentLine.End = current->point; closest_obstruction = -1; closest_obstruction_distance = 999999; for (int o = 0; o < obstructioncount; o++) { bool skip = false; if (currentLine.intersect(obstructions[o], where)) { for (stateStack::iterator iter = stack.begin(); iter != stack.end(); iter++) { if (iter->obstruction == &(obstructions[o])) { skip = true; break; } } if (!skip) { vector = FLine(current->up->point, where).vector(); if (vector.length() < closest_obstruction_distance) { closest_obstruction = o; closest_obstruction_distance = vector.length(); } } } } if (closest_obstruction > -1) { if (stack.front().node->depth < max_tree_depth) { vector = FLine(obstructions[closest_obstruction].Start, obstructions[closest_obstruction].End).vector(); vector_length = vector.length(); vector_angle = AngleBetween(obstructions[closest_obstruction].Start, obstructions[closest_obstruction].End); vector.X = sin(vector_angle * Radian); vector.Y = -cos(vector_angle * Radian); newvector = vector; newvector *= (-1); newpoint = obstructions[closest_obstruction].Start; newpoint += FPoint(newvector.X, newvector.Y); newnode = new treeNode(newpoint); newnode->pushLeft(new treeNode(*end)); current->up->pushLeft(newnode); newvector = vector; newvector *= (vector_length + 1); newpoint = obstructions[closest_obstruction].Start; newpoint += FPoint(newvector.X, newvector.Y); newnode = new treeNode(newpoint); newnode->pushLeft(new treeNode(*end)); current->up->pushRight(newnode); if (leaf == 0) { if (current->up->left) stack.push_front(buildState(current->up->left, &(obstructions[closest_obstruction]))); } else { if (current->up->right) stack.push_front(buildState(current->up->right, &(obstructions[closest_obstruction]))); } } } } drawbuffer->clear(); drawTree(drawbuffer, root); if (current) drawbuffer->setPixelAA(current->point.X, current->point.Y, Pixel(0,0,255,255)); drawcallback(); } return Success; }