From fabbc9e9f488daa682bf103a79d5405b074617df Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Mon, 27 Mar 2017 16:20:50 +0200 Subject: [PATCH 1/8] preprocessor: allow declaration of model variables in the model block --- DynamicModel.cc | 15 +++++++++ DynamicModel.hh | 3 ++ DynareBison.yy | 8 ++++- DynareFlex.ll | 4 +++ ParsingDriver.cc | 79 ++++++++++++++++++++++++++++++++++++++++++------ ParsingDriver.hh | 12 +++++--- 6 files changed, 105 insertions(+), 16 deletions(-) diff --git a/DynamicModel.cc b/DynamicModel.cc index cc3dcf1c..0d71fae9 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -3710,6 +3710,21 @@ DynamicModel::writeDynamicFile(const string &basename, bool block, bool bytecode writeDynamicMFile(t_basename); } +void +DynamicModel::updateAfterVariableChange(DynamicModel &dm) +{ + variable_node_map.clear(); + unary_op_node_map.clear(); + binary_op_node_map.clear(); + trinary_op_node_map.clear(); + external_function_node_map.clear(); + first_deriv_external_function_node_map.clear(); + second_deriv_external_function_node_map.clear(); + + cloneDynamic(dm); + dm.replaceMyEquations(*this); +} + void DynamicModel::cloneDynamic(DynamicModel &dynamic_model) const { diff --git a/DynamicModel.hh b/DynamicModel.hh index 7f0177fb..369c4abe 100644 --- a/DynamicModel.hh +++ b/DynamicModel.hh @@ -263,6 +263,9 @@ public: /*! It assumes that the dynamic model given in argument has just been allocated */ void cloneDynamic(DynamicModel &dynamic_model) const; + //! update equations after variable type change in model block + void updateAfterVariableChange(DynamicModel &dynamic_model); + //! Replaces model equations with derivatives of Lagrangian w.r.t. endogenous void computeRamseyPolicyFOCs(const StaticModel &static_model); //! Replaces the model equations in dynamic_model with those in this model diff --git a/DynareBison.yy b/DynareBison.yy index 10361cdb..9aef7995 100644 --- a/DynareBison.yy +++ b/DynareBison.yy @@ -121,7 +121,7 @@ class ParsingDriver; %token PERFECT_FORESIGHT_SETUP PERFECT_FORESIGHT_SOLVER NO_POSTERIOR_KERNEL_DENSITY FUNCTION %token PRINT PRIOR_MC PRIOR_TRUNC PRIOR_MODE PRIOR_MEAN POSTERIOR_MODE POSTERIOR_MEAN POSTERIOR_MEDIAN MLE_MODE PRUNING %token QUOTED_STRING -%token QZ_CRITERIUM QZ_ZERO_THRESHOLD FULL DSGE_VAR DSGE_VARLAG DSGE_PRIOR_WEIGHT TRUNCATE +%token QZ_CRITERIUM QZ_ZERO_THRESHOLD FULL DSGE_VAR DSGE_VARLAG DSGE_PRIOR_WEIGHT TRUNCATE PIPE_E PIPE_X PIPE_P %token RELATIVE_IRF REPLIC SIMUL_REPLIC RPLOT SAVE_PARAMS_AND_STEADY_STATE PARAMETER_UNCERTAINTY %token SHOCKS SHOCK_DECOMPOSITION SHOCK_GROUPS USE_SHOCK_GROUPS SIGMA_E SIMUL SIMUL_ALGO SIMUL_SEED ENDOGENOUS_TERMINAL_PERIOD %token SMOOTHER SMOOTHER2HISTVAL SQUARE_ROOT_SOLVER STACK_SOLVE_ALGO STEADY_STATE_MODEL SOLVE_ALGO SOLVER_PERIODS ROBUST_LIN_SOLVE @@ -734,6 +734,12 @@ hand_side : '(' hand_side ')' { $$ = $2;} | symbol { $$ = driver.add_model_variable($1); } + | symbol PIPE_E + { $$ = driver.declare_or_change_type(eEndogenous, $1); } + | symbol PIPE_X + { $$ = driver.declare_or_change_type(eExogenous, $1); } + | symbol PIPE_P + { $$ = driver.declare_or_change_type(eParameter, $1); } | non_negative_number { $$ = driver.add_non_negative_constant($1); } | hand_side PLUS hand_side diff --git a/DynareFlex.ll b/DynareFlex.ll index 59eac989..d26dd946 100644 --- a/DynareFlex.ll +++ b/DynareFlex.ll @@ -852,6 +852,10 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 } . { yylval->string_val->append(yytext); } +\|[eE] { return token::PIPE_E; } +\|[xX] { return token::PIPE_X; } +\|[pP] { return token::PIPE_P; } + \'[^\']+\' { yylval->string_val = new string(yytext + 1); yylval->string_val->resize(yylval->string_val->length() - 1); diff --git a/ParsingDriver.cc b/ParsingDriver.cc index d370979e..18319a57 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -44,7 +44,7 @@ void ParsingDriver::check_symbol_existence_in_model_block(const string &name) { if (!mod_file->symbol_table.exists(name)) - model_error("Unknown symbol: " + name); + model_error("Unknown symbol: " + name, name); } void @@ -139,10 +139,17 @@ ParsingDriver::create_error_string(const Dynare::parser::location_type &l, const } void -ParsingDriver::model_error(const string &m) +ParsingDriver::create_error_string(const Dynare::parser::location_type &l, const string &m, const string &var) { - create_error_string(location, m, model_errors); - model_error_encountered = true; + ostringstream stream; + create_error_string(l, m, stream); + model_errors.push_back(make_pair(var, stream.str())); +} + +void +ParsingDriver::model_error(const string &m, const string &var) +{ + create_error_string(location, m, var); } void @@ -360,7 +367,7 @@ ParsingDriver::add_model_variable(string *name) { symb_id = mod_file->symbol_table.getID(*name); if (undeclared_model_vars.find(*name) != undeclared_model_vars.end()) - model_error("Unknown symbol: " + *name); + model_error("Unknown symbol: " + *name, *name); } catch (SymbolTable::UnknownSymbolNameException &e) { @@ -374,6 +381,57 @@ ParsingDriver::add_model_variable(string *name) return add_model_variable(symb_id, 0); } +expr_t +ParsingDriver::declare_or_change_type(SymbolType new_type, string *name) +{ + int symb_id; + try + { + symb_id = mod_file->symbol_table.getID(*name); + mod_file->symbol_table.changeType(symb_id, new_type); + + // change in equations in ModelTree + DynamicModel *dm = new DynamicModel(mod_file->symbol_table, + mod_file->num_constants, + mod_file->external_functions_table); + mod_file->dynamic_model.updateAfterVariableChange(*dm); + delete dm; + + // remove error messages + undeclared_model_vars.erase(*name); + for (vector >::const_iterator it = model_errors.begin(); + it != model_errors.end();) + if (it->first == *name) + it = model_errors.erase(it); + else + it++; + } + catch (SymbolTable::UnknownSymbolNameException &e) + { + switch (new_type) + { + case eEndogenous: + declare_endogenous(new string(*name)); + break; + case eExogenous: + declare_exogenous(new string(*name)); + break; + case eExogenousDet: + declare_exogenous_det(new string(*name)); + break; + case eParameter: + declare_parameter(new string(*name)); + break; + default: + error("Type not yet supported"); + } + symb_id = mod_file->symbol_table.getID(*name); + } + delete name; + return add_model_variable(symb_id, 0); + +} + expr_t ParsingDriver::add_model_variable(int symb_id, int lag) { @@ -689,9 +747,10 @@ ParsingDriver::begin_model() void ParsingDriver::end_model() { - if (model_error_encountered) + if (model_errors.size() > 0) { - cerr << model_errors.str(); + for (vector >::const_iterator it = model_errors.begin(); it != model_errors.end(); it++) + cerr << it->second; exit(EXIT_FAILURE); } reset_data_tree(); @@ -2657,11 +2716,11 @@ ParsingDriver::add_model_var_or_external_function(string *function_name, bool in else { // e.g. model_var(lag) => ADD MODEL VARIABLE WITH LEAD (NumConstNode)/LAG (UnaryOpNode) if (undeclared_model_vars.find(*function_name) != undeclared_model_vars.end()) - model_error("Unknown symbol: " + *function_name); + model_error("Unknown symbol: " + *function_name, *function_name); pair rv = is_there_one_integer_argument(); if (!rv.first) - model_error(string("Symbol ") + *function_name + string(" is being treated as if it were a function (i.e., takes an argument that is not an integer).")); + model_error(string("Symbol ") + *function_name + string(" is being treated as if it were a function (i.e., takes an argument that is not an integer)."), ""); nid = add_model_variable(mod_file->symbol_table.getID(*function_name), (int) rv.second); stack_external_function_args.pop(); @@ -2692,7 +2751,7 @@ ParsingDriver::add_model_var_or_external_function(string *function_name, bool in // Continue processing, noting that it was not declared // Paring will end at the end of the model block undeclared_model_vars.insert(*function_name); - model_error("Unknown symbol: " + *function_name); + model_error("Unknown symbol: " + *function_name, *function_name); pair rv = is_there_one_integer_argument(); if (rv.first) { diff --git a/ParsingDriver.hh b/ParsingDriver.hh index 29b9c321..2a0856fa 100644 --- a/ParsingDriver.hh +++ b/ParsingDriver.hh @@ -234,12 +234,10 @@ private: bool nostrict; - bool model_error_encountered; - - ostringstream model_errors; + vector > model_errors; public: - ParsingDriver(WarningConsolidation &warnings_arg, bool nostrict_arg) : warnings(warnings_arg), nostrict(nostrict_arg), model_error_encountered(false) { }; + ParsingDriver(WarningConsolidation &warnings_arg, bool nostrict_arg) : warnings(warnings_arg), nostrict(nostrict_arg) { }; //! Starts parsing, and constructs the MOD file representation /*! The returned pointer should be deleted after use */ @@ -268,9 +266,10 @@ public: 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); + void model_error(const string &m, const string &var); //! Code shared between model_error() and error() + void create_error_string(const Dynare::parser::location_type &l, const string &m, const string &var); 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 @@ -330,6 +329,9 @@ public: expr_t add_inf_constant(); //! Adds a model variable to ModelTree and VariableTable expr_t add_model_variable(string *name); + //! Declares a variable of type new_type OR changes a variable in the equations to type new_type + //! and removes any error messages that may have been issued in model_errors + expr_t declare_or_change_type(SymbolType new_type, string *name); //! Adds an Expression's variable expr_t add_expression_variable(string *name); //! Adds a "periods" statement From 74d377ab35d4c5df240bf1236cbd4cff3c332b4f Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Thu, 30 Mar 2017 17:28:54 +0200 Subject: [PATCH 2/8] preprocessor: fix typo --- ParsingDriver.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ParsingDriver.cc b/ParsingDriver.cc index 18319a57..c0b914ac 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -399,7 +399,7 @@ ParsingDriver::declare_or_change_type(SymbolType new_type, string *name) // remove error messages undeclared_model_vars.erase(*name); - for (vector >::const_iterator it = model_errors.begin(); + for (vector >::iterator it = model_errors.begin(); it != model_errors.end();) if (it->first == *name) it = model_errors.erase(it); From 58a21322e2dd3ce47853b43d086f42890da11a37 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Mon, 3 Apr 2017 14:52:20 +0200 Subject: [PATCH 3/8] preprocessor: allow variables to pass undeclared as exogenous variables when nostrict flag is passed --- ParsingDriver.cc | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/ParsingDriver.cc b/ParsingDriver.cc index c0b914ac..e0ffbf8e 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -749,9 +749,24 @@ ParsingDriver::end_model() { if (model_errors.size() > 0) { - for (vector >::const_iterator it = model_errors.begin(); it != model_errors.end(); it++) - cerr << it->second; - exit(EXIT_FAILURE); + bool exit_after_write = false; + bool exit_after_write_undeclared_vars = true; + for (vector >::const_iterator it = model_errors.begin(); + it != model_errors.end(); it++) + { + if (it->first == "") + exit_after_write = true; + + if (mod_file->symbol_table.getType(it->first) == eExogenous) + { + exit_after_write_undeclared_vars = false; + cerr << "(Changed to warning): "; + } + + cerr << it->second; + } + if (exit_after_write || exit_after_write_undeclared_vars) + exit(EXIT_FAILURE); } reset_data_tree(); } From 5e59e9f56f4cf7cdfc341693a5616a71d5c9a426 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Mon, 3 Apr 2017 16:28:28 +0200 Subject: [PATCH 4/8] preprocessor: remove warning --- ParsingDriver.cc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/ParsingDriver.cc b/ParsingDriver.cc index e0ffbf8e..f083b170 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -758,12 +758,9 @@ ParsingDriver::end_model() exit_after_write = true; if (mod_file->symbol_table.getType(it->first) == eExogenous) - { - exit_after_write_undeclared_vars = false; - cerr << "(Changed to warning): "; - } - - cerr << it->second; + exit_after_write_undeclared_vars = false; + else + cerr << it->second; } if (exit_after_write || exit_after_write_undeclared_vars) exit(EXIT_FAILURE); From 710819348b78eba08b349f1e0be7f8a7a62d2db7 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Mon, 3 Apr 2017 16:44:31 +0200 Subject: [PATCH 5/8] preprocessor: declare variables as exogenous in shocks and histval when the nostrict option is passed --- ParsingDriver.cc | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/ParsingDriver.cc b/ParsingDriver.cc index f083b170..f3b617da 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -594,6 +594,10 @@ ParsingDriver::initval_file(string *filename) void ParsingDriver::hist_val(string *name, string *lag, expr_t rhs) { + if (nostrict) + if (!mod_file->symbol_table.exists(*name)) + declare_exogenous(new string(*name)); + check_symbol_existence(*name); int symb_id = mod_file->symbol_table.getID(*name); SymbolType type = mod_file->symbol_table.getType(symb_id); @@ -832,6 +836,10 @@ ParsingDriver::add_det_shock(string *var, bool conditional_forecast) void ParsingDriver::add_stderr_shock(string *var, expr_t value) { + if (nostrict) + if (!mod_file->symbol_table.exists(*var)) + declare_exogenous(new string(*var)); + check_symbol_existence(*var); int symb_id = mod_file->symbol_table.getID(*var); @@ -847,6 +855,10 @@ ParsingDriver::add_stderr_shock(string *var, expr_t value) void ParsingDriver::add_var_shock(string *var, expr_t value) { + if (nostrict) + if (!mod_file->symbol_table.exists(*var)) + declare_exogenous(new string(*var)); + check_symbol_existence(*var); int symb_id = mod_file->symbol_table.getID(*var); @@ -862,6 +874,14 @@ ParsingDriver::add_var_shock(string *var, expr_t value) void ParsingDriver::add_covar_shock(string *var1, string *var2, expr_t value) { + if (nostrict) + { + if (!mod_file->symbol_table.exists(*var1)) + declare_exogenous(new string(*var1)); + if (!mod_file->symbol_table.exists(*var2)) + declare_exogenous(new string(*var2)); + } + check_symbol_existence(*var1); check_symbol_existence(*var2); int symb_id1 = mod_file->symbol_table.getID(*var1); @@ -885,6 +905,14 @@ ParsingDriver::add_covar_shock(string *var1, string *var2, expr_t value) void ParsingDriver::add_correl_shock(string *var1, string *var2, expr_t value) { + if (nostrict) + { + if (!mod_file->symbol_table.exists(*var1)) + declare_exogenous(new string(*var1)); + if (!mod_file->symbol_table.exists(*var2)) + declare_exogenous(new string(*var2)); + } + check_symbol_existence(*var1); check_symbol_existence(*var2); int symb_id1 = mod_file->symbol_table.getID(*var1); From 8754e5df26492585eefff3a1597a344b40c91dd6 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Mon, 3 Apr 2017 17:18:46 +0200 Subject: [PATCH 6/8] preprocessor: instead of declaring unknown symbols as exogenous in the histval and shocks blocks, ignore the declaration (as done in initval and endval). --- ParsingDriver.cc | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/ParsingDriver.cc b/ParsingDriver.cc index f3b617da..f978676f 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -596,7 +596,11 @@ ParsingDriver::hist_val(string *name, string *lag, expr_t rhs) { if (nostrict) if (!mod_file->symbol_table.exists(*name)) - declare_exogenous(new string(*name)); + { + warning("discarding '" + *name + "' as it was not recognized in the histavl block"); + delete name; + return; + } check_symbol_existence(*name); int symb_id = mod_file->symbol_table.getID(*name); @@ -838,7 +842,11 @@ ParsingDriver::add_stderr_shock(string *var, expr_t value) { if (nostrict) if (!mod_file->symbol_table.exists(*var)) - declare_exogenous(new string(*var)); + { + warning("discarding shocks block declaration of the standard error of '" + *var + "' as it was not declared"); + delete var; + return; + } check_symbol_existence(*var); int symb_id = mod_file->symbol_table.getID(*var); @@ -857,7 +865,11 @@ ParsingDriver::add_var_shock(string *var, expr_t value) { if (nostrict) if (!mod_file->symbol_table.exists(*var)) - declare_exogenous(new string(*var)); + { + warning("discarding shocks block declaration of the variance of '" + *var + "' as it was not declared"); + delete var; + return; + } check_symbol_existence(*var); int symb_id = mod_file->symbol_table.getID(*var); @@ -875,12 +887,13 @@ void ParsingDriver::add_covar_shock(string *var1, string *var2, expr_t value) { if (nostrict) - { - if (!mod_file->symbol_table.exists(*var1)) - declare_exogenous(new string(*var1)); - if (!mod_file->symbol_table.exists(*var2)) - declare_exogenous(new string(*var2)); - } + if (!mod_file->symbol_table.exists(*var1) || !mod_file->symbol_table.exists(*var2)) + { + warning("discarding shocks block declaration of the covariance of '" + *var1 + "' and '" + *var2 + "' as at least one was not declared"); + delete var1; + delete var2; + return; + } check_symbol_existence(*var1); check_symbol_existence(*var2); @@ -906,12 +919,13 @@ void ParsingDriver::add_correl_shock(string *var1, string *var2, expr_t value) { if (nostrict) - { - if (!mod_file->symbol_table.exists(*var1)) - declare_exogenous(new string(*var1)); - if (!mod_file->symbol_table.exists(*var2)) - declare_exogenous(new string(*var2)); - } + if (!mod_file->symbol_table.exists(*var1) || !mod_file->symbol_table.exists(*var2)) + { + warning("discarding shocks block declaration of the correlation of '" + *var1 + "' and '" + *var2 + "' as at least one was not declared"); + delete var1; + delete var2; + return; + } check_symbol_existence(*var1); check_symbol_existence(*var2); From 4e357fe495a92aba94eb659d95338aa83de60a06 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Mon, 3 Apr 2017 17:19:28 +0200 Subject: [PATCH 7/8] =?UTF-8?q?preprocessor:=20update=20error=20messages?= =?UTF-8?q?=20with=20references=20to=20=E2=80=98nostrict=E2=80=99=20option?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ParsingDriver.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ParsingDriver.cc b/ParsingDriver.cc index f978676f..ba04a350 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -44,14 +44,14 @@ void ParsingDriver::check_symbol_existence_in_model_block(const string &name) { if (!mod_file->symbol_table.exists(name)) - model_error("Unknown symbol: " + name, name); + model_error("Unknown symbol: " + name + ". Try using 'nostrict' option to have this declared as an exogenous variable by the preprocessor.", name); } void ParsingDriver::check_symbol_existence(const string &name) { if (!mod_file->symbol_table.exists(name)) - error("Unknown symbol: " + name); + error("Unknown symbol: " + name + ". If referenced from the 'initval', 'endval', 'histval', or 'shocks' block, you can pass the 'nostrict' option to dynare to have this line ignored."); } void @@ -367,7 +367,7 @@ ParsingDriver::add_model_variable(string *name) { symb_id = mod_file->symbol_table.getID(*name); if (undeclared_model_vars.find(*name) != undeclared_model_vars.end()) - model_error("Unknown symbol: " + *name, *name); + model_error("Unknown symbol: " + *name + ". Try using 'nostrict' option to have this declared as an exogenous variable by the preprocessor.", *name); } catch (SymbolTable::UnknownSymbolNameException &e) { @@ -2770,7 +2770,7 @@ ParsingDriver::add_model_var_or_external_function(string *function_name, bool in else { // e.g. model_var(lag) => ADD MODEL VARIABLE WITH LEAD (NumConstNode)/LAG (UnaryOpNode) if (undeclared_model_vars.find(*function_name) != undeclared_model_vars.end()) - model_error("Unknown symbol: " + *function_name, *function_name); + model_error("Unknown symbol: " + *function_name + ". Try using 'nostrict' option to have this declared as an exogenous variable by the preprocessor.", *function_name); pair rv = is_there_one_integer_argument(); if (!rv.first) @@ -2805,7 +2805,7 @@ ParsingDriver::add_model_var_or_external_function(string *function_name, bool in // Continue processing, noting that it was not declared // Paring will end at the end of the model block undeclared_model_vars.insert(*function_name); - model_error("Unknown symbol: " + *function_name, *function_name); + model_error("Unknown symbol: " + *function_name + ". Try using 'nostrict' option to have this declared as an exogenous variable by the preprocessor.", *function_name); pair rv = is_there_one_integer_argument(); if (rv.first) { From aead792195c0b27ea42dea435b87d463d07d630f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Adjemian=20=28Charybdis=29?= Date: Mon, 3 Apr 2017 18:06:15 +0200 Subject: [PATCH 8/8] Cosmetic change. --- ParsingDriver.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ParsingDriver.cc b/ParsingDriver.cc index ba04a350..8f068bb5 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -44,14 +44,14 @@ void ParsingDriver::check_symbol_existence_in_model_block(const string &name) { if (!mod_file->symbol_table.exists(name)) - model_error("Unknown symbol: " + name + ". Try using 'nostrict' option to have this declared as an exogenous variable by the preprocessor.", name); + model_error("Unknown symbol: " + name + ".\nTry using 'nostrict' option to have this declared as an exogenous variable by the preprocessor.", name); } void ParsingDriver::check_symbol_existence(const string &name) { if (!mod_file->symbol_table.exists(name)) - error("Unknown symbol: " + name + ". If referenced from the 'initval', 'endval', 'histval', or 'shocks' block, you can pass the 'nostrict' option to dynare to have this line ignored."); + error("Unknown symbol: " + name + ".\nIf referenced from the 'initval', 'endval', 'histval', or 'shocks' block, you can pass the 'nostrict' option to dynare to have this line ignored."); } void @@ -367,7 +367,7 @@ ParsingDriver::add_model_variable(string *name) { symb_id = mod_file->symbol_table.getID(*name); if (undeclared_model_vars.find(*name) != undeclared_model_vars.end()) - model_error("Unknown symbol: " + *name + ". Try using 'nostrict' option to have this declared as an exogenous variable by the preprocessor.", *name); + model_error("Unknown symbol: " + *name + ".\nTry using 'nostrict' option to have this declared as an exogenous variable by the preprocessor.", *name); } catch (SymbolTable::UnknownSymbolNameException &e) { @@ -2770,7 +2770,7 @@ ParsingDriver::add_model_var_or_external_function(string *function_name, bool in else { // e.g. model_var(lag) => ADD MODEL VARIABLE WITH LEAD (NumConstNode)/LAG (UnaryOpNode) if (undeclared_model_vars.find(*function_name) != undeclared_model_vars.end()) - model_error("Unknown symbol: " + *function_name + ". Try using 'nostrict' option to have this declared as an exogenous variable by the preprocessor.", *function_name); + model_error("Unknown symbol: " + *function_name + ".\nTry using 'nostrict' option to have this declared as an exogenous variable by the preprocessor.", *function_name); pair rv = is_there_one_integer_argument(); if (!rv.first) @@ -2805,7 +2805,7 @@ ParsingDriver::add_model_var_or_external_function(string *function_name, bool in // Continue processing, noting that it was not declared // Paring will end at the end of the model block undeclared_model_vars.insert(*function_name); - model_error("Unknown symbol: " + *function_name + ". Try using 'nostrict' option to have this declared as an exogenous variable by the preprocessor.", *function_name); + model_error("Unknown symbol: " + *function_name + ".\nTry using 'nostrict' option to have this declared as an exogenous variable by the preprocessor.", *function_name); pair rv = is_there_one_integer_argument(); if (rv.first) {