grammar.cpp.svn-base

来自「Complete support for EBNF notation; Obje」· SVN-BASE 代码 · 共 639 行 · 第 1/2 页

SVN-BASE
639
字号
}template<class T> inline set<vector<T> > set_consisting_of_a_single_one_element_vector(const T &x){	set<vector<T> > result;	vector<T> v;	v.push_back(x);	result.insert(v);	return result;}template<class T> inline set<vector<T> > set_consisting_of_a_single_empty_vector(){	set<vector<T> > result;	result.insert(vector<T>());	return result;}set<vector<NonterminalExpression *> > make_rules_proc(NonterminalExpression *expr){	if(typeid(*expr)==typeid(NonterminalExpressionDisjunction))	{		NonterminalExpressionDisjunction &expr_d=*dynamic_cast<NonterminalExpressionDisjunction *>(expr);		set<vector<NonterminalExpression *> > result=make_rules_proc(expr_d.expr1);		union_assign(result, make_rules_proc(expr_d.expr2));		return result;	}	else if(typeid(*expr)==typeid(NonterminalExpressionConjunction))	{		NonterminalExpressionConjunction &expr_c=*dynamic_cast<NonterminalExpressionConjunction *>(expr);		assert(false);		return set<vector<NonterminalExpression *> >();	}	else if(typeid(*expr)==typeid(NonterminalExpressionConcatenation))	{		NonterminalExpressionConcatenation &expr_cat=*dynamic_cast<NonterminalExpressionConcatenation *>(expr);		return concatenate_sets_of_vectors(make_rules_proc(expr_cat.expr1), make_rules_proc(expr_cat.expr2));	}	else if(typeid(*expr)==typeid(NonterminalExpressionComplement))	{		NonterminalExpressionComplement &expr_com=*dynamic_cast<NonterminalExpressionComplement *>(expr);		assert(false);		return set<vector<NonterminalExpression *> >();	}	else if(typeid(*expr)==typeid(NonterminalExpressionOmittable))	{		NonterminalExpressionOmittable &expr_om=*dynamic_cast<NonterminalExpressionOmittable *>(expr);		set<vector<NonterminalExpression *> > result=make_rules_proc(expr_om.expr);		result.insert(vector<NonterminalExpression *>()); // {epsilon}		return result;	}	else if(typeid(*expr)==typeid(NonterminalExpressionInParentheses))	{		NonterminalExpressionInParentheses &expr_p=*dynamic_cast<NonterminalExpressionInParentheses *>(expr);		return make_rules_proc(expr_p.expr);	}	else if(typeid(*expr)==typeid(NonterminalExpressionIteration))	{		NonterminalExpressionIteration &expr_it=*dynamic_cast<NonterminalExpressionIteration *>(expr);		set<vector<NonterminalExpression *> > result;		vector<NonterminalExpression *> v;		v.push_back(&expr_it);		result.insert(v);		if(expr_it.reflexive)			result.insert(vector<NonterminalExpression *>()); // {epsilon}		return result;	}	else if(typeid(*expr)==typeid(NonterminalExpressionIterationPair))	{		NonterminalExpressionIterationPair &expr_it2=*dynamic_cast<NonterminalExpressionIterationPair *>(expr);		return set_consisting_of_a_single_one_element_vector<NonterminalExpression *>(&expr_it2);	}	else if(typeid(*expr)==typeid(NonterminalExpressionEpsilon))	{		return set_consisting_of_a_single_empty_vector<NonterminalExpression *>();	}	else if(typeid(*expr)==typeid(NonterminalExpressionSymbol))	{		NonterminalExpressionSymbol &expr_s=*dynamic_cast<NonterminalExpressionSymbol *>(expr);		return set_consisting_of_a_single_one_element_vector<NonterminalExpression *>(&expr_s);	}	else if(typeid(*expr)==typeid(NonterminalExpressionMemberName))	{		NonterminalExpressionMemberName &expr_mn=*dynamic_cast<NonterminalExpressionMemberName *>(expr);		return make_rules_proc(expr_mn.expr);	}	else if(typeid(*expr)==typeid(NonterminalExpressionCreate))	{		NonterminalExpressionCreate &expr_create=*dynamic_cast<NonterminalExpressionCreate *>(expr);		return set_consisting_of_a_single_one_element_vector<NonterminalExpression *>(&expr_create);	}	else if(typeid(*expr)==typeid(NonterminalExpressionUpdate))	{		NonterminalExpressionUpdate &expr_update=*dynamic_cast<NonterminalExpressionUpdate *>(expr);		return set_consisting_of_a_single_one_element_vector<NonterminalExpression *>(&expr_update);	}	else if(typeid(*expr)==typeid(NonterminalExpressionConnectUp))	{		NonterminalExpressionConnectUp &expr_up=*dynamic_cast<NonterminalExpressionConnectUp *>(expr);		return set_consisting_of_a_single_one_element_vector<NonterminalExpression *>(&expr_up);	}	else if(typeid(*expr)==typeid(NonterminalExpressionCode))	{		NonterminalExpressionCode &expr_code=*dynamic_cast<NonterminalExpressionCode *>(expr);		return set_consisting_of_a_single_one_element_vector<NonterminalExpression *>(&expr_code);	}	else if(typeid(*expr)==typeid(NonterminalExpressionPrecedence))	{		NonterminalExpressionPrecedence &expr_pr=*dynamic_cast<NonterminalExpressionPrecedence *>(expr);		return set_consisting_of_a_single_one_element_vector<NonterminalExpression *>(&expr_pr);	}	else	{		assert(false);		return set<vector<NonterminalExpression *> >();	}}int find_creator_or_updater_in_rule(const RuleData &rule, int pos){	assert(rule.body.size()>pos);	for(int i=pos; i>=0; i--)		if(rule.body[i].is_nonterminal())		{			NonterminalData &nonterminal=data.nonterminals[rule.body[i].nonterminal_number()];			if(nonterminal.category==NonterminalData::CREATOR || nonterminal.category==NonterminalData::UPDATER)				return i;		}	return -1;}// 'requested_rules' is a set of all rules already made for this alternative of// this nonterminal. 'rule' is the current rule; its body is incomplete. The// symbol returned by this function shall be appended to the end or rule body// by the caller.// TO DO: if there are no symbols for this creator or updater to process, then// remove it.SymbolNumber make_creator_or_updater_or_use_existing_one(const set<RuleData> &requested_rules, RuleData &rule, int last1){	NonterminalExpressionCreate *expr_create=dynamic_cast<NonterminalExpressionCreate *>(rule.expr_body[last1]);	NonterminalExpressionUpdate *expr_update=dynamic_cast<NonterminalExpressionUpdate *>(rule.expr_body[last1]);	assert((expr_create!=NULL) ^ (expr_update!=NULL));#ifdef DEBUG_MAKE_CREATOR_OR_UPDATER_OR_USE_EXISTING_ONE	cout << "make_creator_or_updater_or_use_existing_one(): " << rule.in_printable_form() << "\n";#endif	// Looking for an existing creator or updater that could be used here.	int first1;	if(expr_create)		first1=0;	else if(expr_update)	{		first1=find_creator_or_updater_in_rule(rule, last1-1);		assert(first1!=-1);	}	else		assert(false);#ifdef DEBUG_MAKE_CREATOR_OR_UPDATER_OR_USE_EXISTING_ONE	cout << "\tfirst1=" << first1 << ", last1=" << last1 << "\n";#endif	for(set<RuleData>::const_iterator p=requested_rules.begin(); p!=requested_rules.end(); p++)	{		if(rule.an!=p->an)			continue;		int last2=-1;		for(int i=0; i<p->expr_body.size(); i++)			if(p->expr_body[i]==rule.expr_body[last1])			{				last2=i;				break;			}		if(last2==-1)			continue;	#ifdef DEBUG_MAKE_CREATOR_OR_UPDATER_OR_USE_EXISTING_ONE		cout << "\tConsidering " << data.full_symbol_name(p->body[last2], false)			<< " in rule " << p->in_printable_form() << "\n";	#endif		int first2;		if(expr_create)			first2=0;		else if(expr_update)		{			first2=find_creator_or_updater_in_rule(*p, last2-1);			assert(first2!=-1);		}		else			assert(false);	#ifdef DEBUG_MAKE_CREATOR_OR_UPDATER_OR_USE_EXISTING_ONE		cout << "\t\tfirst2=" << first2 << ", last2=" << last2 << "\n";	#endif		if(last1-first1 != last2-first2)		{		#ifdef DEBUG_MAKE_CREATOR_OR_UPDATER_OR_USE_EXISTING_ONE			cout << "\t\tLength mismatch.\n";		#endif			continue;		}		bool ok_flag=true;		for(int i=last1-1, j=last2-1; i>=first1; i--, j--)			if(rule.expr_body[i]!=p->expr_body[j])			{			#ifdef DEBUG_MAKE_CREATOR_OR_UPDATER_OR_USE_EXISTING_ONE				cout << "\t\tMismatch in position (" << i << ", " << j << ")\n";			#endif				ok_flag=false;				break;			}		if(ok_flag)		{			#ifdef DEBUG_MAKE_CREATOR_OR_UPDATER_OR_USE_EXISTING_ONE				cout << "\t\tReusing " << data.full_symbol_name(p->body[last2], false) << "\n";			#endif			return p->body[last2];		}	}	// Creating a new creator or updater.	int symbol_nn;	if(expr_create)	{		if(expr_create->creator_nn.size()==0)			expr_create->local_creator_number=++data.nonterminals[rule.nn].number_of_creators;		symbol_nn=make_invoker_or_creator_or_updater(rule.nn, rule.an, expr_create->local_creator_number, expr_create->creator_nn.size()+1, NonterminalData::CREATOR, expr_create->kw);		expr_create->creator_nn.push_back(symbol_nn);	}	else if(expr_update)	{		if(expr_update->updater_nn.size()==0)			expr_update->local_updater_number=++data.nonterminals[rule.nn].number_of_updaters;		symbol_nn=make_invoker_or_creator_or_updater(rule.nn, rule.an, expr_update->local_updater_number, expr_update->updater_nn.size()+1, NonterminalData::UPDATER, expr_update->kw);		expr_update->updater_nn.push_back(symbol_nn);	}	else		assert(false);#ifdef DEBUG_MAKE_CREATOR_OR_UPDATER_OR_USE_EXISTING_ONE	cout << "\t\tCreating nonterminal " << data.nonterminals[symbol_nn].name << "\n";#endif	return SymbolNumber::for_nonterminal(symbol_nn);}bool operator <(const RuleData &r1, const RuleData &r2){	// the order of comparison is really important.	if(r1.nn<r2.nn) return true;	if(r1.nn>r2.nn) return false;	if(r1.body<r2.body) return true;	if(r1.body>r2.body) return false;	if(r1.an<r2.an) return true;	if(r1.an>r2.an) return false;	if(r1.expr_body<r2.expr_body) return true;	if(r1.expr_body>r2.expr_body) return false;	return r1.precedence_expressions<r2.precedence_expressions;}void build_create_and_update_operator_locations_and_source_rules_database(){//	cout << "build_creator_and_updater_source_rules_database()\n";	for(int i=0; i<data.rules.size(); i++)	{		RuleData &rule=data.rules[i];		for(int j=0; j<rule.body.size(); j++)		{			SymbolNumber sn=rule.body[j];			if(sn.is_nonterminal())			{				NonterminalData::Category category=data.nonterminals[sn.nonterminal_number()].category;				if(category==NonterminalData::CREATOR || category==NonterminalData::UPDATER)				{				//	cout << data.symbol_name(sn) << " in " << rule.in_printable_form() << "\n";					rule.create_and_update_operator_locations.push_back(j);				}				if(category==NonterminalData::CREATOR)				{					int nn=sn.nonterminal_number();					AlternativeData &alternative=data.access_alternative(rule.nn, rule.an);					if(find(alternative.creator_nn.begin(), alternative.creator_nn.end(), nn)==alternative.creator_nn.end())						alternative.creator_nn.push_back(nn);					if(rule.creator_nn==-1)						rule.creator_nn=nn;					else if(rule.creator_nn!=nn)					{						cout << "\n\n\t\tUnexpected internal error:\n\n";						cout << "Found " << data.nonterminals[nn].name							<< " in rule " << rule.in_printable_form()							<< ", " << data.nonterminals[rule.creator_nn].name							<< " expected.\n";						assert(false);					}				}				if(data.nonterminals[sn.nonterminal_number()].is_ancillary)				{					data.nonterminals[sn.nonterminal_number()].rules_where_ancillary_symbol_is_used.push_back(i);				}			}		}	}}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?