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

📄 process.cpp.svn-base

📁 Complete support for EBNF notation; Object-oriented parser design; C++ output; Deterministic bottom-
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
				{					triad<ClassHierarchy::Class *, int, int> cnr=nonterminal.type->find_data_member_in_direct_relatives(name_we_shall_use.c_str());					if(cnr.first)					{						// I think this can be replaced by						// 'already_processed' data member						// of type vector<DataMember *> in						// ProcDataII.						cout << "Unable to generate data member " << name_we_shall_use							<< " in class " << nonterminal.type->get_full_name()							<< " for " << data.full_symbol_name(expr_s.sn, false) << " at ";						t->print_location(cout);						cout << ", because identifier " << name_we_shall_use << " is already in use.\n";						flag=false;						continue;					}					ClassHierarchy::DataMember *new_data_member=new ClassHierarchy::DataMember;					new_data_member->name=name_we_shall_use;					new_data_member->was_implicitly_declared=prototype_data_member->was_implicitly_declared;					new_data_member->declared_at=prototype_data_member->declared_at;					new_data_member->number_of_nested_iterations=iteration_depth-i-1;					new_data_member->type=type_we_shall_use;					if(i>0)					{						new_data_member->senior=expr_s.data_members_in_bodies[i-1];						new_data_member->senior_rests_in_a_body=true;					}					else					{						new_data_member->senior=prototype_data_member;						new_data_member->senior_rests_in_a_body=false;					}				#ifdef DEBUG_DATA_MEMBERS_IN_BODIES					cout << "\n\t\tmaking dm " <<  new_data_member->name << " in " << nonterminal.type->get_full_name()						<< " (senior " << new_data_member->senior->get_full_name() << ").\n";				#endif					classes.put_data_member_to_class(new_data_member, nonterminal.type);					expr_s.data_members_in_bodies.push_back(new_data_member);					proc_data.data_members_already_processed[make_pair(prototype_data_member, sn.nonterminal_number())]=&expr_s;				}			}			else				assert(i==iteration_depth-1);		}		return flag;	}	else if(typeid(*expr)==typeid(NonterminalExpressionMemberName))	{		NonterminalExpressionMemberName &expr_mn=*dynamic_cast<NonterminalExpressionMemberName *>(expr);		return process_expression_proc_ii(expr_mn.expr, proc_data);	}	else if(typeid(*expr)==typeid(NonterminalExpressionCreate))	{		NonterminalExpressionCreate &expr_create=*dynamic_cast<NonterminalExpressionCreate *>(expr);		proc_data.make_operator=&expr_create;		return true;	}	else if(typeid(*expr)==typeid(NonterminalExpressionUpdate))		return true;	else if(typeid(*expr)==typeid(NonterminalExpressionConnectUp))		return true;	else if(typeid(*expr)==typeid(NonterminalExpressionCode))		return true;	else if(typeid(*expr)==typeid(NonterminalExpressionPrecedence))		return true;	else	{		assert(false);		return false;	}}bool process_terminal_type_declaration(TerminalData &terminal, NonterminalTypeExpression *type){	if(type)	{		Terminal *t1=type->name;		if(!identifier_contains_no_hyphens(t1))			return false;		Terminal *t2=type->base_name;		ClassHierarchy::Class *previous_declaration=classes.find(t1->text);		ClassHierarchy::Class *base_class=(t2 ? classes.find(t2->text) : classes.terminal);		if(previous_declaration)		{			cout << "Class " << t1->text << ", ";			previous_declaration->print_where_it_was_declared(cout);			cout << ", cannot be used as a class for terminal " << terminal.name << " at ";			t1->print_location(cout);			cout << ".\n";			return false;		}		if(!base_class)		{			report_undefined_base_class(cout, t2);			return false;		}		if(!base_class->is_abstract || !base_class->is_derivative_of_terminal || base_class->is_a_built_in_template)		{			cout << "Class " << t2->text << ", ";			base_class->print_where_it_was_declared(cout);			cout << ", cannot be used as a base class for " << t1->text << " at ";			t2->print_location(cout);			cout << ": either Terminal or an abstract derivative of Terminal is required.\n";			return false;		}		terminal.type=new ClassHierarchy::Class(t1->text, base_class, NULL);		terminal.type->declared_at=t1;	}	else	{		string class_name=default_terminal_class_name(terminal.name);		if(!class_name.size())		{			cout << "Unable to generate default class name for terminal " << terminal.name << " at ";			terminal.declaration->print_location(cout);			cout << ".\n";			return false;		}		ClassHierarchy::Class *previous_declaration=classes.find(class_name.c_str());		if(previous_declaration)		{			cout << "Unable to generate default class name for terminal " << terminal.name << " at ";			terminal.declaration->print_location(cout);			cout << ", because the name " << class_name << " is already in use";			if(previous_declaration->declared_at)			{				cout << " (it was ";				previous_declaration->print_where_it_was_declared(cout);				cout << ")";			}			cout << ".\n";			return false;		}		terminal.type=new ClassHierarchy::Class(class_name, classes.terminal, NULL);		terminal.type->was_implicitly_declared=true;		terminal.type->declared_at=terminal.declaration;	}	terminal.type->is_abstract=false;	terminal.type->assigned_to=SymbolNumber::for_terminal(data.terminals.size());	return true;}bool process_nonterminal_type_declaration(int nn, NonterminalTypeExpression *type){	NonterminalData &nonterminal=data.nonterminals[nn];	ClassHierarchy::Class *default_base_class;	if(nonterminal.category==NonterminalData::EXTERNAL)	{		assert(("fix me!", false));		default_base_class=classes.wrapper;	}	else		default_base_class=classes.nonterminal;	if(type)	{		Terminal *t1=type->name;		if(!identifier_contains_no_hyphens(t1))			return false;		Terminal *t2=type->base_name;		ClassHierarchy::Class *previous_declaration=classes.find(t1->text);		ClassHierarchy::Class *base_class=(t2 ? classes.find(t2->text) : default_base_class);		if(previous_declaration)		{			cout << "Class " << t1->text << ", ";			previous_declaration->print_where_it_was_declared(cout);			cout << ", cannot be used as a class for nonterminal " << nonterminal.name << " at ";			t1->print_location(cout);			cout << ".\n";			return false;		}		if(!base_class)		{			report_undefined_base_class(cout, t2);			return false;		}		if(!base_class->is_abstract || !base_class->is_derivative_of_nonterminal || base_class->is_a_built_in_template)		{			cout << "Class " << t2->text << ", ";			base_class->print_where_it_was_declared(cout);			cout << ", cannot be used as a base class for " << t1->text << " at ";			t2->print_location(cout);			cout << ": either Nonterminal or an abstract derivative of Nonterminal is required.\n";			return false;		}		nonterminal.type=new ClassHierarchy::Class(t1->text, base_class, NULL);		nonterminal.type->declared_at=t1;	}	else	{		string class_name=default_nonterminal_class_name(nonterminal.name);		assert(class_name.size());		ClassHierarchy::Class *previous_declaration=classes.find(class_name.c_str());		if(previous_declaration)		{			cout << "Unable to generate default class name for nonterminal " << nonterminal.name << " at ";			nonterminal.declaration->print_location(cout);			cout << ", because the name " << class_name << " is already in use";			if(previous_declaration->declared_at)			{				cout << " (it was ";				previous_declaration->print_where_it_was_declared(cout);				cout << ")";			}			cout << ".\n";			return false;		}		nonterminal.type=new ClassHierarchy::Class(class_name, default_base_class, NULL);		nonterminal.type->was_implicitly_declared=true;		nonterminal.type->declared_at=nonterminal.declaration;	}	nonterminal.type->is_abstract=false;	nonterminal.type->assigned_to=SymbolNumber::for_nonterminal(nn);	return true;}ClassHierarchy::Class *process_external_type_declaration(NonterminalExternalTypeExpression *external_type, NonterminalData *nonterminal){	// if external_type!=NULL and nonterminal!=NULL:	//	explicit declaration of an external type for a nonterminal:	//	can appear both in 'nonterminal' and 'external' statements.	// if external_type!=NULL and nonterminal==NULL:	//	when does _that_ happen, I wonder?!	// if external_type==NULL and nonterminal!=NULL:	//	implicit declaration of an external type for a nonterminal:	//	currently only from withing 'external' statement.	assert(external_type!=NULL || nonterminal!=NULL);	if(external_type!=NULL && nonterminal==NULL)	{		// remove me!		cout << "Finally it happened!\n"			"If you ever see this message printed, please report the fact to the author!\n";		throw QuietException();	}	string s;	if(external_type)	{		try		{			s=serialize_external_type_expression(*external_type);		}		catch(TerminalId *)		{			return NULL;		}	}	else	{		cout << "process_external_type_declaration(): got NULL, using " << nonterminal->name << " as class name.\n";		s=nonterminal->name;	}	ClassHierarchy::Class *previous_declaration=classes.find(s.c_str());	if(!previous_declaration)	{		ClassHierarchy::Class *new_class=new ClassHierarchy::Class(s);		if(external_type)			new_class->declared_at=external_type->id;		else		{			new_class->declared_at=nonterminal->declaration;			new_class->was_implicitly_declared=true;		}		if(nonterminal)			nonterminal->external_type=new_class;		return new_class;	}	else if(!previous_declaration->is_internal)	{		if(nonterminal)			nonterminal->external_type=previous_declaration;		return previous_declaration;	}	else	{		cout << "Class " << s << ", ";		previous_declaration->print_where_it_was_declared(cout);		if(nonterminal)			cout << ", cannot be used as an external class for nonterminal " << nonterminal->name << " at ";		else			cout << ", cannot be used as external class at ";		external_type->id->print_location(cout);		cout << ".\n";		return NULL;	}}bool process_alternative_type_declaration(AlternativeData &alternative, NonterminalData &nonterminal, int alternative_number, NonterminalTypeExpression *type){	if(!nonterminal.type) return false;	assert(nonterminal.type->nonterminal_class_category==ClassHierarchy::Class::BASE);	if(type)	{		Terminal *t1=type->name;		if(!identifier_contains_no_hyphens(t1))			return false;		Terminal *t2=type->base_name;		ClassHierarchy::Class *previous_declaration=classes.find(t1->text);		ClassHierarchy::Class *base_class=(t2 ? classes.find(t2->text) : nonterminal.type);		if(previous_declaration)		{			cout << "Class " << t1->text << ", ";			previous_declaration->print_where_it_was_declared(cout);			cout << ", cannot be used as a class for the "				<< english2_itoa(alternative_number+1, false) << " alternative ";			cout << "of nonterminal " << nonterminal.name << " at ";			t1->print_location(cout);			cout << ".\n";			return false;		}		if(!base_class)		{			report_undefined_base_class(cout, t2);			return false;		}		// checking whether base_class is a derivative of nonterminal.type		bool flag=false;		for(ClassHierarchy::Class *m=base_class; m!=NULL; m=m->ancestor)			if(m==nonterminal.type)			{				flag=true;				break;			}		if(!flag || (!base_class->nonterminal_class_category==ClassHierarchy::Class::ABSTRACT			&& !base_class->nonterminal_class_category==ClassHierarchy::Class::BASE))		{			cout << "Class " << t2->text << ", ";			base_class->print_where_it_was_declared(cout);			cout << ", cannot be used as a base class for " << t1->text << " at ";			t2->print_location(cout);			cout << ": either " << nonterminal.type->name << " or an abstract derivative of ";			cout << nonterminal.type->name << " is required.\n";			return false;		}		alternative.type=new ClassHierarchy::Class(t1->text, base_class, NULL);		alternative.type->declared_at=t1;	}	else	{		string class_name=default_alternative_class_name(nonterminal.type->name, alternative_number);		ClassHierarchy::Class *previous_declaration=classes.find(class_name.c_str());		if(previous_declaration)		{			cout << "Unable to generate default class name for the ";			cout << english2_itoa(alternative_number+1, false)				<< " alternative of nonterminal "				<< nonterminal.name << " at ";			nonterminal.declaration->print_location(cout);			cout << ", because the name " << class_name << " is already in use";			if(previous_declaration->declared_at)			{				cout << " (it was ";				previous_declaration->print_where_it_was_declared(cout);				cout << ")";			}			cout << ".\n";			return false;		}

⌨️ 快捷键说明

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