preprocessor: issue warnings for undeclared model variables when the end of the model block is encountered. #1286
parent
1cabe76b06
commit
bfd239aa26
|
@ -696,9 +696,9 @@ model_options_list : model_options_list COMMA model_options
|
||||||
;
|
;
|
||||||
|
|
||||||
model : MODEL ';' { driver.begin_model(); }
|
model : MODEL ';' { driver.begin_model(); }
|
||||||
equation_list END ';' { driver.reset_data_tree(); }
|
equation_list END ';' { driver.end_model(); }
|
||||||
| MODEL '(' model_options_list ')' ';' { driver.begin_model(); }
|
| MODEL '(' model_options_list ')' ';' { driver.begin_model(); }
|
||||||
equation_list END ';' { driver.reset_data_tree(); }
|
equation_list END ';' { driver.end_model(); }
|
||||||
;
|
;
|
||||||
|
|
||||||
equation_list : equation_list equation
|
equation_list : equation_list equation
|
||||||
|
|
|
@ -40,6 +40,13 @@ ParsingDriver::symbol_exists_and_is_not_modfile_local_or_external_function(const
|
||||||
return (type != eModFileLocalVariable && type != eExternalFunction);
|
return (type != eModFileLocalVariable && type != eExternalFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ParsingDriver::check_symbol_existence_in_model_block(const string &name)
|
||||||
|
{
|
||||||
|
if (!mod_file->symbol_table.exists(name))
|
||||||
|
model_error("Unknown symbol: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ParsingDriver::check_symbol_existence(const string &name)
|
ParsingDriver::check_symbol_existence(const string &name)
|
||||||
{
|
{
|
||||||
|
@ -106,16 +113,7 @@ ParsingDriver::parse(istream &in, bool debug)
|
||||||
void
|
void
|
||||||
ParsingDriver::error(const Dynare::parser::location_type &l, const string &m)
|
ParsingDriver::error(const Dynare::parser::location_type &l, const string &m)
|
||||||
{
|
{
|
||||||
cerr << "ERROR: " << *l.begin.filename << ": line " << l.begin.line;
|
create_error_string(l, m, cerr);
|
||||||
if (l.begin.line == l.end.line)
|
|
||||||
if (l.begin.column == l.end.column - 1)
|
|
||||||
cerr << ", col " << l.begin.column;
|
|
||||||
else
|
|
||||||
cerr << ", cols " << l.begin.column << "-" << l.end.column - 1;
|
|
||||||
else
|
|
||||||
cerr << ", col " << l.begin.column << " -"
|
|
||||||
<< " line " << l.end.line << ", col " << l.end.column - 1;
|
|
||||||
cerr << ": " << m << endl;
|
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,6 +123,28 @@ ParsingDriver::error(const string &m)
|
||||||
error(location, m);
|
error(location, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ParsingDriver::create_error_string(const Dynare::parser::location_type &l, const string &m, ostream &stream)
|
||||||
|
{
|
||||||
|
stream << "ERROR: " << *l.begin.filename << ": line " << l.begin.line;
|
||||||
|
if (l.begin.line == l.end.line)
|
||||||
|
if (l.begin.column == l.end.column - 1)
|
||||||
|
stream << ", col " << l.begin.column;
|
||||||
|
else
|
||||||
|
stream << ", cols " << l.begin.column << "-" << l.end.column - 1;
|
||||||
|
else
|
||||||
|
stream << ", col " << l.begin.column << " -"
|
||||||
|
<< " line " << l.end.line << ", col " << l.end.column - 1;
|
||||||
|
stream << ": " << m << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ParsingDriver::model_error(const string &m)
|
||||||
|
{
|
||||||
|
create_error_string(location, m, model_errors);
|
||||||
|
model_error_encountered = true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ParsingDriver::warning(const string &m)
|
ParsingDriver::warning(const string &m)
|
||||||
{
|
{
|
||||||
|
@ -334,8 +354,17 @@ ParsingDriver::add_inf_constant()
|
||||||
expr_t
|
expr_t
|
||||||
ParsingDriver::add_model_variable(string *name)
|
ParsingDriver::add_model_variable(string *name)
|
||||||
{
|
{
|
||||||
check_symbol_existence(*name);
|
check_symbol_existence_in_model_block(*name);
|
||||||
int symb_id = mod_file->symbol_table.getID(*name);
|
int symb_id;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
symb_id = mod_file->symbol_table.getID(*name);
|
||||||
|
}
|
||||||
|
catch (SymbolTable::UnknownSymbolNameException &e)
|
||||||
|
{
|
||||||
|
declare_exogenous(new string (*name));
|
||||||
|
symb_id = mod_file->symbol_table.getID(*name);
|
||||||
|
}
|
||||||
delete name;
|
delete name;
|
||||||
return add_model_variable(symb_id, 0);
|
return add_model_variable(symb_id, 0);
|
||||||
}
|
}
|
||||||
|
@ -652,6 +681,17 @@ ParsingDriver::begin_model()
|
||||||
set_current_data_tree(&mod_file->dynamic_model);
|
set_current_data_tree(&mod_file->dynamic_model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ParsingDriver::end_model()
|
||||||
|
{
|
||||||
|
if (model_error_encountered)
|
||||||
|
{
|
||||||
|
cerr << model_errors.str();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
reset_data_tree();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ParsingDriver::end_shocks(bool overwrite)
|
ParsingDriver::end_shocks(bool overwrite)
|
||||||
{
|
{
|
||||||
|
|
|
@ -93,6 +93,10 @@ private:
|
||||||
//! Checks that a given symbol exists and is a endogenous or exogenous, and stops with an error message if it isn't
|
//! Checks that a given symbol exists and is a endogenous or exogenous, and stops with an error message if it isn't
|
||||||
void check_symbol_is_endogenous_or_exogenous(string *name);
|
void check_symbol_is_endogenous_or_exogenous(string *name);
|
||||||
|
|
||||||
|
//! Checks for symbol existence in model block. If it doesn't exist, an error message is stored to be printed at
|
||||||
|
//! the end of the model block
|
||||||
|
void check_symbol_existence_in_model_block(const string &name);
|
||||||
|
|
||||||
//! Helper to add a symbol declaration
|
//! Helper to add a symbol declaration
|
||||||
void declare_symbol(const string *name, SymbolType type, const string *tex_name, const vector<pair<string *, string *> *> *partition_value);
|
void declare_symbol(const string *name, SymbolType type, const string *tex_name, const vector<pair<string *, string *> *> *partition_value);
|
||||||
|
|
||||||
|
@ -228,8 +232,12 @@ private:
|
||||||
|
|
||||||
bool nostrict;
|
bool nostrict;
|
||||||
|
|
||||||
|
bool model_error_encountered;
|
||||||
|
|
||||||
|
ostringstream model_errors;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ParsingDriver(WarningConsolidation &warnings_arg, bool nostrict_arg) : warnings(warnings_arg), nostrict(nostrict_arg) { };
|
ParsingDriver(WarningConsolidation &warnings_arg, bool nostrict_arg) : warnings(warnings_arg), nostrict(nostrict_arg), model_error_encountered(false) { };
|
||||||
|
|
||||||
//! Starts parsing, and constructs the MOD file representation
|
//! Starts parsing, and constructs the MOD file representation
|
||||||
/*! The returned pointer should be deleted after use */
|
/*! The returned pointer should be deleted after use */
|
||||||
|
@ -257,6 +265,12 @@ public:
|
||||||
//! Warning handler using saved location
|
//! Warning handler using saved location
|
||||||
void warning(const string &m);
|
void warning(const string &m);
|
||||||
|
|
||||||
|
//! Error handler with explicit location (used in model block, accumulating error messages to be printed later)
|
||||||
|
void model_error(const string &m);
|
||||||
|
|
||||||
|
//! Code shared between model_error() and error()
|
||||||
|
void create_error_string(const Dynare::parser::location_type &l, const string &m, ostream &stream);
|
||||||
|
|
||||||
//! Check if a given symbol exists in the parsing context, and is not a mod file local variable
|
//! Check if a given symbol exists in the parsing context, and is not a mod file local variable
|
||||||
bool symbol_exists_and_is_not_modfile_local_or_external_function(const char *s);
|
bool symbol_exists_and_is_not_modfile_local_or_external_function(const char *s);
|
||||||
//! Sets mode of ModelTree class to use C output
|
//! Sets mode of ModelTree class to use C output
|
||||||
|
@ -341,6 +355,8 @@ public:
|
||||||
void end_homotopy();
|
void end_homotopy();
|
||||||
//! Begin a model block
|
//! Begin a model block
|
||||||
void begin_model();
|
void begin_model();
|
||||||
|
//! End a model block, printing errors that were encountered in parsing
|
||||||
|
void end_model();
|
||||||
//! Writes a shocks statement
|
//! Writes a shocks statement
|
||||||
void end_shocks(bool overwrite);
|
void end_shocks(bool overwrite);
|
||||||
//! Writes a mshocks statement
|
//! Writes a mshocks statement
|
||||||
|
|
Loading…
Reference in New Issue