diff --git a/DynareBison.yy b/DynareBison.yy index 9b6cb7f9..26a727e2 100644 --- a/DynareBison.yy +++ b/DynareBison.yy @@ -707,9 +707,12 @@ svar_var_list : svar_var_list COMMA symbol ; restriction_expression : expression {driver.check_restriction_expression_constant($1);} - | restriction_elem_expression - | restriction_expression restriction_elem_expression - ; + | restriction_expression_1 + ; + +restriction_expression_1 : restriction_elem_expression + | restriction_expression_1 restriction_elem_expression + ; restriction_elem_expression : COEFF '(' symbol COMMA INT_NUMBER ')' { driver.add_positive_restriction_element($3,$5);} @@ -717,8 +720,6 @@ restriction_elem_expression : COEFF '(' symbol COMMA INT_NUMBER ')' { driver.add_negative_restriction_element($4,$6);} | expression TIMES COEFF '(' symbol COMMA INT_NUMBER ')' { driver.add_positive_restriction_element($1,$5,$7);} - | MINUS expression COEFF TIMES '(' symbol COMMA INT_NUMBER ')' - { driver.add_negative_restriction_element($2,$6,$8);} ; markov_switching : MARKOV_SWITCHING '(' ms_options_list ')' ';' diff --git a/ParsingDriver.cc b/ParsingDriver.cc index 87a743a1..eff84af4 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -834,6 +834,8 @@ ParsingDriver::add_restriction_equation_nbr(string *eq_nbr) { svar_equation_nbr = atoi(eq_nbr->c_str()); svar_left_handside = true; + // reinitialize restriction type that must be set from the first restriction element + svar_restriction_type = ParsingDriver::NOT_SET; } void @@ -848,94 +850,79 @@ ParsingDriver::add_restriction_equal() void ParsingDriver::add_positive_restriction_element(expr_t value, string *variable, string *lag) { - check_symbol_existence(*variable); - int symb_id = mod_file->symbol_table.getID(*variable); - // if the expression is not on the left handside, change its sign if (!svar_left_handside) value = add_uminus(value); - - int current_lag = atoi(lag->c_str()); - SvarIdentificationStatement::svar_identification_restriction new_restriction; - new_restriction.equation = svar_equation_nbr; - if (current_lag > 0) - new_restriction.restriction_nbr = ++svar_Ri_restriction_nbr[svar_equation_nbr]; - else - new_restriction.restriction_nbr = ++svar_Qi_restriction_nbr[svar_equation_nbr]; - new_restriction.lag = current_lag; - new_restriction.variable = symb_id; - new_restriction.value = value; - - svar_ident_restrictions.push_back(new_restriction); + + add_restriction_element(value, variable, lag); } void ParsingDriver::add_positive_restriction_element(string *variable, string *lag) { - check_symbol_existence(*variable); - int symb_id = mod_file->symbol_table.getID(*variable); expr_t value(data_tree->One); // if the expression is not on the left handside, change its sign if (!svar_left_handside) value = add_uminus(value); - int current_lag = atoi(lag->c_str()); - SvarIdentificationStatement::svar_identification_restriction new_restriction; - new_restriction.equation = svar_equation_nbr; - if (current_lag > 0) - new_restriction.restriction_nbr = ++svar_Ri_restriction_nbr[svar_equation_nbr]; - else - new_restriction.restriction_nbr = ++svar_Qi_restriction_nbr[svar_equation_nbr]; - new_restriction.lag = current_lag; - new_restriction.variable = symb_id; - new_restriction.value = value; - - svar_ident_restrictions.push_back(new_restriction); + add_restriction_element(value, variable, lag); } void ParsingDriver::add_negative_restriction_element(expr_t value, string *variable, string *lag) { - check_symbol_existence(*variable); - int symb_id = mod_file->symbol_table.getID(*variable); - // if the expression is on the left handside, change its sign if (svar_left_handside) value = add_uminus(value); - int current_lag = atoi(lag->c_str()); - SvarIdentificationStatement::svar_identification_restriction new_restriction; - new_restriction.equation = svar_equation_nbr; - if (current_lag > 0) - new_restriction.restriction_nbr = ++svar_Ri_restriction_nbr[svar_equation_nbr]; - else - new_restriction.restriction_nbr = ++svar_Qi_restriction_nbr[svar_equation_nbr]; - new_restriction.lag = current_lag; - new_restriction.variable = symb_id; - new_restriction.value = value; - - svar_ident_restrictions.push_back(new_restriction); + add_restriction_element(value, variable, lag); } void ParsingDriver::add_negative_restriction_element(string *variable, string *lag) { - check_symbol_existence(*variable); - int symb_id = mod_file->symbol_table.getID(*variable); expr_t value(data_tree->One); // if the expression is on the left handside, change its sign if (svar_left_handside) value = add_uminus(value); + add_restriction_element(value, variable, lag); +} + +void +ParsingDriver::add_restriction_element(expr_t value, string *variable, string *lag) +{ + check_symbol_existence(*variable); + int symb_id = mod_file->symbol_table.getID(*variable); + int current_lag = atoi(lag->c_str()); + if (svar_restriction_type == ParsingDriver::NOT_SET) + { + if (current_lag == 0) + { + svar_restriction_type = ParsingDriver::Qi_TYPE; + ++svar_Qi_restriction_nbr[svar_equation_nbr]; + } + else + { + svar_restriction_type = ParsingDriver::Ri_TYPE; + ++svar_Ri_restriction_nbr[svar_equation_nbr]; + } + } + else + { + if ((svar_restriction_type == Qi_TYPE && current_lag > 0) + || (svar_restriction_type == Ri_TYPE && current_lag == 0)) + error("SVAR_IDENTIFICATION: a single restrictions must affect either Qi or Ri, but not both"); + } SvarIdentificationStatement::svar_identification_restriction new_restriction; new_restriction.equation = svar_equation_nbr; if (current_lag > 0) - new_restriction.restriction_nbr = ++svar_Ri_restriction_nbr[svar_equation_nbr]; + new_restriction.restriction_nbr = svar_Ri_restriction_nbr[svar_equation_nbr]; else - new_restriction.restriction_nbr = ++svar_Qi_restriction_nbr[svar_equation_nbr]; + new_restriction.restriction_nbr = svar_Qi_restriction_nbr[svar_equation_nbr]; new_restriction.lag = current_lag; new_restriction.variable = symb_id; new_restriction.value = value; diff --git a/ParsingDriver.hh b/ParsingDriver.hh index d6464507..dedf5e6d 100644 --- a/ParsingDriver.hh +++ b/ParsingDriver.hh @@ -159,6 +159,14 @@ private: //! Temporary storage for current restriction number in svar_identification block map svar_Qi_restriction_nbr; map svar_Ri_restriction_nbr; + //! Temporary storage for restriction type + enum SvarRestrictionType + { + NOT_SET, + Qi_TYPE, + Ri_TYPE + }; + SvarRestrictionType svar_restriction_type; //! Temporary storage for argument list of external function stack > stack_external_function_args; @@ -378,6 +386,8 @@ public: void add_negative_restriction_element(expr_t value, string *variable, string *lag); //! Svar_Idenditification Statement: add negative unit coefficient of a linear restriction void add_negative_restriction_element(string *variable, string *lag); + //! Svar_Idenditification Statement: add restriction element + void add_restriction_element(expr_t value, string *variable, string *lag); //! Svar_Identification Statement: check that restriction is homogenous void check_restriction_expression_constant(expr_t value); //! Svar_Identification Statement: restriction of form upper cholesky