📄 variables.cpp
字号:
}
}
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 + -