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

📄 codegen.cpp.svn-base

📁 Complete support for EBNF notation; Object-oriented parser design; C++ output; Deterministic bottom-
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
		fprintf(a, "\t\t\tif (m_debug)\n");		fprintf(a, "\t\t\t\tcout << \x22Shift \x22 << new_state << \x22\\n\x22;\n");		fprintf(a, "\t\t\t#endif\n");	}	fprintf(a, "\t\t\tsymbol_stack.push_back(%s);\n", ref_to_input_symbol);	fprintf(a, "\t\t\tstate_stack.push_back(new_state);\n");	if(!data.variables.input_queue) {		fprintf(a, "\t\t\tinput_symbol=%s;\n", data.variables.get_token_expression.c_str());		if (data.variables.generate_verbose_prints) {			fprintf(a, "\t\t\t#if WHALE_DEBUG != 0\n");			fprintf(a, "\t\t\tif (m_debug)\n");			fprintf(a, "\t\t\t\tcout << \x22read token \\x22\x22 << "					"input_symbol->symbol_name() << \x22\\x22\\n\x22;\n");			fprintf(a, "\t\t\t#endif\n");		}	}	else		fprintf(a, "\t\t\tinput_symbols.pop();\n");	fprintf(a, "\t\t}\n");	fprintf(a, "\t\telse if(lr_action.is_reduce())\n");	fprintf(a, "\t\t{\n");	fprintf(a, "\t\t\tint rule_number=lr_action.reduce_rule();\n");	if(data.variables.generate_verbose_prints) {		fprintf(a, "\t\t\t#if WHALE_DEBUG != 0\n");		fprintf(a, "\t\t\tif (m_debug)\n");		fprintf(a, "\t\t\t\tcout << \x22Reduce \x22 << rule_number << \x22\\n\x22;\n");		fprintf(a, "\t\t\t#endif\n");	}	fprintf(a, "\t\t\tint rule_length=rules[rule_number].length;\n");	fprintf(a, "\t\t\tint rule_start=symbol_stack.size()-rule_length;\n");	if(data.variables.generate_sanity_checks)		fprintf(a, "\t\t\tif(rule_start<0) throw logic_error(\x22Whale: rule_start<0\x22);\n");	fprintf(a, "\t\t\tNonterminal *new_symbol;\n");	fprintf(a, "\t\t\t\n");	fprintf(a, "\t\t\tswitch(rule_number)\n");	fprintf(a, "\t\t\t{\n");	for(int i=1 /* S->S' excluded */; i<data.rules.size(); i++)		generate_reduce_code(a, "\t\t\t", i);	if(data.variables.generate_sanity_checks)		fprintf(a, "\t\t\tdefault:\n"			"\t\t\t\tthrow logic_error(\x22Whale: Invalid rule number.\x22);\n");	fprintf(a, "\t\t\t}\n");	fprintf(a, "\t\t\t\n");	fprintf(a, "\t\t\tfor(int i=0; i<rule_length; i++)\n");	fprintf(a, "\t\t\t{\n");	fprintf(a, "\t\t\t\tsymbol_stack.pop_back();\n");	fprintf(a, "\t\t\t\tstate_stack.pop_back();\n");	fprintf(a, "\t\t\t}\n");	fprintf(a, "\t\t\tint nn=rules[rule_number].nn;\n");	fprintf(a, "\t\t\tsymbol_stack.push_back(new_symbol);\n");	fprintf(a, "\t\t\tint new_state=access_goto_table(state_stack[state_stack.size()-1], nn);\n");	if(data.variables.generate_verbose_prints) {		fprintf(a, "\t\t\t#if WHALE_DEBUG != 0\n");		fprintf(a, "\t\t\tif (m_debug)\n");		fprintf(a, "\t\t\t\tcout << \x22Goto \x22 << new_state << \x22\\n\x22;\n");		fprintf(a, "\t\t\t#endif\n");	}	fprintf(a, "\t\t\tstate_stack.push_back(new_state);\n");	fprintf(a, "\t\t}\n");	fprintf(a, "\t\telse if(lr_action.is_accept())\n");	fprintf(a, "\t\t{\n");	if(data.variables.generate_verbose_prints) {		fprintf(a, "\t\t\t#if WHALE_DEBUG != 0\n");		fprintf(a, "\t\t\tif (m_debug)\n");		fprintf(a, "\t\t\t\tcout << \x22" "Accept\\n\x22;\n");		fprintf(a, "\t\t\t#endif\n");	}	if(data.variables.generate_sanity_checks)		fprintf(a, "\t\t\tif(symbol_stack.size()!=1)\n"			"\t\t\t\tthrow logic_error(\x22Whale: Stack size !=1 while accepting.\x22);\n");	fprintf(a, "\t\t\t%s *result = dynamic_cast<%s *>(symbol_stack.back());\n", S_name, S_name);	if(data.variables.make_up_connection)		fprintf(a, "\t\t\tresult->up = 0;\n");	fprintf(a, "\t\t\treturn result;\n");	fprintf(a, "\t\t}\n");	fprintf(a, "\t\telse\n");	fprintf(a, "\t\t{\n");	if(data.variables.generate_verbose_prints) {		fprintf(a, "\t\t\t#if WHALE_DEBUG != 0\n");		fprintf(a, "\t\t\tif (m_debug)\n");		fprintf(a, "\t\t\t\tcout << \x22" "Error\\n\x22;\n");		fprintf(a, "\t\t\t#endif\n");	}	if(data.variables.error_handler)	{		fprintf(a, "\t\t\t// User-specified error handler.\n");		fprintf(a, "\t\t\t%s\n", data.variables.error_handler);	}	else	{		fprintf(a, "\t\t\tif(typeid(*%s)!=typeid(TerminalError))\n", ref_to_input_symbol);		fprintf(a, "\t\t\t\treport_error(cout, %s);\n", ref_to_input_symbol);		fprintf(a, "\t\t\tif(!recover_from_error())\n");		fprintf(a, "\t\t\t\treturn NULL;\n");	}	fprintf(a, "\t\t}\n");	fprintf(a, "\t}\n");	fprintf(a, "}\n");}void generate_reduce_code(FILE *a, const char *indent, int rn){	RuleData &rule=data.rules[rn];	NonterminalData &nonterminal=data.nonterminals[rule.nn];	SymbolNumber sn=SymbolNumber::for_nonterminal(rule.nn);	string fi=string(indent)+string("\t");	const char *further_indent=fi.c_str();	ClassHierarchy::Class *type=data.get_class_assigned_to_alternative(rule.nn, rule.an);#ifdef ANNOUNCE_REDUCE_CODE_GENERATION	cout << "Generating reduce code for nonterminal " << nonterminal.name << "\n";#endif	fprintf(a, "%scase %d: {\t// %s\n", indent, rn, rule.in_printable_form().c_str());	if(nonterminal.category==NonterminalData::NORMAL ||		nonterminal.category==NonterminalData::BODY)	{		AlternativeData &alternative=nonterminal.alternatives[rule.an];		if(data.variables.generate_verbose_prints) {			fprintf(a, "%s#if WHALE_DEBUG != 0\n", further_indent);			fprintf(a, "%sif (m_debug)\n", further_indent);			fprintf(a, "%s\tcout << \x22Reducing by rule %s\\n\x22;\n", further_indent, prepare_for_printf(rule.in_printable_form()).c_str());			fprintf(a, "%s#endif\n", further_indent);		}	//	const char *n_name=((nonterminal.category==NonterminalData::BODY &&	//		rule.code_to_execute_upon_reduce) ? "body_n" : "n");		const char *n_name=(nonterminal.category==NonterminalData::BODY ?			"body_n" : "n");	//	string n_with_arrow=string(n_name)+string("->");		int first_position;		if(rule.create_and_update_operator_locations.size()==0)		{			fprintf(a, "%s%s *%s=new %s;\n", further_indent, type->get_full_name().c_str(), n_name, type->get_full_name().c_str());			first_position=0;		}		else		{			SymbolNumber creator_sn=rule.body[rule.create_and_update_operator_locations[0]];			assert(creator_sn.is_nonterminal());			NonterminalData &creator=data.nonterminals[creator_sn.nonterminal_number()];			fprintf(a, "%s%s *%s=(", further_indent, type->get_full_name().c_str(), n_name);			generate_expression_that_gets_single_symbol_from_stack(a, creator.type, "rule_start", rule.create_and_update_operator_locations[0]);			fprintf(a, ")->n;\n");			first_position=rule.create_and_update_operator_locations.back()+1;		}		if(alternative.connect_up && rule.creator_nn==-1)		{			/* here we have to look for a creator of our parent.			 * (a remarkable situation: a completely born child			 * is looking for his parent, while the latter is			 * still in his egg, waiting to be born. This is			 * bottom-up parsing...)			 */		//	if(data.variables.generate_sanity_checks)		//	else		//	assert(false);		//	***BUOY***			fprintf(a, "%s%s->up=dynamic_cast<Creator *>(symbol_stack[find_some_creator_in_stack(rule_start-1)])->object();\n", further_indent, n_name);		}		set<ClassHierarchy::DataMember *> initialized_data_members;		if(first_position<rule.body.size())		{			fprintf(a, "%s\n", further_indent);			for(int i=first_position; i<rule.expr_body.size(); i++)			{				ClassHierarchy::DataMember *dm=generate_code_that_copies_single_symbol_from_stack_to_one_or_more_data_members(a, further_indent, type, rule.expr_body[i], n_name, "rule_start", i);				if(dm!=NULL) initialized_data_members.insert(dm);			}			fprintf(a, "%s\n", further_indent);		}		if(rule.create_and_update_operator_locations.size()==0)			generate_code_that_initializes_all_remaining_data_members(a, further_indent, type, n_name, initialized_data_members);		fprintf(a, "%snew_symbol=%s;\n", further_indent, n_name);		// if it is an iteration body and there is a code to execute		// upon reduce, then it's possible that there is a Creator to		// connect to.		if(nonterminal.category==NonterminalData::BODY &&			rule.code_to_execute_upon_reduce)		{			fprintf(a, "%s\n", further_indent);			int creator_nn=find_creator_somewhere_around_rule(rn);			if(creator_nn==-1)				fprintf(a, "%s/* Code operates without an object */\n", further_indent);			else if(creator_nn==0)				generate_code_to_establish_connection_to_unknown_creator(a, further_indent, nonterminal.master_nn, nonterminal.master_an);			else			{				fprintf(a, "%s/* Establishing connection to the object */\n", further_indent);				generate_code_to_establish_connection_to_creator(a, further_indent, creator_nn);			}		}	}	else if(nonterminal.category==NonterminalData::EXTERNAL)	{		fprintf(a, "%s/* Reduce to an external nonterminal. */\n", further_indent);	}	else if(nonterminal.category==NonterminalData::ITERATOR)	{		assert(rule.code_to_execute_upon_reduce==NULL);		vector<ClassHierarchy::Class *> body_types;		assert(nonterminal.type->template_parameters.size());		for(int i=0; i<nonterminal.type->template_parameters.size(); i++)			body_types.push_back(nonterminal.type->template_parameters[i]);		if(rule.body.size()==1)		{			char *v_name;			if(body_types.size()==1)				v_name="body";			else if(body_types.size()==2)				v_name="body_a";			else				assert(false);			if(data.variables.generate_verbose_prints) {				fprintf(a, "%s#if WHALE_DEBUG != 0\n", further_indent);				fprintf(a, "%sif (m_debug)\n", further_indent);				fprintf(a, "%s\tcout << \x22" "Creating iterator %s\\n\x22;\n", further_indent, nonterminal.name);				fprintf(a, "%s#endif\n", further_indent);			}			fprintf(a, "%s%s *it=new %s;\n", further_indent, type->get_full_name().c_str(), type->get_full_name().c_str());			generate_code_that_fills_up_field(a, further_indent, expression_that_gets_single_symbol_from_stack(NULL, "rule_start", 0), "it", false);			fprintf(a, "%sit->%s.push_back(", further_indent, v_name);			generate_expression_that_gets_single_symbol_from_stack(a, body_types[0], "rule_start", 0);			fprintf(a, ");\n");			fprintf(a, "%snew_symbol=it;\n", further_indent);		}		else if(rule.body.size()==2)		{			assert(body_types.size()==1);			if(data.variables.generate_verbose_prints) {				fprintf(a, "%s#if WHALE_DEBUG != 0\n", further_indent);				fprintf(a, "%sif (m_debug)\n", further_indent);				fprintf(a, "%s\tcout << \x22" "Updating iterator %s\\n\x22;\n", further_indent, nonterminal.name);				fprintf(a, "%s#endif\n", further_indent);			}			fprintf(a, "%s%s *it=", further_indent, type->get_full_name().c_str());			generate_expression_that_gets_single_symbol_from_stack(a, type, "rule_start", 0);			fprintf(a, ";\n");			generate_code_that_fills_up_field(a, further_indent, expression_that_gets_single_symbol_from_stack(NULL, "rule_start", 1), "it", false);			fprintf(a, "%sit->body.push_back(", further_indent);			generate_expression_that_gets_single_symbol_from_stack(a, body_types[0], "rule_start", 1);			fprintf(a, ");\n");			fprintf(a, "%snew_symbol=it;\n", further_indent);		}		else if(rule.body.size()==3)		{			assert(body_types.size()==2);			if(data.variables.generate_verbose_prints) {				fprintf(a, "%s#if WHALE_DEBUG != 0\n", further_indent);				fprintf(a, "%sif (m_debug)\n", further_indent);				fprintf(a, "%s\tcout << \x22" "Updating pair iterator %s\\n\x22;\n", further_indent, nonterminal.name);				fprintf(a, "%s#endif\n", further_indent);			}			fprintf(a, "%s%s *it=", further_indent, type->get_full_name().c_str());			generate_expression_that_gets_single_symbol_from_stack(a, type, "rule_start", 0);			fprintf(a, ";\n");			generate_code_that_fills_up_field(a, further_indent, expression_that_gets_single_symbol_from_stack(NULL, "rule_start", 1), "it", false);			fprintf(a, "%sit->body_b.push_back(", further_indent);			generate_expression_that_gets_single_symbol_from_stack(a, body_types[1], "rule_start", 1);			fprintf(a, ");\n");			generate_code_that_fills_up_field(a, further_indent, expression_that_gets_single_symbol_from_stack(NULL, "rule_start", 2), "it", false);			fprintf(a, "%sit->body_a.push_back(", further_indent);			generate_expression_that_gets_single_symbol_from_stack(a, body_types[0], "rule_start", 2);			fprintf(a, ");\n");			fprintf(a, "%snew_symbol=it;\n", further_indent);		}		else			assert(false);	}	else if(nonterminal.category==NonterminalData::INVOKER)	{		assert(rule.code_to_execute_upon_reduce);		fprintf(a, "%s%s *invoker=new %s;\n", further_indent, type->get_full_name().c_str(), type->get_full_name().c_str());		fprintf(a, "%snew_symbol=invoker;\n", further_indent);		int creator_nn=find_creator_somewhere_around_rule(rn);		if(creator_nn==-1)			fprintf(a, "%s/* Code operates without an object */\n", further_indent);		else if(creator_nn==0)			generate_code_to_establish_connection_to_unknown_creator(a, further_indent, nonterminal.master_nn, nonterminal.master_an);		else		{			fprintf(a, "%s/* Establishing connection to the object */\n", further_indent);			generate_code_to_establish_connection_to_creator(a, further_indent, creator_nn);		}	}	else if(nonterminal.category==NonterminalData::CREATOR ||		nonterminal.category==NonterminalData::UPDATER)	{		assert(rule.code_to_execute_upon_reduce==NULL);		bool it_is_creator=(nonterminal.category==NonterminalData::CREATOR);		assert(nonterminal.rules_where_ancillary_symbol_is_used.size()>0);		int parent_rule_number=nonterminal.rules_where_ancillary_symbol_is_used[0];		RuleData &parent_rule=data.rules[parent_rule_number];		NonterminalData &parent_nonterminal=data.nonterminals[parent_rule.nn];		AlternativeData &parent_alternative=parent_nonterminal.alternatives[parent_rule.an];		ClassHierarchy::Class *parent_type=data.get_class_assigned_to_alternative(parent_rule.nn, parent_rule.an);		assert(parent_rule.create_and_update_operator_locations.size()>=(it_is_creator ? 1 : 2));		int first_position_in_this_rule; // Important note: for			// creators it may differ from rule to rule.		int number_of_positions_to_process;		if(it_is_creator)		{			int creator_pos=parent_rule.create_and_update_operator_locations[0];			assert(parent_rule.body[creator_pos]==sn);			first_position_in_thi

⌨️ 快捷键说明

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