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

📄 codegen.cpp

📁 Full support for extended regular expressions (those with intersection and complement); Support for
💻 CPP
📖 第 1 页 / 共 3 页
字号:
					fprintf(a, "-1, 0, ");
				else
				{
					assert(exc_data.size()==1);
					fprintf(a, "%d, %d, ", exc_location, exc_data[0]);
				}
				
				int l2_line=data.tables.layer1_to_layer2[l1_line];
				offset=data.tables.line_to_offset_in_table_of_lines[l2_line];
			}
			
			fprintf(a, "table_of_lines%s", printable_increment(offset));
		}
		else
		{
			fprintf(a, "{ ");
			for(int j=0; j<data.number_of_symbol_classes; j++)
			{
				if(j) fprintf(a, ", ");
				
				// all state numbers are incremented by one.
				fprintf(a, "%d", data.final_automaton[i].transitions[j]+1);
			}
			fprintf(a, " }");
		}
		
		// all action numbers are also incremented by one.
		fprintf(a, ", %d", data.final_automaton[i].action_accepted_here+1);
		
		if(data.variables.generate_arbitrary_lookahead_support)
			fprintf(a, ", %s", (data.final_automaton[i].actions_that_need_lookahead_here.size()>0 ? "true" : "false"));
		
		fprintf(a, " }");
	}
	fprintf(a, "\n};\n");
}

void generate_table_of_lines(FILE *a)
{
	fprintf(a, "\nconst %s %s::table_of_lines[%s::size_of_table_of_lines]={\n",
		data.variables.analyzer_state_type,
		data.variables.dolphin_class_name,
		data.variables.dolphin_class_name);
	TablePrinter tp(a, "\t", "%3d", 12);
	tp.print(data.tables.compressed_table_of_lines);
	fprintf(a, "\n};\n");
}

void generate_table_of_symbol_classes(FILE *a)
{
	fprintf(a, "\nconst int %s::symbol_to_symbol_class[%s::alphabet_cardinality]={\n",
		data.variables.dolphin_class_name,
		data.variables.dolphin_class_name);
	TablePrinter tp(a, "\t", "%3d", 12);
	tp.print(data.symbol_to_symbol_class);
	fprintf(a, "\n};\n");
}

void generate_table_of_lookahead_states(FILE *a)
{
	fprintf(a, "\nconst %s %s::lookahead_states[%s::size_of_table_of_lookahead_states]={\n",
		data.variables.analyzer_state_type,
		data.variables.dolphin_class_name,
		data.variables.dolphin_class_name);
	TablePrinter tp(a, "\t", "%3d", 12);
	tp.print(data.tables.compressed_table_of_lookahead_states);
	fprintf(a, "\n};\n");
}

// the table of actions is used to implement lookahead
void generate_table_of_actions(FILE *a)
{
#if 0
	fprintf(a, "\nconst int %s::action_to_recognized_expression[%s::number_of_actions+1]={\n",
		data.variables.dolphin_class_name,
		data.variables.dolphin_class_name);
	TablePrinter tp(a, "\t", "%3d", 12);
	tp.print(data.tables.action_to_recognized_expression);
	fprintf(a, "\n};\n");
#endif
	
	const int actions_per_line=2;
	
	fprintf(a, "\nconst %s::ActionData %s::actions[%s::number_of_actions+1]={\n\t",
		data.variables.dolphin_class_name,
		data.variables.dolphin_class_name,
		data.variables.dolphin_class_name);
	
	fprintf(a, "{ ");
	if(data.variables.generate_arbitrary_lookahead_support &&
		data.variables.generate_fixed_length_lookahead_support)
	{
		fprintf(a, "0, NULL, 0");
	}
	else if(data.variables.generate_fixed_length_lookahead_support)
	{
		assert(!data.variables.generate_arbitrary_lookahead_support);
		fprintf(a, "0");
	}
	else if(data.variables.generate_arbitrary_lookahead_support)
	{
		assert(!data.variables.generate_fixed_length_lookahead_support);
		fprintf(a, "NULL, 0");
	}
	if(data.variables.generate_eof_lookahead_support)
	{
		if(data.variables.generate_fixed_length_lookahead_support ||
			data.variables.generate_arbitrary_lookahead_support)
		{
			fprintf(a, ", ");
		}
		fprintf(a, "0");
	}
	fprintf(a, " }");
	
	for(int i=0; i<data.actions.size(); i++)
	{
		fprintf(a, ((i+1)%actions_per_line==0 ? ",\n\t" : ", "));
		
		int re_number=data.actions[i].recognized_expression_number;
		RecognizedExpressionData &re=data.recognized_expressions[re_number];
		
		fprintf(a, "{ ");
		
		bool comma_needed=false;
		
		if(data.variables.generate_fixed_length_lookahead_support)
		{
			fprintf(a, "%d", re.lookahead_length);
			comma_needed=true;
		}
		
		if(data.variables.generate_arbitrary_lookahead_support)
		{
			if(comma_needed)
				fprintf(a, ", ");
			else
				comma_needed=true;
			
			if(re.lookahead_length==-1)
			{
				int offset=data.tables.offset_in_table_of_lookahead_states[re_number];
				int number=data.tables.number_of_lookahead_states[re_number];
				fprintf(a, "lookahead_states%s, %d", printable_increment(offset), number);
			}
			else
				fprintf(a, "NULL, 0");
		}
		
		if(data.variables.generate_eof_lookahead_support)
		{
			if(comma_needed)
				fprintf(a, ", ");
			else
				comma_needed=true;
			
			fprintf(a, "%d", re.lookahead_eof);
		}
		
		comma_needed;
		fprintf(a, " }");
	}
	
	fprintf(a, "\n};\n");
}

