⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 process.cpp.svn-base

📁 Complete support for EBNF notation; Object-oriented parser design; C++ output; Deterministic bottom-
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
				}				else					alternative.type=NULL;			//	cout << "pushing alternative: " << (void *)rule_statement.right << "\n";				nonterminal.alternatives.push_back(alternative);			}			else				assert(false);		}		else if(typeid(*data.S->statements[i])==typeid(NonterminalPrecedenceStatement))		{			// precedence statements are dealt with in precedence.cpp		}		else if(typeid(*data.S->statements[i])==typeid(NonterminalOptionStatement))		{			bool result=process_option_statement(*dynamic_cast<NonterminalOptionStatement *>(data.S->statements[i]));			if(!result)				flag=false;		}		else if(typeid(*data.S->statements[i])==typeid(NonterminalStartStatement))		{			NonterminalStartStatement &start_statement=dynamic_cast<NonterminalStartStatement&>(*data.S->statements[i]);			start_nonterminal_name =  start_statement.id->text;		}		else if(typeid(*data.S->statements[i])==typeid(NonterminalInvalidStatement))			flag=false;		else			assert(false);	}	if(!flag) return false;	for(int i=0; i<data.nonterminals.size(); i++)	{		NonterminalData &nonterminal=data.nonterminals[i];		if(nonterminal.is_ancillary) continue;		if(nonterminal.name==start_nonterminal_name)			data.start_nonterminal_number=i;		if(!nonterminal.alternatives.size() && !nonterminal.type->descendants.size())		{			assert(nonterminal.type->nonterminal_class_category==ClassHierarchy::Class::UNKNOWN);			cout << "Applying a doubtful fix to nonterminal " << nonterminal.name << "\n";			nonterminal.type->nonterminal_class_category=ClassHierarchy::Class::SINGLE;		}	}	return true;}bool process_expressions(){	bool flag=true;	for(int i=0; i<data.nonterminals.size(); i++)	{		if(data.nonterminals[i].is_ancillary) continue;		for(int j=0; j<data.nonterminals[i].alternatives.size(); j++)		{			NonterminalData &nonterminal=data.nonterminals[i]; // this declaration cannot be moved one loop level above, because process_expressions_proc can add nonterminals.			AlternativeData &alternative=nonterminal.alternatives[j];		#ifdef DEBUG			cout << i << ", " <<j << ": alternative.expr = " << (void *)alternative.expr << "\n";		#endif			assert(alternative.expr);			ProcessExpressionProcData proc_data(i, j);			if(!process_expression_proc(alternative.expr, proc_data))				flag=false;		}	}	if(!flag) return false;	map<int, vector<NonterminalExpressionSymbol *> > nonterminals_that_cannot_be_connected_up;	for(int i=0; i<data.nonterminals.size(); i++)	{		NonterminalData &nonterminal=data.nonterminals[i];		if(nonterminal.is_ancillary) continue;		for(int j=0; j<nonterminal.alternatives.size(); j++)		{			AlternativeData &alternative=nonterminal.alternatives[j];			assert(alternative.expr);			ProcessExpressionProcIIData proc_data(i, j, nonterminals_that_cannot_be_connected_up);			if(!process_expression_proc_ii(alternative.expr, proc_data))				flag=false;		}	}	// A -> a create b C;	// B -> a b C;			// create operator required here.	// C -> c connect_up d;	for(map<int, vector<NonterminalExpressionSymbol *> >::const_iterator p=nonterminals_that_cannot_be_connected_up.begin(); p!=nonterminals_that_cannot_be_connected_up.end(); p++)	{		NonterminalData &nonterminal=data.nonterminals[p->first];		vector<Terminal *> v1, v2;		for(int i=0; i<nonterminal.requests_to_connect_up.size(); i++)			v1.push_back(nonterminal.requests_to_connect_up[i]->kw);		for(int i=0; i<p->second.size(); i++)			v2.push_back(p->second[i]->symbol);		cout << "Using connect_up operator ";		print_a_number_of_terminal_locations(cout, v1, "at");		cout << " requires create operator before any reference to "			<< "nonterminal " << nonterminal.name			<< "; appearance" << (v2.size()==1 ? "" : "s")			<< " of " << nonterminal.name << " ";		print_a_number_of_terminal_locations(cout, v2, "at");		cout << " " << (v2.size()==1 ? "is" : "are")			<< " not preceded by create.\n";		flag=false;	}	return flag;}bool process_expression_proc(NonterminalExpression *expr, ProcessExpressionProcData &proc_data){	if(typeid(*expr)==typeid(NonterminalExpressionDisjunction))	{		NonterminalExpressionDisjunction &expr_d=*dynamic_cast<NonterminalExpressionDisjunction *>(expr);		bool iabc_backup=proc_data.inside_anything_but_concatenation;		proc_data.inside_anything_but_concatenation=true;		bool result1=process_expression_proc(expr_d.expr1, proc_data);		bool result2=process_expression_proc(expr_d.expr2, proc_data);		proc_data.inside_anything_but_concatenation=iabc_backup;		return result1 && result2;	}	else if(typeid(*expr)==typeid(NonterminalExpressionConjunction))	{		NonterminalExpressionConjunction &expr_c=*dynamic_cast<NonterminalExpressionConjunction *>(expr);		bool iabc_backup=proc_data.inside_anything_but_concatenation;		proc_data.inside_anything_but_concatenation=true;		process_expression_proc(expr_c.expr1, proc_data);		cout << "Conjunction, used at ";		expr_c.op->print_location(cout);		cout << ", is not supported.\n";		process_expression_proc(expr_c.expr2, proc_data);		proc_data.inside_anything_but_concatenation=iabc_backup;		return false;	}	else if(typeid(*expr)==typeid(NonterminalExpressionConcatenation))	{		NonterminalExpressionConcatenation &expr_cat=*dynamic_cast<NonterminalExpressionConcatenation *>(expr);		bool result1=process_expression_proc(expr_cat.expr1, proc_data);		bool result2=process_expression_proc(expr_cat.expr2, proc_data);		return result1 && result2;	}	else if(typeid(*expr)==typeid(NonterminalExpressionComplement))	{		NonterminalExpressionComplement &expr_com=*dynamic_cast<NonterminalExpressionComplement *>(expr);		cout << "Complement, used at ";		expr_com.op->print_location(cout);		cout << ", is not supported.\n";		bool iabc_backup=proc_data.inside_anything_but_concatenation;		proc_data.inside_anything_but_concatenation=true;		process_expression_proc(expr_com.expr, proc_data);		proc_data.inside_anything_but_concatenation=iabc_backup;		return false;	}	else if(typeid(*expr)==typeid(NonterminalExpressionOmittable))	{		NonterminalExpressionOmittable &expr_om=*dynamic_cast<NonterminalExpressionOmittable *>(expr);		bool iabc_backup=proc_data.inside_anything_but_concatenation;		proc_data.inside_anything_but_concatenation=true;		bool result=process_expression_proc(expr_om.expr, proc_data);		proc_data.inside_anything_but_concatenation=iabc_backup;		return result;	}	else if(typeid(*expr)==typeid(NonterminalExpressionInParentheses))	{		NonterminalExpressionInParentheses &expr_p=*dynamic_cast<NonterminalExpressionInParentheses *>(expr);		bool result=process_expression_proc(expr_p.expr, proc_data);		return result;	}	else if(typeid(*expr)==typeid(NonterminalExpressionIteration))	{		NonterminalExpressionIteration &expr_it=*dynamic_cast<NonterminalExpressionIteration *>(expr);		if(proc_data.member_expression)		{			cout << "Warning: member name specification at ";			proc_data.member_expression->t->print_location(cout);			cout << " has no effect inside iteration at ";			expr_it.sign->print_location(cout);			cout << ".\n";		}		NonterminalMemberExpression *backup=proc_data.member_expression;		proc_data.member_expression=NULL;		proc_data.number_of_nested_iterations++;		bool iabc_backup=proc_data.inside_anything_but_concatenation;		proc_data.inside_anything_but_concatenation=true;		bool result=process_expression_proc(expr_it.expr, proc_data);		proc_data.inside_anything_but_concatenation=iabc_backup;		proc_data.number_of_nested_iterations--;		proc_data.member_expression=backup;		if(!result) return false;		expr_it.local_iterator_number=++proc_data.nonterminal().number_of_iterators;		expr_it.body_sn=make_body_symbol(expr_it.expr, proc_data.nn, proc_data.an, expr_it.local_iterator_number, 0, expr_it.sign);		expr_it.iterator_nn=make_single_iterator_symbol(expr_it.body_sn, proc_data.nn, proc_data.an, expr_it.local_iterator_number, expr_it.sign);		if(typeid(*expr_it.sign)==typeid(TerminalAsterisk))			expr_it.reflexive=true;		else if(typeid(*expr_it.sign)==typeid(TerminalPlus))			expr_it.reflexive=false;		else			assert(false);		return true;	}	else if(typeid(*expr)==typeid(NonterminalExpressionIterationPair))	{		NonterminalExpressionIterationPair &expr_it2=*dynamic_cast<NonterminalExpressionIterationPair *>(expr);		if(proc_data.member_expression)		{			cout << "Warning: member name specification at ";			proc_data.member_expression->t->print_location(cout);			cout << " has no effect inside iteration at ";			expr_it2.kw->print_location(cout);			cout << ".\n";		}		NonterminalMemberExpression *backup=proc_data.member_expression;		proc_data.member_expression=NULL;		proc_data.number_of_nested_iterations++;		bool iabc_backup=proc_data.inside_anything_but_concatenation;		proc_data.inside_anything_but_concatenation=true;		bool result1=process_expression_proc(expr_it2.expr1, proc_data);		bool result2=process_expression_proc(expr_it2.expr2, proc_data);		proc_data.inside_anything_but_concatenation=iabc_backup;		proc_data.number_of_nested_iterations--;		proc_data.member_expression=backup;		if(!result1 || !result2) return false;		expr_it2.local_iterator_number=++proc_data.nonterminal().number_of_iterators;		expr_it2.body1_sn=make_body_symbol(expr_it2.expr1, proc_data.nn, proc_data.an, expr_it2.local_iterator_number, 1, expr_it2.kw);		expr_it2.body2_sn=make_body_symbol(expr_it2.expr2, proc_data.nn, proc_data.an, expr_it2.local_iterator_number, 2, expr_it2.kw);		expr_it2.iterator_nn=make_pair_iterator_symbol(expr_it2.body1_sn, expr_it2.body2_sn, proc_data.nn, proc_data.an, expr_it2.local_iterator_number, expr_it2.kw);		return true;	}	else if(typeid(*expr)==typeid(NonterminalExpressionEpsilon))		return true;	else if(typeid(*expr)==typeid(NonterminalExpressionSymbol))	{		NonterminalExpressionSymbol &expr_s=*dynamic_cast<NonterminalExpressionSymbol *>(expr);		Terminal *t=expr_s.symbol;		int tn=data.find_terminal(t->text);		int nn=data.find_nonterminal(t->text);		assert(tn==-1 || nn==-1);		if(tn==-1 && nn==-1)		{			cout << "Undefined symbol " << t->text << " at ";			t->print_location(cout);			cout << ".\n";			return false;		}		proc_data.symbol_count++;		expr_s.number_of_iterations=proc_data.number_of_nested_iterations;		ClassHierarchy::Class *internal_class_for_this_symbol;		ClassHierarchy::Class *external_class_for_this_symbol;		if(tn!=-1)		{			if(tn==data.eof_terminal_number)			{				cout << "Warning: explicit use of end-of-file symbol at ";				t->print_location(cout);				cout << ".\n";			}			expr_s.sn=SymbolNumber::for_terminal(tn);			internal_class_for_this_symbol=data.terminals[tn].type;			external_class_for_this_symbol=NULL;		}		else if(nn!=-1)		{			NonterminalData &nonterminal=data.nonterminals[nn];			expr_s.sn=SymbolNumber::for_nonterminal(nn);			if(nonterminal.external_type)			{				internal_class_for_this_symbol=nonterminal.type;				external_class_for_this_symbol=nonterminal.external_type;			}			else			{				internal_class_for_this_symbol=nonterminal.type;				external_class_for_this_symbol=NULL;			}		}		assert(internal_class_for_this_symbol);		NonterminalMemberExpression *m_expr=proc_data.member_expression;		if(m_expr)			m_expr->number_of_affected_symbols++;		if(m_expr && m_expr->is_nothing)			return true;		if(!m_expr && data.variables.default_member_name_is_nothing)			return true;		if(!m_expr)		{			ClassHierarchy::Class *class_assigned_to_host_nonterminal=data.get_class_assigned_to_alternative(proc_data.nn, proc_data.an);			string s=generate_default_data_member_name(proc_data.symbol_count);			triad<ClassHierarchy::Class *, int, int> cnr=class_assigned_to_host_nonterminal->find_data_member_in_direct_relatives(s.c_str());			if(cnr.first)			{				cout << "Unable to generate default data member name for ";				cout << data.full_symbol_name(expr_s.sn, false) << " at ";				t->print_location(cout);				cout << ", because identifier " << s << " is already in use.\n";				return false;			}			ClassHierarchy::DataMember *new_data_member=new ClassHierarchy::DataMember;			new_data_member->name=s;			new_data_member->was_implicitly_declared=true;			new_data_member->declared_at=t;			new_data_member->number_of_nested_iterations=proc_data.number_of_nested_iterations;			if(external_class_for_this_symbol)			{				new_data_member->type=external_class_for_this_symbol;				new_data_member->internal_type_if_there_is_an_external_type=internal_class_for_this_symbol;			}			else			{				new_data_member->type=internal_class_for_this_symbol;				new_data_member->internal_type_if_there_is_an_external_type=NULL;			}			classes.put_data_member_to_class(new_data_member, class_assigned_to_host_nonterminal);			expr_s.data_member_i=new_data_member;			return true;		}		assert(m_expr);		/* What are we going to do is to unify data types.           */		/* Consider ( ... symbol ... ) = (member expression)         */		/* We have just read _symbol_, and we have access to the     */		/* previously read member expression.                        */		/* internal_class_for_this_symbol and external_class_... are */		/* properties of symbol that doesn't depend upon this        */		/* context. m_expr->everything are different properties of   */		/* the member expression. We have to modify data members     */		/* created by member expression so that they would become    */		/* capable of holding our symbol, while retaining all holding*/		/* capabilities they had before. */		// 6 cases to consider.		if(m_expr->i_specified && !m_expr->e_specified && !external_class_for_this_symbol)		{			// the most simple case: just unify the type data

⌨️ 快捷键说明

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