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

📄 variables.cpp

📁 Full support for extended regular expressions (those with intersection and complement); Support for
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		}
	}
	
	data.variables.input_stream_is_FILE_asterisk=(!strcmp(data.variables.input_stream_class, "FILE *") ||
		!strcmp(data.variables.input_stream_class, "FILE*"));
	
	if(data.assignments.count("input_character_class"))
		flag=flag & assign_value_to_id_or_string_variable(data.variables.input_character_class,
			"input_character_class");
	else
		data.variables.input_character_class=data.variables.internal_char_type;
	
	if(data.assignments.count("how_to_return_token"))
		flag=flag & process_parametrized_string(data.variables.how_to_return_token,
			"how_to_return_token", "t");
	else
	{
		if(data.variables.using_whale)
		{
			string str=string("return make_token<")+string(data.variables.whale_namespace)+string("::$t>();");
			data.variables.how_to_return_token=strdup(str.c_str());
		}
		else
			data.variables.how_to_return_token="return $t;";
	}
	
	if(data.assignments.count("how_to_get_actual_character"))
		flag=flag & process_parametrized_string(data.variables.how_to_get_actual_character,
			"how_to_get_actual_character", "c");
	else
		data.variables.how_to_get_actual_character="$c";
	
	if(data.assignments.count("how_to_check_eof"))
		flag=flag & process_parametrized_string(data.variables.how_to_check_eof,
			"how_to_check_eof", "s");
	else if(data.variables.input_stream_is_FILE_asterisk)
		data.variables.how_to_check_eof="feof($s)";
	else
		data.variables.how_to_check_eof="$s.eof()";
	
	if(data.assignments.count("how_to_check_stream_error"))
		flag=flag & process_parametrized_string(data.variables.how_to_check_stream_error,
			"how_to_check_stream_error", "s");
	else if(data.variables.input_stream_is_FILE_asterisk)
		data.variables.how_to_check_stream_error="$s==NULL";
	else
		data.variables.how_to_check_stream_error="$s.bad()";
	
	if(data.assignments.count("how_to_get_character_from_stream"))
		flag=flag & process_parametrized_string(data.variables.how_to_get_character_from_stream,
			"how_to_get_character_from_stream", "cs");
	else if(data.variables.input_stream_is_FILE_asterisk)
		data.variables.how_to_get_character_from_stream="$c=fgetc($s)";
	else
		data.variables.how_to_get_character_from_stream="$s.get($c)";
	
	if(data.assignments.count("analyzer_state_type"))
		flag=flag & assign_value_to_id_or_string_variable(data.variables.analyzer_state_type,
			"analyzer_state_type");
	
	flag=flag & assign_value_to_code_variable(data.variables.code_in_class_before_all,
		"code_in_class_before_all");
	flag=flag & assign_value_to_code_variable(data.variables.code_in_class,
		"code_in_class");
	flag=flag & assign_value_to_code_variable(data.variables.code_in_class_after_all,
		"code_in_class_after_all");
	
	flag=flag & assign_value_to_code_variable(data.variables.code_in_constructor,
		"code_in_constructor");
	
	flag=flag & assign_value_to_code_variable(data.variables.code_in_h_before_all,
		"code_in_h_before_all");
	flag=flag & assign_value_to_code_variable(data.variables.code_in_h,
		"code_in_h");
	flag=flag & assign_value_to_code_variable(data.variables.code_in_h_after_all,
		"code_in_h_after_all");
	
	flag=flag & assign_value_to_code_variable(data.variables.code_in_cpp_before_all,
		"code_in_cpp_before_all");
	flag=flag & assign_value_to_code_variable(data.variables.code_in_cpp,
		"code_in_cpp");
	flag=flag & assign_value_to_code_variable(data.variables.code_in_cpp_after_all,
		"code_in_cpp_after_all");
	
	return flag;
}

