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

📄 process.cpp.svn-base

📁 Complete support for EBNF notation; Object-oriented parser design; C++ output; Deterministic bottom-
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
		alternative.type=new ClassHierarchy::Class(class_name, nonterminal.type, NULL);		alternative.type->was_implicitly_declared=true;		alternative.type->declared_at=alternative.declaration;	}	alternative.type->is_abstract=false;	alternative.type->assigned_to=nonterminal.type->assigned_to;	alternative.type->nonterminal_class_category=ClassHierarchy::Class::SPECIFIC;	alternative.type->nonterminal_alternative_number=alternative_number;	return true;}ClassHierarchy::Class *process_standalone_type_declaration(NonterminalTypeExpression *type){	assert(type);	if(!identifier_contains_no_hyphens(type->name))		return NULL;	ClassHierarchy::Class *previous_declaration=classes.find(type->name->text);	if(previous_declaration)	{		cout << "Class " << previous_declaration->name << ", ";		previous_declaration->print_where_it_was_declared(cout);		cout << ", cannot be redeclared at ";		type->name->print_location(cout);		cout << ".\n";		return NULL;	}	if(!type->base_name)	{		cout << "Class " << type->name->text << " requires an explicit base class at ";		type->name->print_location(cout);		cout << ".\n";		return NULL;	}	ClassHierarchy::Class *base_class=classes.find(type->base_name->text);	if(!base_class)	{		report_undefined_base_class(cout, type->base_name);		return NULL;	}	if(!base_class->assigned_to && base_class->is_internal && !base_class->is_a_built_in_template)	{		ClassHierarchy::Class *m=new ClassHierarchy::Class(type->name->text, base_class, NULL);		m->declared_at=type->name;		m->is_abstract=true;		return m;	}	else if(base_class->assigned_to.is_nonterminal() &&		(base_class->nonterminal_class_category==ClassHierarchy::Class::UNKNOWN ||		base_class->nonterminal_class_category==ClassHierarchy::Class::BASE ||		base_class->nonterminal_class_category==ClassHierarchy::Class::ABSTRACT))	{//		NonterminalData &nonterminal=data.nonterminals[base_class->assigned_to.nonterminal_number()];		if(base_class->nonterminal_class_category==ClassHierarchy::Class::UNKNOWN)			base_class->nonterminal_class_category=ClassHierarchy::Class::BASE;		ClassHierarchy::Class *m=new ClassHierarchy::Class(type->name->text, base_class, NULL);		m->nonterminal_class_category=ClassHierarchy::Class::ABSTRACT;		m->declared_at=type->name;		m->assigned_to=base_class->assigned_to;	//	m->is_abstract=false; // ???????????????????????????????		m->is_abstract=true;		return m;	}	else	{		cout << "Class " << base_class->name << ", ";		base_class->print_where_it_was_declared(cout);		cout << ", cannot be used as a base class for abstract class " << type->name->text << " at ";		type->name->print_location(cout);		cout << ".\n";		return NULL;	}}void print_a_number_of_terminal_locations(ostream &os, vector<Terminal *> &a, char *word){	for(int k=0; k<a.size(); k++)	{		if(k) os << (k<a.size()-1 ? ", " : " and ");		os << word << " ";		a[k]->print_location(os);	}}// id -> TerminalId, "for" -> TerminalFor, ";" -> TerminalSemicolon etc.string default_terminal_class_name(const char *s){	static std::map<const char *, const char *, NullTerminatedStringCompare> database;	if(database.begin()==database.end())	{//		cout << "default_terminal_class_name(): called for the first time, building database.\n";		database["!"]="ExclamationMark";		database["@"]="CommercialAt";		database["#"]="Sharp";		database["$"]="Dollar";		database["%"]="Percent";		database["^"]="Circumflex";		database["&"]="Ampersand";		database["*"]="Asterisk";		database["("]="LeftParenthesis";		database[")"]="RightParenthesis";		database["["]="LeftBracket";		database["]"]="RightBracket";		database["{"]="LeftBrace";		database["}"]="RightBrace";		database["+"]="Plus";		database["-"]="Minus";		database["++"]="Increment";		database["--"]="Decrement";		database[":"]="Colon";		database[";"]="Semicolon";		database[","]="Comma";		database["."]="Period";		database["..."]="Ellipsis";		database["<"]="LessThan";		database[">"]="GreaterThan";		database["<="]="LessOrEqual";		database[">="]="GreaterOrEqual";		database["="]="Equal";		database["!="]="NotEqual";		database[":="]="Assign";		database["+="]="SumAssign";		database["-="]="DifferenceAssign";		database["*="]="ProductAssign";		database["/="]="QuotientAssign";		database["/"]="Slash";		database["\\"]="Backslash";		database["?"]="QuestionMark";		database["\x22"]="QuotationMark";		database["'"]="Apostrophe";		database["_"]="Underscore";		database["~"]="Tilde";		database["->"]="Arrow";	}	if(s[0]=='"')	{		int l=strlen(s);		assert(s[l-1]=='"');		if(l==2)			return string("");		string contents(s+1, s+l-1);		map<const char *, const char *, NullTerminatedStringCompare>::iterator p=database.find(contents.c_str());		if(p!=database.end())			return string("Terminal")+string((*p).second);		for(string::iterator p=contents.begin(); p!=contents.end(); p++)			if(!(isalpha(*p) || isdigit(*p) || *p=='_' || *p=='-'))				return string("");		return string("Terminal")+default_naming_proc(contents.c_str());	}	else		return string("Terminal")+default_naming_proc(s);}string default_nonterminal_class_name(const char *s){	return string("Nonterminal")+default_naming_proc(s);}string default_alternative_class_name(const string &s, int alternative_number){	char c=s[s.size()-1];	if((c>='a' && c<='z') || c=='_')		return s+roman_itoa(alternative_number+1, true);	else		return s+string("_")+roman_itoa(alternative_number+1, true);}string default_naming_proc(const char *s){	string result;	bool capital_flag=true;	for(int i=0; s[i]; i++)		if((s[i]>='A' && s[i]<='Z') || isdigit(s[i]))		{			result+=s[i];			capital_flag=false;		}		else if(s[i]>='a' && s[i]<='z')		{			result+=char(s[i]-(capital_flag ? 'a'-'A' : 0));			capital_flag=false;		}		else if(s[i]=='_' || s[i]=='-')			capital_flag=true;	return result;}void report_undefined_base_class(ostream &os, Terminal *t){	assert(t);	os << "Undefined base class " << t->text << " at ";	t->print_location(os);	os << ".\n";}bool identifier_contains_no_hyphens(Terminal *t){	for(int i=0; t->text[i]; i++)		if(t->text[i]=='-')		{			cout << "Identifier at ";			t->print_location(cout);			cout << " may not contain hyphens.\n";			return false;		}	return true;}struct ClassNamePrinter : binary_function<ostream &, const ClassHierarchy::Class *, ostream &>{	ostream &operator ()(ostream &os, const ClassHierarchy::Class *c)	{		os << c->name;	}};ClassHierarchy::Class *process_scope_in_member_name_specification(Terminal *scope, Terminal *id, const pair<int, int> &location){	ClassHierarchy::Class *class_assigned_to_host_nonterminal=data.get_class_assigned_to_alternative(location.first, location.second);	assert(class_assigned_to_host_nonterminal);	if(!scope) return class_assigned_to_host_nonterminal;	bool strange_coincidence=!strcmp(scope->text, data.nonterminals[location.first].name);	ClassHierarchy::Class *this_class;	if(strange_coincidence)		this_class=data.nonterminals[location.first].type;	else		this_class=classes.find(scope->text);	if(!this_class)	{		cout << "Undefined class " << scope->text << " at ";		scope->print_location(cout);		cout << ".\n";		return NULL;	}	// this_class should be an ancestor of class_assigned_to_host_nonterminal.	bool found=false;	for(ClassHierarchy::Class *c=class_assigned_to_host_nonterminal; c; c=c->ancestor)		if(c==this_class)		{			found=true;			break;		}	if(found)		return this_class;	else	{		vector<ClassHierarchy::Class *> v;		for(ClassHierarchy::Class *c=class_assigned_to_host_nonterminal; c; c=c->ancestor)			v.push_back(c);		cout << "Class " << this_class->name << " cannot be used to store variable ";		cout << id->text << " at ";		scope->print_location(cout);		cout << ": expecting ";		custom_print(cout, v.begin(), v.end(), ClassNamePrinter(), ", ", " or ");		cout << ".\n";		return NULL;	}}ClassHierarchy::DataMember *process_single_data_member_declaration(Terminal *scope, Terminal *name, int nn, int an, int number_of_iterations){	ClassHierarchy::Class *scope_class=process_scope_in_member_name_specification(scope, name, make_pair(nn, an));	if(!scope_class) return NULL;	assert(name);	char *s=name->text;	triad<ClassHierarchy::Class *, int, int> cnr=scope_class->find_data_member_in_direct_relatives(s);	if(!cnr.first)	{		// creating a new data member.		ClassHierarchy::DataMember *new_data_member=new ClassHierarchy::DataMember;		new_data_member->name=s;		new_data_member->type=NULL;		new_data_member->was_implicitly_declared=false;		new_data_member->declared_at=name;		new_data_member->internal_type_if_there_is_an_external_type=NULL;		new_data_member->number_of_nested_iterations=number_of_iterations;		classes.put_data_member_to_class(new_data_member, scope_class);		return new_data_member;	}	else if(!cnr.third || !scope)	{		// attempting to use an existing data member.		ClassHierarchy::DataMember *data_member=cnr.first->data_members[cnr.second];		if(data_member->better_not_to_use_it_for_ordinary_symbols)		{			cout << "Warning: usage of built-in data member "				<< data_member->name << " at ";			name->print_location(cout);			cout << " would most probably lead to parser malfunction.\n";		}	#if 0		if(data_member->number_of_nested_iterations!=number_of_iterations)		{			cout << "Data member ";			cout << data_member->get_full_name() << ", ";			data_member->print_where_it_was_declared(cout);			cout << ", cannot be used at ";			name->print_location(cout);			cout << ", because " << data_member->number_of_nested_iterations << ", " << number_of_iterations << "\n";			return NULL;		}		else	#endif		data_member->number_of_nested_iterations=max(data_member->number_of_nested_iterations, number_of_iterations);		return data_member;	}	else	{		cout << "Unable to create data member ";		cout << scope_class->name << "::" << s;		cout << " at ";		name->print_location(cout);		cout << ", because a there is a member bearing the same name (";		cnr.first->data_members[cnr.second]->print_where_it_was_declared(cout);		cout << ") in class " << cnr.first->name << ", which is ";		if(cnr.third==-1)			cout << "an ancestor of ";		else			cout << "a descendant of ";		cout << scope_class->name << ".\n";		return NULL;	}}string generate_default_data_member_name(int n){	char s[20];	sprintf(s, "a%u", n);	return string(s);}string serialize_external_type_expression(NonterminalExternalTypeExpression &expr){	string result;	if(typeid(*expr.id)==typeid(TerminalId))	{		if(!identifier_contains_no_hyphens(expr.id))			throw expr.id;		result=expr.id->text;	}	else if(typeid(*expr.id)==typeid(TerminalString))		result=string(expr.id->text+1, expr.id->text+strlen(expr.id->text)-1);	else		assert(false);	if(expr.template_arguments.size())	{		result+="<";		for(int i=0; i<expr.template_arguments.size(); i++)		{			if(i) result+=", ";			result+=serialize_external_type_expression(*expr.template_arguments[i]);		}		if(result[result.size()-1]!='>')			result+=">";		else			result+=" >";	}	if(typeid(*expr.expr1)==typeid(NonterminalExt

⌨️ 快捷键说明

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