void LR0ItemCollectionFamily::build() { set<int> unhandled; { LR0ItemCollection col; col.insert(LR0Item(0, 0)); int ID; insertCollection(col, ID); unhandled.insert(ID); } while (!unhandled.empty()) { int ID = *unhandled.begin(); unhandled.erase(unhandled.begin()); for (auto sym : g_symolList) { LR0ItemCollection newCol; auto& col = ID2Collection[ID]; for (auto item : col) { auto &body = getProductBody(item.productID); if (item.pos < body.size() && body[item.pos] == sym) { newCol.insert(LR0Item(item.productID, item.pos + 1)); } } if (newCol.empty()) continue; int newID; if (insertCollection(newCol, newID)) { unhandled.insert(newID); } transMap[ID][sym] = newID; } } removeCore(); }
void LR0ItemCollectionFamily::closureItem(LR0Item item, LR0ItemCollection& col) { if (!col.insert(item).second) return; auto& body = getProductBody(item.productID); if (item.pos >= body.size()) return; if (!isNonTerm(body[item.pos])) return; int pbegin, pend; getNonTermProductRange(body[item.pos], pbegin, pend); for (int pid = pbegin; pid < pend; ++pid) { closureItem(LR0Item(pid, 0), col); } }
void CFG::constructCanonicalLR0Collection() { if(!augmented) { augmentGrammar(); } canonicalLR0Collection.clear(); canonicalLR0Collection = vector<vector<LR0Item>>( { closure( vector<LR0Item>( { LR0Item( find_if( p.begin(), p.end(), [this](const Production& pr) { return pr.left == s; } ) - p.begin(), 0 ) }) ) }); bool updated = false; vector<string> symbols = v; symbols.insert(symbols.end(), t.begin(), t.end()); do { updated = false; for(size_t i = 0; i < canonicalLR0Collection.size(); ++i) { for(size_t j = 0; j < symbols.size(); ++j) { vector<LR0Item> goToIX = goTo(canonicalLR0Collection[i], symbols[j]); if(goToIX.size() != 0 && !in(goToIX, canonicalLR0Collection)) { canonicalLR0Collection.push_back(goToIX); updated = true; } } } }while(updated); }
vector<LR0Item> CFG::closure(const vector<LR0Item>& is) { vector<LR0Item> js = is; bool updated = false; do { updated = false; for(size_t i = 0; i < js.size(); ++i) { // A -> alpha . B beta Production pr = p[js[i].productionIndex]; if(js[i].dotPosition < pr.right.size()) { string b = pr.right[js[i].dotPosition]; if(in(b, v)) { for(size_t j = 0; j < p.size(); ++j) { if(p[j].left == b) { bool exist = false; for(size_t k = 0; k < js.size(); ++k) { if(js[k].productionIndex == j && js[k].dotPosition == 0) { exist = true; break; } } if(!exist) { js.push_back(LR0Item(j, 0)); updated = true; } } } } } } }while(updated); return js; }
vector<LR0Item> CFG::goTo(const vector<LR0Item>& is, const string& x) { vector<LR0Item> js; for(size_t i = 0; i < is.size(); ++i) { Production pr = p[is[i].productionIndex]; if(!(pr.right.size() == 1 && pr.right[0] == "") && is[i].dotPosition < pr.right.size() && pr.right[is[i].dotPosition] == x) { js.push_back(LR0Item(is[i].productionIndex, is[i].dotPosition + 1)); } } return closure(js); }