// executed just before code generation.
bool assign_values_to_variables_stage_two()
{
	bool flag=true;
	
	if(!data.assignments.count("analyzer_state_type"))
	{
		int n=data.final_automaton.size();
		
		if(n>60000)
			data.variables.analyzer_state_type="int";
		else if(n>30000)
			data.variables.analyzer_state_type="unsigned short";
		else if(n>250)
			data.variables.analyzer_state_type="short";
		else
			data.variables.analyzer_state_type="unsigned char";
	}
	
	data.variables.access_transitions_through_a_method=(data.variables.compress_tables && data.variables.using_layer2);
	
	data.variables.my_new_variable=false;
	data.variables.another_variable=NULL;
	
	return flag;
}

void report_wrong_parameters(ostream &os, const char *variable, NonterminalOptionStatement *st, const char *additional_text)
{
	os << "Wrong value assigned to variable '" << variable << "'";
	if(st)
	{
		cout << " at ";
		print_terminal_location(os, st->left);
	}
	else
		cout << " in command line";
	
	if(additional_text)
		os << ", " << additional_text;
	os << ".\n";
}

void report_ignored_parameters(ostream &os, const char *variable, NonterminalOptionStatement *st, const char *additional_text)
{
	os << "Warning: assignment to '" << variable << "' ignored";
	if(st)
	{
		cout << " at ";
		print_terminal_location(os, st->left);
	}
	else
		cout << " in command line";
	
	if(additional_text)
		os << ", " << additional_text;
	os << ".\n";
}

bool assign_value_to_id_or_string_variable(char *&variable, char *variable_name)
{
	if(!data.assignments.count(variable_name))
	{
		variable=NULL;
		return true;
	}
	AssignmentData &ad=data.assignments[variable_name];
	int n=ad.values.size();
	
	if(n==1 && (ad.values[0].second==AssignmentData::VALUE_ID || ad.values[0].second==AssignmentData::VALUE_STRING))
	{
		variable=ad.values[0].first;
		return true;
	}
	else
	{
		report_wrong_parameters(cout, variable_name, ad.declaration,
			"expecting either an identifier or a string");
		return false;
	}
}

// returns true if no error is found, false otherwise.
// *** The return value has nothing to do with the value of the variable! ***
bool assign_value_to_bool_variable(bool &variable, char *variable_name)
{
	if(!data.assignments.count(variable_name))
		return true;
	AssignmentData &ad=data.assignments[variable_name];
	int n=ad.values.size();
	
	if(n==1 && ad.values[0].second==AssignmentData::VALUE_TRUE)
	{
		variable=true;
		return true;
	}
	else if(n==1 && ad.values[0].second==AssignmentData::VALUE_FALSE)
	{
		variable=false;
		return true;
	}
	else
	{
		report_wrong_parameters(cout, variable_name, ad.declaration,
			"expecting either 'true' or 'false'");
		return false;
	}
}

bool assign_value_to_semibool_variable(int &variable, char *variable_name,
	int max_value, int true_value)
{
	if(!data.assignments.count(variable_name))
		return true;
	AssignmentData &ad=data.assignments[variable_name];
	int n=ad.values.size();

	if(n==1 && ad.values[0].second==AssignmentData::VALUE_TRUE)
	{
		variable=true_value;
		return true;
	}
	else if(n==1 && ad.values[0].second==AssignmentData::VALUE_FALSE)
	{
		variable=0;
		return true;
	}
	else if(n==1 && ad.values[0].second==AssignmentData::VALUE_NUMBER &&
		atoi(ad.values[0].first)>=0 && atoi(ad.values[0].first)<=max_value)
	{
		variable=atoi(ad.values[0].first);
		return true;
	}
	else
	{
		char buf[100];
		sprintf(buf, "expecting 'true', 'false' or a number between 0 "
			"and %d", max_value);
		report_wrong_parameters(cout, variable_name, ad.declaration,
			buf);
		return false;
	}
}

