preprocessor: issue warnings for undeclared model variables when the end of the model block is encountered. #1286

issue#70
Houtan Bastani 2016-09-23 15:22:25 +02:00 committed by Stéphane Adjemian (Lupi)
parent 10b6a794ad
commit a9de8dd0a0
3 changed files with 71 additions and 15 deletions

View File

@ -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

View File

@ -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)
{

View File

@ -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