preprocessor: issue warnings for undeclared model variables when the end of the model block is encountered. #1286
parent
10b6a794ad
commit
a9de8dd0a0
|
@ -696,9 +696,9 @@ model_options_list : model_options_list COMMA model_options
|
|||
;
|
||||
|
||||
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(); }
|
||||
equation_list END ';' { driver.reset_data_tree(); }
|
||||
equation_list END ';' { driver.end_model(); }
|
||||
;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::check_symbol_existence_in_model_block(const string &name)
|
||||
{
|
||||
if (!mod_file->symbol_table.exists(name))
|
||||
model_error("Unknown symbol: " + name);
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::check_symbol_existence(const string &name)
|
||||
{
|
||||
|
@ -106,16 +113,7 @@ ParsingDriver::parse(istream &in, bool debug)
|
|||
void
|
||||
ParsingDriver::error(const Dynare::parser::location_type &l, const string &m)
|
||||
{
|
||||
cerr << "ERROR: " << *l.begin.filename << ": line " << l.begin.line;
|
||||
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;
|
||||
create_error_string(l, m, cerr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
@ -125,6 +123,28 @@ ParsingDriver::error(const string &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
|
||||
ParsingDriver::warning(const string &m)
|
||||
{
|
||||
|
@ -334,8 +354,17 @@ ParsingDriver::add_inf_constant()
|
|||
expr_t
|
||||
ParsingDriver::add_model_variable(string *name)
|
||||
{
|
||||
check_symbol_existence(*name);
|
||||
int symb_id = mod_file->symbol_table.getID(*name);
|
||||
check_symbol_existence_in_model_block(*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;
|
||||
return add_model_variable(symb_id, 0);
|
||||
}
|
||||
|
@ -652,6 +681,17 @@ ParsingDriver::begin_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
|
||||
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
|
||||
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
|
||||
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 model_error_encountered;
|
||||
|
||||
ostringstream model_errors;
|
||||
|
||||
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
|
||||
/*! The returned pointer should be deleted after use */
|
||||
|
@ -257,6 +265,12 @@ public:
|
|||
//! Warning handler using saved location
|
||||
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
|
||||
bool symbol_exists_and_is_not_modfile_local_or_external_function(const char *s);
|
||||
//! Sets mode of ModelTree class to use C output
|
||||
|
@ -341,6 +355,8 @@ public:
|
|||
void end_homotopy();
|
||||
//! Begin a model block
|
||||
void begin_model();
|
||||
//! End a model block, printing errors that were encountered in parsing
|
||||
void end_model();
|
||||
//! Writes a shocks statement
|
||||
void end_shocks(bool overwrite);
|
||||
//! Writes a mshocks statement
|
||||
|
|
Loading…
Reference in New Issue