Merge remote-tracking branch 'origin/declare_vars_in_model_block'
commit
80060fb9ef
|
@ -4062,6 +4062,21 @@ DynamicModel::writeAuxVarRecursiveDefinitions(ostream &output, ExprNodeOutputTyp
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
|
|
|
@ -335,6 +335,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, const bool nopreprocessoroutput);
|
||||
//! Replaces the model equations in dynamic_model with those in this model
|
||||
|
|
|
@ -122,7 +122,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 <string_val> 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
|
||||
|
@ -878,6 +878,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
|
||||
|
|
|
@ -905,6 +905,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
|
|||
}
|
||||
<DATES_STATEMENT>. { yylval->string_val->append(yytext); }
|
||||
|
||||
<DYNARE_BLOCK>\|[eE] { return token::PIPE_E; }
|
||||
<DYNARE_BLOCK>\|[xX] { return token::PIPE_X; }
|
||||
<DYNARE_BLOCK>\|[pP] { return token::PIPE_P; }
|
||||
|
||||
<DYNARE_STATEMENT,DYNARE_BLOCK>\'[^\']+\' {
|
||||
yylval->string_val = new string(yytext + 1);
|
||||
yylval->string_val->resize(yylval->string_val->length() - 1);
|
||||
|
|
|
@ -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);
|
||||
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);
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -377,7 +384,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 + ".\nTry using 'nostrict' option to have this declared as an exogenous variable by the preprocessor.", *name);
|
||||
}
|
||||
catch (SymbolTable::UnknownSymbolNameException &e)
|
||||
{
|
||||
|
@ -391,6 +398,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<pair<string, string> >::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)
|
||||
{
|
||||
|
@ -702,6 +760,14 @@ 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))
|
||||
{
|
||||
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);
|
||||
SymbolType type = mod_file->symbol_table.getType(symb_id);
|
||||
|
@ -894,10 +960,23 @@ ParsingDriver::begin_model()
|
|||
void
|
||||
ParsingDriver::end_model()
|
||||
{
|
||||
if (model_error_encountered)
|
||||
if (model_errors.size() > 0)
|
||||
{
|
||||
cerr << model_errors.str();
|
||||
exit(EXIT_FAILURE);
|
||||
bool exit_after_write = false;
|
||||
bool exit_after_write_undeclared_vars = true;
|
||||
for (vector<pair<string, string> >::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;
|
||||
else
|
||||
cerr << it->second;
|
||||
}
|
||||
if (exit_after_write || exit_after_write_undeclared_vars)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
reset_data_tree();
|
||||
}
|
||||
|
@ -966,6 +1045,14 @@ 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))
|
||||
{
|
||||
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);
|
||||
|
||||
|
@ -981,6 +1068,14 @@ 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))
|
||||
{
|
||||
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);
|
||||
|
||||
|
@ -996,6 +1091,15 @@ 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) || !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);
|
||||
int symb_id1 = mod_file->symbol_table.getID(*var1);
|
||||
|
@ -1019,6 +1123,15 @@ 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) || !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);
|
||||
int symb_id1 = mod_file->symbol_table.getID(*var1);
|
||||
|
@ -3071,11 +3184,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 + ".\nTry using 'nostrict' option to have this declared as an exogenous variable by the preprocessor.", *function_name);
|
||||
|
||||
pair<bool, double> 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();
|
||||
|
@ -3106,7 +3219,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 + ".\nTry using 'nostrict' option to have this declared as an exogenous variable by the preprocessor.", *function_name);
|
||||
pair<bool, double> rv = is_there_one_integer_argument();
|
||||
if (rv.first)
|
||||
{
|
||||
|
|
|
@ -245,9 +245,7 @@ private:
|
|||
|
||||
bool nostrict;
|
||||
|
||||
bool model_error_encountered;
|
||||
|
||||
ostringstream model_errors;
|
||||
vector<pair<string, string> > model_errors;
|
||||
|
||||
//! Used by VAR restrictions
|
||||
void clear_VAR_storage();
|
||||
|
@ -256,9 +254,7 @@ private:
|
|||
string pac_expectation_model_name, pac_expectation_var_model_name, pac_expectation_discount, pac_expectation_growth;
|
||||
|
||||
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 */
|
||||
|
@ -302,9 +298,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
|
||||
|
@ -368,6 +365,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
|
||||
|
|
Loading…
Reference in New Issue