void generate_table_of_initial_states(FILE *a)
{
	fprintf(a, "\nconst %s %s::initial_dfa_states_for_start_conditions[%s::number_of_start_conditions]={\n",
		data.variables.analyzer_state_type,
		data.variables.dolphin_class_name,
		data.variables.dolphin_class_name);
	TablePrinter tp(a, "\t", "%3d", 12);
	tp.print(data.tables.start_condition_to_dfa_state_table);
	fprintf(a, "\n};\n");
}

// this function must be run twice: before DolphinLexicalAnalyzer class with
// mode==1 and after DolphinLexicalAnalyzerClass with mode==2
void generate_whale_emulator(FILE *a, int mode)
{
	assert(data.variables.using_whale && data.variables.whale_emulation_mode);
	assert(mode==1 || mode==2);
	
	if(mode==1)
	{
		fprintf(a, "\n"
			"/******************************/\n"
			"/*    Whale emulation mode    */\n"
			"/******************************/\n");
	}
	else
		fprintf(a, "\n"
			"/* Whale emulator (continued) */\n");
	
	fprintf(a, "namespace %s\n", data.variables.whale_namespace);
	fprintf(a, "{\n");
	
	if(mode==1)
	{
		fprintf(a, "\tstruct Symbol\n"
			"\t{\n"
			"\t};\n");
		fprintf(a, "\tstruct Terminal : Symbol\n"
			"\t{\n"
			"\t\tvirtual int number()=0;\n"
			"\t\t\n"
			"\t\tint line, column;\n"
			"\t\t%s *text;\n"
			"\t};\n", data.variables.internal_char_type);
		fprintf(a, "\tstruct Nonterminal : Symbol\n"
			"\t{\n"
			"\t};\n");
		fprintf(a, "\tstruct TerminalEOF;\n");
		fprintf(a, "\tstruct TerminalError;\n");
	}
	
	if(mode==2)
	{
		// generating all terminal classes referenced from the file.
		set<char *, NullTerminatedStringCompare> terminal_classes;
		for(int i=0; i<data.actions.size(); i++)
		{
			if(typeid(*data.actions[i].declaration->action)==typeid(NonterminalActionReturn))
				terminal_classes.insert(dynamic_cast<NonterminalActionReturn *>(data.actions[i].declaration->action)->return_value->text);
		}
		terminal_classes.insert("TerminalEOF");
		terminal_classes.insert("TerminalError");
		int counter=0;
		for(set<char *, NullTerminatedStringCompare>::iterator p=terminal_classes.begin(); p!=terminal_classes.end(); p++)
			fprintf(a, "\tstruct %s : Terminal\n"
				"\t{\n"
				"\t\tvirtual int number() { return %u; }\n"
				"\t};\n", *p, counter++);
		
		// generating a single nonterminal
		fprintf(a, "\tstruct NonterminalS : Nonterminal\n"
			"\t{\n"
			"\t\tstd::vector<Terminal *> terminals;\n"
			"\t};\n");
		
		// generating a dummy parser
		fprintf(a, "\n\tclass DummyParser\n");
		fprintf(a, "\t{\n");
		fprintf(a, "\t\t%s &dolphin;\n", data.variables.dolphin_class_name);
		fprintf(a, "\t\t\n");
		fprintf(a, "\tpublic:\n");
		fprintf(a, "\t\tDummyParser(%s &lexical_analyzer) : dolphin(lexical_analyzer)\n", data.variables.dolphin_class_name);
		fprintf(a, "\t\t{\n");
		fprintf(a, "\t\t}\n");
		fprintf(a, "\t\tNonterminalS *parse()\n");
		fprintf(a, "\t\t{\n");
		fprintf(a, "\t\t\tNonterminalS *S=new NonterminalS;\n");
		fprintf(a, "\t\t\t\n");
		fprintf(a, "\t\t\tfor(;;)\n");
		fprintf(a, "\t\t\t{\n");
		fprintf(a, "\t\t\t\tTerminal *t=dolphin.get_token();\n");
		fprintf(a, "\t\t\t\tif(typeid(*t)==typeid(TerminalEOF))\n");
		fprintf(a, "\t\t\t\t\treturn S;\n");
		fprintf(a, "\t\t\t\tS->terminals.push_back(t);\n");
		fprintf(a, "\t\t\t}\n");
		fprintf(a, "\t\t}\n");
		fprintf(a, "\t};\n");
	}
	
	fprintf(a, "\n} // namespace %s\n", data.variables.whale_namespace);
	
	if(mode==2)
		fprintf(a, "\ntypedef %s::DummyParser %sParser;\n", data.variables.whale_namespace, data.variables.whale_namespace);
}

