diff --git a/src/DynareBison.yy b/src/DynareBison.yy index e73d9861..180d3e67 100644 --- a/src/DynareBison.yy +++ b/src/DynareBison.yy @@ -199,7 +199,8 @@ class ParsingDriver; %type > named_var_elem subsamples_eq_opt integer_range_w_inf %type >> named_var named_var_1 %type > prior_eq_opt options_eq_opt -%type > matched_moments_list +%type >> period_list +%type > matched_moments_list value_list %% %start statement_list; @@ -1038,7 +1039,7 @@ shock_elem : det_shock_elem ; det_shock_elem : VAR symbol ';' PERIODS period_list ';' VALUES value_list ';' - { driver.add_det_shock($2, false); } + { driver.add_det_shock($2, $5, $8, false); } ; svar_identification : SVAR_IDENTIFICATION {driver.begin_svar_identification();} ';' svar_identification_list END ';' @@ -1137,33 +1138,81 @@ mshock_list : mshock_list det_shock_elem ; period_list : period_list COMMA INT_NUMBER - { driver.add_period($3); } + { + $$ = $1; + int p = stoi($3); + $$.push_back({ p, p }); + } | period_list INT_NUMBER - { driver.add_period($2); } + { + $$ = $1; + int p = stoi($2); + $$.push_back({ p, p }); + } | period_list COMMA INT_NUMBER ':' INT_NUMBER - { driver.add_period($3, $5); } + { + $$ = $1; + int p1 = stoi($3), p2 = stoi($5); + if (p1 > p2) + driver.error("Can't have first period index greater than second index in range specification"); + $$.push_back({ p1, p2 }); + } | period_list INT_NUMBER ':' INT_NUMBER - { driver.add_period($2, $4); } + { + $$ = $1; + int p1 = stoi($2), p2 = stoi($4); + if (p1 > p2) + driver.error("Can't have first period index greater than second index in range specification"); + $$.push_back({ p1, p2 }); + } | INT_NUMBER ':' INT_NUMBER - { driver.add_period($1, $3); } + { + int p1 = stoi($1), p2 = stoi($3); + if (p1 > p2) + driver.error("Can't have first period index greater than second index in range specification"); + $$ = { { p1, p2 } }; + } | INT_NUMBER - { driver.add_period($1); } + { + int p = stoi($1); + $$ = { { p, p } }; + } ; sigma_e : SIGMA_E EQUAL '[' triangular_matrix ']' ';' { driver.do_sigma_e(); }; value_list : value_list COMMA '(' expression ')' - { driver.add_value($4); } + { + $$ = $1; + $$.push_back($4); + } | value_list '(' expression ')' - { driver.add_value($3); } + { + $$ = $1; + $$.push_back($3); + } | '(' expression ')' - { driver.add_value($2); } + { $$ = { $2 }; } | value_list COMMA signed_number - { driver.add_value($3); } + { + $$ = $1; + $$.push_back($3.at(0) == '-' ? + driver.add_uminus(driver.add_non_negative_constant($3.substr(1))) : + driver.add_non_negative_constant($3)); + } | value_list signed_number - { driver.add_value($2); } + { + $$ = $1; + $$.push_back($2.at(0) == '-' ? + driver.add_uminus(driver.add_non_negative_constant($2.substr(1))) : + driver.add_non_negative_constant($2)); + } | signed_number - { driver.add_value($1); } + { + $$ = { $1.at(0) == '-' ? + driver.add_uminus(driver.add_non_negative_constant($1.substr(1))) : + driver.add_non_negative_constant($1) }; + } ; triangular_matrix : triangular_matrix ';' triangular_row @@ -2898,7 +2947,7 @@ conditional_forecast_paths_shock_list : conditional_forecast_paths_shock_elem ; conditional_forecast_paths_shock_elem : VAR symbol ';' PERIODS period_list ';' VALUES value_list ';' - { driver.add_det_shock($2, true); } + { driver.add_det_shock($2, $5, $8, true); } ; steady_state_model : STEADY_STATE_MODEL ';' { driver.begin_steady_state_model(); } diff --git a/src/ParsingDriver.cc b/src/ParsingDriver.cc index 4945bb47..05a0c6ec 100644 --- a/src/ParsingDriver.cc +++ b/src/ParsingDriver.cc @@ -810,7 +810,7 @@ ParsingDriver::end_mshocks(bool overwrite) } void -ParsingDriver::add_det_shock(const string &var, bool conditional_forecast) +ParsingDriver::add_det_shock(const string &var, const vector> &periods, const vector &values, bool conditional_forecast) { if (conditional_forecast) check_symbol_is_endogenous(var); @@ -822,24 +822,21 @@ ParsingDriver::add_det_shock(const string &var, bool conditional_forecast) if (det_shocks.find(symb_id) != det_shocks.end()) error("shocks/conditional_forecast_paths: variable " + var + " declared twice"); - if (det_shocks_periods.size() != det_shocks_values.size()) + if (periods.size() != values.size()) error("shocks/conditional_forecast_paths: variable " + var + ": number of periods is different from number of shock values"); vector v; - for (size_t i = 0; i < det_shocks_periods.size(); i++) + for (size_t i = 0; i < periods.size(); i++) { ShocksStatement::DetShockElement dse; - dse.period1 = det_shocks_periods[i].first; - dse.period2 = det_shocks_periods[i].second; - dse.value = det_shocks_values[i]; + dse.period1 = periods[i].first; + dse.period2 = periods[i].second; + dse.value = values[i]; v.push_back(dse); } det_shocks[symb_id] = v; - - det_shocks_periods.clear(); - det_shocks_values.clear(); } void @@ -936,42 +933,6 @@ ParsingDriver::add_correl_shock(const string &var1, const string &var2, expr_t v corr_shocks[key] = value; } -void -ParsingDriver::add_period(const string &p1, const string &p2) -{ - int p1_val = stoi(p1); - int p2_val = stoi(p2); - if (p1_val > p2_val) - error("shocks/conditional_forecast_paths: can't have first period index greater than second index in range specification"); - det_shocks_periods.emplace_back(p1_val, p2_val); -} - -void -ParsingDriver::add_period(const string &p1) -{ - int p1_val = stoi(p1); - det_shocks_periods.emplace_back(p1_val, p1_val); -} - -void -ParsingDriver::add_value(expr_t value) -{ - det_shocks_values.push_back(value); -} - -void -ParsingDriver::add_value(const string &v) -{ - expr_t id; - - if (v.at(0) == '-') - id = data_tree->AddUMinus(data_tree->AddNonNegativeConstant(v.substr(1, string::npos))); - else - id = data_tree->AddNonNegativeConstant(v); - - det_shocks_values.push_back(id); -} - void ParsingDriver::begin_svar_identification() { diff --git a/src/ParsingDriver.hh b/src/ParsingDriver.hh index 0811f3bc..bbb3d8e5 100644 --- a/src/ParsingDriver.hh +++ b/src/ParsingDriver.hh @@ -151,10 +151,6 @@ private: OptimWeightsStatement::covar_weights_t covar_weights; //! Temporary storage for deterministic shocks ShocksStatement::det_shocks_t det_shocks; - //! Temporary storage for periods of deterministic shocks - vector> det_shocks_periods; - //! Temporary storage for values of deterministic shocks - vector det_shocks_values; //! Temporary storage for variances of shocks ShocksStatement::var_and_std_shocks_t var_shocks; //! Temporary storage for standard errors of shocks @@ -439,7 +435,7 @@ public: //! Writes a mshocks statement void end_mshocks(bool overwrite); //! Adds a deterministic shock or a path element inside a conditional_forecast_paths block - void add_det_shock(const string &var, bool conditional_forecast); + void add_det_shock(const string &var, const vector> &periods, const vector &values, bool conditional_forecast); //! Adds a std error shock void add_stderr_shock(const string &var, expr_t value); //! Adds a variance shock