コード例 #1
0
ファイル: ItemSetBuilder.cpp プロジェクト: Albeforia/Pitaya
	void ItemSetBuilder::build_successors(const ItemSet& set) {
		// reset
		for (auto& item : set.m_closure) item.complete = false;

		for (auto& item : set.m_closure) {
			if (item.complete) continue;
			auto& production = m_grammar.get_production(item.production_id());
			auto dot = item.dot();
			// skip item whose dot is at right end
			if (dot >= production.rhs_count()) {
				item.complete = true;
				continue;
			}
			auto& symbol = production[dot + 1];		// symbol after dot
			// for each item which has 'symbol' after its dot
			for (auto& item2 : set.m_closure) {
				if (item2.complete) continue;
				auto& production2 = m_grammar.get_production(item2.production_id());
				auto dot2 = item2.dot();
				if (dot2 >= production2.rhs_count()) {
					// 'item2' has no successor
					item2.complete = true;
					continue;
				}
				auto& symbol2 = production2[dot2 + 1];			// symbol after dot
				if (symbol == symbol2) {
					// each item becomes complete after contibuting a successor
					item2.complete = true;
					auto& add = m_curr_item_set.add_kernel(production2, dot2 + 1);
					add.lookaheads().resize(m_grammar.symbol_count());
					// add backward propagation link
					auto& new_node = new_link();
					new_node->next = add.backward_plink();
					add.backward_plink() = new_node;
					new_node->item = &item2;
				}
			}
			// build set from new kernels
			auto& new_set = build_item_set();
			if (symbol.type() == SymbolType::NONTERMINAL) {
				auto& act = set.add_action(symbol, ActionType::GOTO, new_set.id());
			}
			else {
				auto& act = set.add_action(symbol, ActionType::SHIFT, new_set.id());
				assert(act.type != ActionType::SSCONFLICT);
			}
		}
	}