예제 #1
0
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();
}
예제 #2
0
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);
    }
}
예제 #3
0
파일: CFG.cpp 프로젝트: ZephyrZhng/code_ub
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);
}
예제 #4
0
파일: CFG.cpp 프로젝트: ZephyrZhng/code_ub
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;
}
예제 #5
0
파일: CFG.cpp 프로젝트: ZephyrZhng/code_ub
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);
}