コード例 #1
0
ファイル: parser.cpp プロジェクト: OasisGallagher/EL
bool Parser::CreateFirstSetsOnePass() {
	bool anySetModified = false;

	for (GrammarContainer::const_iterator ite = env_->grammars.begin(); ite != env_->grammars.end(); ++ite) {
		Grammar* g = *ite;
		const CondinateContainer& conds = g->GetCondinates();
		GrammarSymbolSet& firstSet = firstSetContainer_[g->GetLhs()];

		for (CondinateContainer::const_iterator ite2 = conds.begin(); ite2 != conds.end(); ++ite2) {
			Condinate* c = *ite2;
			SymbolVector::iterator ite3 = c->symbols.begin();

			for (; ite3 != c->symbols.end(); ++ite3) {
				GrammarSymbol& current = *ite3;

				anySetModified = MergeNonEpsilonElements(firstSet, firstSetContainer_[current]) || anySetModified;

				GrammarSymbolSet& currentFirstSet = firstSetContainer_[current];
				if (currentFirstSet.find(NativeSymbols::epsilon) == currentFirstSet.end()) {
					break;
				}
			}

			if (ite3 == c->symbols.end()) {
				anySetModified = firstSet.insert(NativeSymbols::epsilon).second || anySetModified;
			}
		}
	}

	return anySetModified;
}
コード例 #2
0
ファイル: syntaxer.cpp プロジェクト: OasisGallagher/EL
int Syntaxer::Reduce(int cpos) {
	Grammar* g = nullptr;
	const Condinate* cond = p_.env->grammars.GetTargetCondinate(cpos, &g);

	int length = cond->symbols.front() == NativeSymbols::epsilon ? 0 : cond->symbols.size();

	std::string log = ">> [R] `" + Utility::Concat(stack_->symbols.end() - length, stack_->symbols.end()) + "` to `" + g->GetLhs().ToString() + "`. ";

	void* newValue = (cond->action != nullptr) ? cond->action->Invoke(stack_->values) : nullptr;

	stack_->pop(length);

	int nextState = p_.lrTable.GetGoto(stack_->states.back(), g->GetLhs());
	Debug::Log(log + "Goto state " + std::to_string(nextState) + ".");

	if (nextState < 0) {
		Debug::LogError("empty goto item(" + std::to_string(stack_->states.back()) + ", " + g->GetLhs().ToString() + ")");
		return nextState;
	}

	stack_->push(nextState, newValue, g->GetLhs());
	return nextState;
}
コード例 #3
0
ファイル: parser.cpp プロジェクト: OasisGallagher/EL
bool Parser::CreateFollowSetsOnePass() {
	bool anySetModified = false;

	GrammarSymbolSet gss;
	for (GrammarContainer::const_iterator ite = env_->grammars.begin(); ite != env_->grammars.end(); ++ite) {
		Grammar* g = *ite;
		const CondinateContainer& conds = g->GetCondinates();

		for (CondinateContainer::const_iterator ite2 = conds.begin(); ite2 != conds.end(); ++ite2) {
			Condinate* current = *ite2;
			for (SymbolVector::iterator ite3 = current->symbols.begin(); ite3 != current->symbols.end(); ++ite3) {
				GrammarSymbol& symbol = *ite3;
				if (symbol.SymbolType() == GrammarSymbolTerminal) {
					continue;
				}

				SymbolVector::iterator ite4 = ite3;
				firstSetContainer_.GetFirstSet(gss, ++ite4, current->symbols.end());
				anySetModified = MergeNonEpsilonElements(followSetContainer_[symbol], gss) || anySetModified;

				if (gss.find(NativeSymbols::epsilon) != gss.end()) {
					anySetModified = MergeNonEpsilonElements(followSetContainer_[symbol], followSetContainer_[g->GetLhs()]) || anySetModified;
				}

				gss.clear();
			}
		}
	}

	return anySetModified;
}