bool assign_value_to_int_variable(int &variable, char *variable_name)
{
	if(!data.assignments.count(variable_name))
		return true;
	AssignmentData &ad=data.assignments[variable_name];
	int n=ad.values.size();
	
	if(n==1 && ad.values[0].second==AssignmentData::VALUE_NUMBER)
	{
		variable=atoi(ad.values[0].first);
		return true;
	}
	else if(n==1 && ad.values[0].second==AssignmentData::VALUE_HEX_NUMBER)
	{
		sscanf(ad.values[0].first, "%x", &variable);
		return true;
	}
	else
	{
		report_wrong_parameters(cout, variable_name, ad.declaration,
			"expecting a number");
		return false;
	}
}

bool assign_value_to_code_variable(char *&variable, char *variable_name)
{
	if(!data.assignments.count(variable_name))
	{
		variable=NULL;
		return true;
	}
	AssignmentData &ad=data.assignments[variable_name];
	int n=ad.values.size();
	
	if(n==1 && (ad.values[0].second==AssignmentData::VALUE_STRING || ad.values[0].second==AssignmentData::VALUE_CODE ))
	{
		variable=ad.values[0].first;
		return true;
	}
	else
	{
		report_wrong_parameters(cout, variable_name, ad.declaration,
			"expecting C++ code");
		return false;
	}
}

struct CharWithDollar
{
	char c;
	CharWithDollar(char c1) { c=c1; }
	operator char() const { return c; }
};

ostream &operator <<(ostream &os, CharWithDollar cwd)
{
	return os << '$' << char(cwd);
}

bool process_parametrized_string(char *&variable, char *variable_name, char *parameters)
{
	if(!data.assignments.count(variable_name))
		return true;
	AssignmentData &ad=data.assignments[variable_name];
	int n=ad.values.size();

	if(n==1 && ad.values[0].second==AssignmentData::VALUE_STRING)
	{
		int np=strlen(parameters);
		char *s=ad.values[0].first;
		
		set<CharWithDollar> unused_parameters, invalid_parameters;
		for(int j=0; j<np; j++)
			unused_parameters.insert(CharWithDollar(parameters[j]));
		
		bool after_dollar=false;
		for(int i=0; s[i]; i++)
		{
			char c=s[i];
			if(after_dollar)
			{
				if(c!='$' && c>' ' && c<128)
				{
					bool local_flag=false;
					for(int j=0; j<np; j++)
						if(parameters[j]==c)
						{
							unused_parameters.erase(CharWithDollar(c));
							local_flag=true;
							break;
						}
					if(!local_flag)
						invalid_parameters.insert(CharWithDollar(c));
				}
				after_dollar=false;
			}
			else if(c=='$')
				after_dollar=true;
		}
		
		assert(ad.declaration);
		if(unused_parameters.size())
		{
			cout << "Warning: unused parameter" << (unused_parameters.size()==1 ? " " : "s ");
			print_with_and(cout, unused_parameters.begin(), unused_parameters.end());
			cout << " in string at ";
			print_terminal_location(cout, ad.declaration->right[0]);
			cout << ".\n";
		}
		if(invalid_parameters.size())
		{
			cout << "Invalid parameter" << (invalid_parameters.size()==1 ? " " : "s ");
			print_with_and(cout, invalid_parameters.begin(), invalid_parameters.end());
			cout << " in string at ";
			print_terminal_location(cout, ad.declaration->right[0]);
			cout << ".\n";
			return false;
		}
		
		variable=s;
	}
	else
	{
		report_wrong_parameters(cout, variable_name, ad.declaration,
			"expecting a string");
		return false;
	}
	
	return true;
}

bool Variables::check_database_integrity()
{
	bool flag=true;
	for(std::map<const char *, variable_base *, NullTerminatedStringCompare>::iterator p=database.begin(); p!=database.end(); p++)
		if(!p->second->has_value_assigned_to_it)
		{
			cout << "Due to internal error, no value was assigned to variable " << p->first << ".\n";
			flag=false;
		}
	return flag;
}

⌨️ 快捷键说明

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