void print_parametrized_string(FILE *a, char *s, char *parameters, char *values[])
{
	bool after_dollar=false;
	for(int i=0; s[i]; i++)
	{
		char c=s[i];
		if(after_dollar)
		{
			if(c=='$')
				fputc('$', a);
			else if(c<=' ' || c>=128)
				fprintf(a, "$%c", c);
			else
			{
				bool local_flag=false;
				for(int j=0; j<parameters[j]; j++)
					if(parameters[j]==c)
					{
						fprintf(a, "%s", values[j]);
						local_flag=true;
						break;
					}
				assert(local_flag);
			}
			after_dollar=false;
		}
		else if(c=='$' && s[i+1])
			after_dollar=true;
		else
			fputc(c, a);
	}
}

void generate_action(FILE *a, const char *indent, ActionData &action, bool break_after)
{
	if(typeid(*action.declaration->action)==typeid(NonterminalActionReturn))
	{
		NonterminalActionReturn &a_ret=*dynamic_cast<NonterminalActionReturn *>(action.declaration->action);
		
		fprintf(a, "%s", indent);
		char *parameter_values[]={a_ret.return_value->text};
		print_parametrized_string(a, data.variables.how_to_return_token, "t", parameter_values);
		fprintf(a, "\n");
	}
	else if(typeid(*action.declaration->action)==typeid(NonterminalActionSkip))
	{
		if(data.variables.generate_verbose_prints)
			fprintf(a, "%scout << \x22skipping\\n\x22;\n", indent);
		if(break_after)
			fprintf(a, "%sbreak;\n", indent);
	}
	else if(typeid(*action.declaration->action)==typeid(NonterminalActionCodeII))
	{
		NonterminalActionCodeII &a_code2=*dynamic_cast<NonterminalActionCodeII *>(action.declaration->action);
		
		fprintf(a, "%s", indent);
		fprintf(a, "%s", a_code2.s.c_str());
		fprintf(a, "\n");
		
		if(break_after)
			fprintf(a, "%sbreak;\n", indent);
	}
}

void generate_actions_for_special_expression(FILE *a, const char *indent, RecognizedExpressionData &re, bool break_after)
{
	assert(re.start_condition_to_action_number.size());
	
	int an0=re.start_condition_to_action_number[0];
	bool one_action=true;
	for(int i=1; i<re.start_condition_to_action_number.size(); i++)
		if(re.start_condition_to_action_number[i]!=an0)
		{
			one_action=false;
			break;
		}
	
	if(one_action)
		generate_action(a, indent, data.actions[an0], break_after);
	else
	{
		fprintf(a, "%sswitch(start_condition)\n", indent);
		fprintf(a, "%s{\n", indent);
		
		set<int> action_numbers;
		for(int i=0; i<re.start_condition_to_action_number.size(); i++)
			action_numbers.insert(re.start_condition_to_action_number[i]);
		action_numbers.erase(-1);
		
		string further_indent=string(indent)+string("\t");
		
		for(set<int>::iterator p=action_numbers.begin(); p!=action_numbers.end(); p++)
		{
			for(int i=0; i<re.start_condition_to_action_number.size(); i++)
				if(re.start_condition_to_action_number[i]==*p)
					fprintf(a, "%scase %s:\n", indent, data.start_conditions[i].name);
			
			generate_action(a, further_indent.c_str(), data.actions[*p], true);
		}
		
		fprintf(a, "%s}\n", indent);
		
		if(break_after)
			fprintf(a, "%sbreak;\n", indent);
	}
}

string expression_for_initial_state()
{
	if(data.variables.start_conditions_enabled)
		return string("initial_dfa_states_for_start_conditions[start_condition]");
	else
		return string("initial_dfa_state");
}


bool type_is_a_pointer(char *s)
{
	for(int i=strlen(s)-1; i>=0; i++)
		if(s[i]=='*')
			return true;
		else if(s[i]>' ')
			return false;
	return false;
}

bool type_should_be_printed_without_space(char *s)
{
	int l=strlen(s);
	if(l<3) return false;
	return s[l-1]=='*' && s[l-2]==' ';
}

//void insert_cpp_code_in_file(FILE *a, const char *indent, Terminal *code)
//{
//}

⌨️ 快捷键说明

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