Commit a9de8dd0 authored by Houtan Bastani's avatar Houtan Bastani Committed by Stéphane Adjemian
Browse files

preprocessor: issue warnings for undeclared model variables when the end of...

preprocessor: issue warnings for undeclared model variables when the end of the model block is encountered. #1286
parent 10b6a794
......@@ -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,23 +113,36 @@ 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;
create_error_string(l, m, cerr);
exit(EXIT_FAILURE);
}
void
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)
cerr << ", col " << l.begin.column;
stream << ", col " << l.begin.column;
else
cerr << ", cols " << l.begin.column << "-" << l.end.column - 1;
stream << ", cols " << l.begin.column << "-" << l.end.column - 1;
else
cerr << ", col " << l.begin.column << " -"
stream << ", col " << l.begin.column << " -"
<< " line " << l.end.line << ", col " << l.end.column - 1;
cerr << ": " << m << endl;
exit(EXIT_FAILURE);
stream << ": " << m << endl;
}
void
ParsingDriver::error(const string &m)
ParsingDriver::model_error(const string &m)
{
error(location, m);
create_error_string(location, m, model_errors);
model_error_encountered = true;
}
void
......@@ -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
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment