2008-02-03 11:28:36 +01:00
/*
2023-01-16 15:02:50 +01:00
* Copyright © 2003 - 2023 Dynare Team
2008-02-03 11:28:36 +01:00
*
* This file is part of Dynare .
*
* Dynare is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* Dynare is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2021-06-09 16:52:20 +02:00
* along with Dynare . If not , see < https : //www.gnu.org/licenses/>.
2008-02-03 11:28:36 +01:00
*/
# include <fstream>
# include <iostream>
2010-02-22 17:33:38 +01:00
# include <cassert>
2010-10-20 14:47:03 +02:00
# include <sstream>
2011-01-13 19:10:16 +01:00
# include <cmath>
2008-02-03 11:28:36 +01:00
# include "ParsingDriver.hh"
# include "Statement.hh"
2010-04-06 11:07:19 +02:00
# include "ExprNode.hh"
2012-01-23 16:52:27 +01:00
# include "WarningConsolidation.hh"
2008-02-03 11:28:36 +01:00
bool
2018-07-31 11:48:08 +02:00
ParsingDriver : : symbol_exists_and_is_not_modfile_local_or_external_function ( const string & s )
2008-02-03 11:28:36 +01:00
{
if ( ! mod_file - > symbol_table . exists ( s ) )
return false ;
2009-02-26 11:46:54 +01:00
SymbolType type = mod_file - > symbol_table . getType ( s ) ;
2019-12-16 19:42:59 +01:00
return type ! = SymbolType : : modFileLocalVariable & & type ! = SymbolType : : externalFunction ;
2008-02-03 11:28:36 +01:00
}
2016-09-23 15:22:25 +02:00
void
ParsingDriver : : check_symbol_existence_in_model_block ( const string & name )
{
2022-05-04 16:01:34 +02:00
if ( ! mod_file - > symbol_table . exists ( name ) | | undeclared_model_vars . contains ( name ) )
2018-03-20 09:56:22 +01:00
undeclared_model_variable_error ( " Unknown symbol: " + name , name ) ;
2016-09-23 15:22:25 +02:00
}
2008-02-03 11:28:36 +01:00
void
ParsingDriver : : check_symbol_existence ( const string & name )
{
if ( ! mod_file - > symbol_table . exists ( name ) )
2017-04-03 18:06:15 +02:00
error ( " Unknown symbol: " + name + " . \n If referenced from the 'initval', 'endval', 'histval', or 'shocks' block, you can pass the 'nostrict' option to dynare to have this line ignored. " ) ;
2008-02-03 11:28:36 +01:00
}
2011-12-11 15:35:26 +01:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : check_symbol_is_parameter ( const string & name )
2011-12-11 15:35:26 +01:00
{
2018-07-31 11:48:08 +02:00
check_symbol_existence ( name ) ;
int symb_id = mod_file - > symbol_table . getID ( name ) ;
2018-07-17 18:34:07 +02:00
if ( mod_file - > symbol_table . getType ( symb_id ) ! = SymbolType : : parameter )
2018-07-31 11:48:08 +02:00
error ( name + " is not a parameter " ) ;
2011-12-11 15:35:26 +01:00
}
2008-02-03 11:28:36 +01:00
void
ParsingDriver : : set_current_data_tree ( DataTree * data_tree_arg )
{
data_tree = data_tree_arg ;
model_tree = dynamic_cast < ModelTree * > ( data_tree_arg ) ;
2009-07-07 16:20:48 +02:00
dynamic_model = dynamic_cast < DynamicModel * > ( data_tree_arg ) ;
2008-02-03 11:28:36 +01:00
}
void
ParsingDriver : : reset_data_tree ( )
{
set_current_data_tree ( & mod_file - > expressions_tree ) ;
}
2010-02-22 17:33:38 +01:00
void
ParsingDriver : : reset_current_external_function_options ( )
{
2018-10-02 18:10:12 +02:00
current_external_function_options . nargs = ExternalFunctionsTable : : defaultNargs ;
current_external_function_options . firstDerivSymbID = ExternalFunctionsTable : : IDNotSet ;
current_external_function_options . secondDerivSymbID = ExternalFunctionsTable : : IDNotSet ;
current_external_function_id = ExternalFunctionsTable : : IDNotSet ;
2010-02-22 17:33:38 +01:00
}
2018-07-31 12:23:56 +02:00
unique_ptr < ModFile >
2008-03-28 18:38:10 +01:00
ParsingDriver : : parse ( istream & in , bool debug )
2008-02-03 11:28:36 +01:00
{
2018-07-31 12:23:56 +02:00
mod_file = make_unique < ModFile > ( warnings ) ;
2008-02-03 11:28:36 +01:00
reset_data_tree ( ) ;
2009-01-22 16:05:38 +01:00
estim_params . init ( * data_tree ) ;
2016-05-10 18:01:00 +02:00
osr_params . init ( * data_tree ) ;
2010-02-22 17:33:38 +01:00
reset_current_external_function_options ( ) ;
2008-02-03 11:28:36 +01:00
2018-07-31 12:23:56 +02:00
lexer = make_unique < DynareFlex > ( & in ) ;
2008-03-28 18:21:45 +01:00
lexer - > set_debug ( debug ) ;
2008-02-03 11:28:36 +01:00
Dynare : : parser parser ( * this ) ;
2008-03-28 18:21:45 +01:00
parser . set_debug_level ( debug ) ;
2008-02-03 11:28:36 +01:00
parser . parse ( ) ;
2018-07-31 12:23:56 +02:00
return move ( mod_file ) ;
2008-02-03 11:28:36 +01:00
}
void
ParsingDriver : : error ( const Dynare : : parser : : location_type & l , const string & m )
{
2016-09-23 15:22:25 +02:00
create_error_string ( l , m , cerr ) ;
exit ( EXIT_FAILURE ) ;
}
void
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 ;
2013-05-31 18:19:12 +02:00
if ( l . begin . line = = l . end . line )
if ( l . begin . column = = l . end . column - 1 )
2016-09-23 15:22:25 +02:00
stream < < " , col " < < l . begin . column ;
2013-05-31 18:19:12 +02:00
else
2016-09-23 15:22:25 +02:00
stream < < " , cols " < < l . begin . column < < " - " < < l . end . column - 1 ;
2013-05-31 18:19:12 +02:00
else
2016-09-23 15:22:25 +02:00
stream < < " , col " < < l . begin . column < < " - "
2017-06-01 19:58:32 +02:00
< < " line " < < l . end . line < < " , col " < < l . end . column - 1 ;
2016-09-23 15:22:25 +02:00
stream < < " : " < < m < < endl ;
2008-02-03 11:28:36 +01:00
}
void
2017-03-27 16:20:50 +02:00
ParsingDriver : : create_error_string ( const Dynare : : parser : : location_type & l , const string & m , const string & var )
2008-02-03 11:28:36 +01:00
{
2017-03-27 16:20:50 +02:00
ostringstream stream ;
create_error_string ( l , m , stream ) ;
2018-06-04 12:48:09 +02:00
model_errors . emplace_back ( var , stream . str ( ) ) ;
2017-03-27 16:20:50 +02:00
}
void
ParsingDriver : : model_error ( const string & m , const string & var )
{
create_error_string ( location , m , var ) ;
2008-02-03 11:28:36 +01:00
}
2018-03-20 09:56:22 +01:00
void
ParsingDriver : : undeclared_model_variable_error ( const string & m , const string & var )
{
ostringstream stream ;
if ( ! nostrict )
{
stream < < " ERROR: " < < * location . begin . filename < < " : line " < < location . begin . line ;
if ( location . begin . line = = location . end . line )
if ( location . begin . column = = location . end . column - 1 )
stream < < " , col " < < location . begin . column ;
else
stream < < " , cols " < < location . begin . column < < " - " < < location . end . column - 1 ;
else
stream < < " , col " < < location . begin . column < < " - "
< < " line " < < location . end . line < < " , col " < < location . end . column - 1 ;
stream < < " : " ;
}
stream < < m ;
if ( nostrict )
stream < < " automatically declared exogenous. " ;
2018-06-04 12:48:09 +02:00
undeclared_model_variable_errors . emplace_back ( var , stream . str ( ) ) ;
2018-03-20 09:56:22 +01:00
}
2008-02-03 11:28:36 +01:00
void
ParsingDriver : : warning ( const string & m )
{
2013-02-26 16:50:05 +01:00
warnings < < " WARNING: " < < location < < " : " < < m < < endl ;
2008-02-03 11:28:36 +01:00
}
2022-03-29 16:44:04 +02:00
int
2018-07-31 11:48:08 +02:00
ParsingDriver : : declare_symbol ( const string & name , SymbolType type , const string & tex_name , const vector < pair < string , string > > & partition_value )
2008-02-03 11:28:36 +01:00
{
2022-03-29 16:44:04 +02:00
int symb_id ;
2008-02-03 11:28:36 +01:00
try
{
2022-03-29 16:44:04 +02:00
symb_id = mod_file - > symbol_table . addSymbol ( name , type , tex_name , partition_value ) ;
2008-02-03 11:28:36 +01:00
}
2009-12-16 18:13:23 +01:00
catch ( SymbolTable : : AlreadyDeclaredException & e )
2008-02-03 11:28:36 +01:00
{
if ( e . same_type )
2022-03-29 16:44:04 +02:00
{
warning ( " Symbol " + name + " declared twice. " ) ;
symb_id = mod_file - > symbol_table . getID ( name ) ;
}
2008-02-03 11:28:36 +01:00
else
2018-07-31 11:48:08 +02:00
error ( " Symbol " + name + " declared twice with different types! " ) ;
2008-02-03 11:28:36 +01:00
}
2022-03-29 16:44:04 +02:00
return symb_id ;
2008-02-03 11:28:36 +01:00
}
2022-03-29 16:44:04 +02:00
int
2018-07-31 11:48:08 +02:00
ParsingDriver : : declare_endogenous ( const string & name , const string & tex_name , const vector < pair < string , string > > & partition_value )
2008-02-03 11:28:36 +01:00
{
2022-03-29 16:44:04 +02:00
return declare_symbol ( name , SymbolType : : endogenous , tex_name , partition_value ) ;
2008-02-03 11:28:36 +01:00
}
2022-03-28 18:11:53 +02:00
void
2022-03-30 17:40:01 +02:00
ParsingDriver : : var ( const vector < tuple < string , string , vector < pair < string , string > > > > & symbol_list ,
bool log_option )
2022-03-28 18:11:53 +02:00
{
for ( auto & [ name , tex_name , partition ] : symbol_list )
2022-03-30 17:40:01 +02:00
{
int symb_id = declare_endogenous ( name , tex_name , partition ) ;
if ( log_option )
mod_file - > symbol_table . markWithLogTransform ( symb_id ) ;
}
2022-03-28 18:11:53 +02:00
}
2022-03-29 16:44:04 +02:00
int
2018-07-31 11:48:08 +02:00
ParsingDriver : : declare_exogenous ( const string & name , const string & tex_name , const vector < pair < string , string > > & partition_value )
2008-02-03 11:28:36 +01:00
{
2022-03-29 16:44:04 +02:00
return declare_symbol ( name , SymbolType : : exogenous , tex_name , partition_value ) ;
2008-02-03 11:28:36 +01:00
}
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : varexo ( const vector < tuple < string , string , vector < pair < string , string > > > > & symbol_list )
{
for ( auto & [ name , tex_name , partition ] : symbol_list )
declare_exogenous ( name , tex_name , partition ) ;
}
void
ParsingDriver : : varexo_det ( const vector < tuple < string , string , vector < pair < string , string > > > > & symbol_list )
2008-02-03 11:28:36 +01:00
{
2022-03-28 18:11:53 +02:00
for ( auto & [ name , tex_name , partition ] : symbol_list )
declare_symbol ( name , SymbolType : : exogenousDet , tex_name , partition ) ;
2008-02-03 11:28:36 +01:00
}
2022-03-29 16:44:04 +02:00
int
2018-07-31 11:48:08 +02:00
ParsingDriver : : declare_parameter ( const string & name , const string & tex_name , const vector < pair < string , string > > & partition_value )
2008-02-03 11:28:36 +01:00
{
2022-03-29 16:44:04 +02:00
return declare_symbol ( name , SymbolType : : parameter , tex_name , partition_value ) ;
2008-02-03 11:28:36 +01:00
}
2022-03-28 18:11:53 +02:00
void
ParsingDriver : : parameters ( const vector < tuple < string , string , vector < pair < string , string > > > > & symbol_list )
{
for ( auto & [ name , tex_name , partition ] : symbol_list )
declare_parameter ( name , tex_name , partition ) ;
}
2011-12-14 13:58:21 +01:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : declare_statement_local_variable ( const string & name )
2011-12-14 13:58:21 +01:00
{
2018-07-31 11:48:08 +02:00
if ( mod_file - > symbol_table . exists ( name ) )
error ( " Symbol " + name + " cannot be assigned within a statement "
2017-06-01 19:58:32 +02:00
+ " while being assigned elsewhere in the modfile " ) ;
2018-07-31 11:48:08 +02:00
declare_symbol ( name , SymbolType : : statementDeclaredVariable , " " , { } ) ;
2011-12-14 13:58:21 +01:00
}
2011-03-29 18:18:32 +02:00
void
2019-12-18 17:32:41 +01:00
ParsingDriver : : set_planner_discount ( expr_t value )
2011-03-29 18:18:32 +02:00
{
2019-12-18 17:32:41 +01:00
planner_discount = value ;
}
void
ParsingDriver : : set_planner_discount_latex_name ( string tex_name )
{
planner_discount_latex_name = move ( tex_name ) ;
2011-03-29 18:18:32 +02:00
}
2010-10-15 19:05:16 +02:00
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : end_trend_var ( bool log_trend , expr_t growth_factor , const vector < pair < string , string > > & symbol_list )
2010-10-15 19:05:16 +02:00
{
2022-03-28 18:11:53 +02:00
vector < int > declared_trend_vars ;
for ( auto & [ name , tex_name ] : symbol_list )
{
2022-03-29 16:44:04 +02:00
int symb_id = declare_symbol ( name , log_trend ? SymbolType : : logTrend : SymbolType : : trend , tex_name , { } ) ;
declared_trend_vars . push_back ( symb_id ) ;
2022-03-28 18:11:53 +02:00
}
2010-10-15 19:05:16 +02:00
try
{
dynamic_model - > addTrendVariables ( declared_trend_vars , growth_factor ) ;
}
catch ( DataTree : : TrendException & e )
{
error ( " Trend variable " + e . name + " was declared twice. " ) ;
}
declared_trend_vars . clear ( ) ;
reset_data_tree ( ) ;
}
2009-11-07 19:37:11 +01:00
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : predetermined_variables ( const vector < string > & symbol_list )
2009-11-07 19:37:11 +01:00
{
2022-03-28 18:11:53 +02:00
for ( auto & name : symbol_list )
{
check_symbol_is_endogenous ( name ) ;
int symb_id = mod_file - > symbol_table . getID ( name ) ;
mod_file - > symbol_table . markPredetermined ( symb_id ) ;
}
2009-11-07 19:37:11 +01:00
}
2009-09-02 16:37:59 +02:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_equation_tags ( string key , string value )
2009-09-02 16:37:59 +02:00
{
2022-05-04 16:01:34 +02:00
if ( eq_tags . contains ( key ) )
2021-07-20 14:56:48 +02:00
error ( " Tag ' " + key + " ' cannot be declared twice for the same equation " ) ;
2020-02-20 15:29:10 +01:00
eq_tags [ key ] = value ;
2018-07-09 14:39:13 +02:00
2018-07-31 11:48:08 +02:00
transform ( key . begin ( ) , key . end ( ) , key . begin ( ) , : : tolower ) ;
2022-07-20 10:44:29 +02:00
if ( key = = " endogenous " )
2018-07-17 18:34:07 +02:00
declare_or_change_type ( SymbolType : : endogenous , value ) ;
2009-09-02 16:37:59 +02:00
}
2010-09-16 19:18:45 +02:00
expr_t
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_non_negative_constant ( const string & constant )
2008-02-03 11:28:36 +01:00
{
2018-07-31 11:48:08 +02:00
return data_tree - > AddNonNegativeConstant ( constant ) ;
2008-02-03 11:28:36 +01:00
}
2010-09-16 19:18:45 +02:00
expr_t
2009-01-22 16:05:38 +01:00
ParsingDriver : : add_nan_constant ( )
{
return data_tree - > NaN ;
}
2010-09-16 19:18:45 +02:00
expr_t
2009-01-22 16:05:38 +01:00
ParsingDriver : : add_inf_constant ( )
{
return data_tree - > Infinity ;
}
2010-09-16 19:18:45 +02:00
expr_t
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_model_variable ( const string & name )
2008-02-03 11:28:36 +01:00
{
2019-10-08 16:06:01 +02:00
if ( name . find ( " . " ) ! = string : : npos )
error ( name + " treated as a variable, but it contains a '.' " ) ;
2018-07-31 11:48:08 +02:00
check_symbol_existence_in_model_block ( name ) ;
2016-09-23 15:22:25 +02:00
int symb_id ;
try
{
2018-07-31 11:48:08 +02:00
symb_id = mod_file - > symbol_table . getID ( name ) ;
2021-12-14 17:24:14 +01:00
if ( mod_file - > symbol_table . getType ( symb_id ) = = SymbolType : : excludedVariable )
2021-12-14 18:10:10 +01:00
error ( " Variable ' " + name + " ' can no longer be used since it has been excluded by a previous 'model_remove' or 'var_remove' statement " ) ;
2016-09-23 15:22:25 +02:00
}
catch ( SymbolTable : : UnknownSymbolNameException & e )
{
2021-11-19 17:32:45 +01:00
/* Declare variable as exogenous to continue parsing. Processing will end
at end of model block ( or planner_objective statement ) if nostrict
option was not passed . */
2022-03-29 16:44:04 +02:00
symb_id = declare_exogenous ( name ) ;
2018-07-31 11:48:08 +02:00
undeclared_model_vars . insert ( name ) ;
2016-09-23 15:22:25 +02:00
}
2010-02-22 17:33:38 +01:00
return add_model_variable ( symb_id , 0 ) ;
2008-02-03 11:28:36 +01:00
}
2017-03-27 16:20:50 +02:00
expr_t
2018-07-31 11:48:08 +02:00
ParsingDriver : : declare_or_change_type ( SymbolType new_type , const string & name )
2017-03-27 16:20:50 +02:00
{
int symb_id ;
try
{
2018-07-31 11:48:08 +02:00
symb_id = mod_file - > symbol_table . getID ( name ) ;
2017-03-27 16:20:50 +02:00
mod_file - > symbol_table . changeType ( symb_id , new_type ) ;
// remove error messages
2018-07-31 11:48:08 +02:00
undeclared_model_vars . erase ( name ) ;
2022-05-04 16:25:58 +02:00
erase_if ( undeclared_model_variable_errors ,
[ & name ] ( auto & v ) { return v . first = = name ; } ) ;
2017-03-27 16:20:50 +02:00
}
catch ( SymbolTable : : UnknownSymbolNameException & e )
{
switch ( new_type )
{
2018-07-17 18:34:07 +02:00
case SymbolType : : endogenous :
2022-03-29 16:44:04 +02:00
symb_id = declare_endogenous ( name ) ;
2017-03-27 16:20:50 +02:00
break ;
2018-07-17 18:34:07 +02:00
case SymbolType : : exogenous :
2022-03-29 16:44:04 +02:00
symb_id = declare_exogenous ( name ) ;
2017-03-27 16:20:50 +02:00
break ;
2018-07-17 18:34:07 +02:00
case SymbolType : : parameter :
2022-03-29 16:44:04 +02:00
symb_id = declare_parameter ( name ) ;
2017-03-27 16:20:50 +02:00
break ;
default :
error ( " Type not yet supported " ) ;
}
}
return add_model_variable ( symb_id , 0 ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
2010-02-22 17:33:38 +01:00
ParsingDriver : : add_model_variable ( int symb_id , int lag )
2008-02-03 11:28:36 +01:00
{
2010-02-22 17:33:38 +01:00
assert ( symb_id > = 0 ) ;
SymbolType type = mod_file - > symbol_table . getType ( symb_id ) ;
2008-02-03 11:28:36 +01:00
2018-07-17 18:34:07 +02:00
if ( type = = SymbolType : : modFileLocalVariable )
2019-12-20 16:59:30 +01:00
error ( " Variable " + mod_file - > symbol_table . getName ( symb_id )
+ " not allowed inside model declaration. Its scope is only outside model. " ) ;
2008-02-03 11:28:36 +01:00
2018-07-17 18:34:07 +02:00
if ( type = = SymbolType : : externalFunction )
2019-12-20 16:59:30 +01:00
error ( " Symbol " + mod_file - > symbol_table . getName ( symb_id )
+ " is a function name external to Dynare. It cannot be used like a variable without input argument inside model. " ) ;
2008-10-13 18:44:20 +02:00
2021-01-22 11:59:44 +01:00
// See dynare#1765
if ( type = = SymbolType : : exogenousDet & & lag ! = 0 )
error ( " Exogenous deterministic variable " + mod_file - > symbol_table . getName ( symb_id ) + " cannot be given a lead or a lag. " ) ;
2018-07-17 18:34:07 +02:00
if ( type = = SymbolType : : modelLocalVariable & & lag ! = 0 )
2010-02-22 17:33:38 +01:00
error ( " Model local variable " + mod_file - > symbol_table . getName ( symb_id ) + " cannot be given a lead or a lag. " ) ;
2008-10-13 18:44:20 +02:00
2021-07-21 16:16:39 +02:00
if ( data_tree = = planner_objective . get ( ) )
{
if ( lag ! = 0 )
error ( " Leads and lags on variables are forbidden in 'planner_objective'. " ) ;
if ( type = = SymbolType : : modelLocalVariable )
error ( " Model local variable " + mod_file - > symbol_table . getName ( symb_id ) + " cannot be used in 'planner_objective'. " ) ;
}
2010-10-11 14:49:23 +02:00
2021-07-21 16:16:39 +02:00
if ( data_tree = = occbin_constraints_tree . get ( ) )
{
if ( lag ! = 0 )
error ( " Leads and lags on variables are forbidden in 'occbin_constraints'. Note that you can achieve the same effect by introducing an auxiliary variable in the model. " ) ;
if ( type = = SymbolType : : modelLocalVariable )
error ( " Model local variable " + mod_file - > symbol_table . getName ( symb_id ) + " cannot be used in 'occbin_constraints'. " ) ;
if ( type = = SymbolType : : exogenous | | type = = SymbolType : : exogenousDet )
error ( " Exogenous variable " + mod_file - > symbol_table . getName ( symb_id ) + " cannot be used in 'occbin_constraints'. " ) ;
}
2014-05-13 11:46:19 +02:00
2008-10-13 18:44:20 +02:00
// It makes sense to allow a lead/lag on parameters: during steady state calibration, endogenous and parameters can be swapped
2021-07-21 16:16:39 +02:00
// NB: we use data_tree here, to avoid a crash in the occbin_constraints case
return data_tree - > AddVariable ( symb_id , lag ) ;
2008-02-03 11:28:36 +01:00
}
2010-09-16 19:18:45 +02:00
expr_t
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_expression_variable ( const string & name )
2008-02-03 11:28:36 +01:00
{
2019-10-08 16:06:01 +02:00
if ( name . find ( " . " ) ! = string : : npos )
error ( name + " treated as a variable, but it contains a '.' " ) ;
2018-09-03 17:16:28 +02:00
if ( parsing_epilogue & & ! mod_file - > symbol_table . exists ( name ) )
error ( " Variable " + name + " used in the epilogue block but was not declared. " ) ;
2008-02-03 11:28:36 +01:00
// If symbol doesn't exist, then declare it as a mod file local variable
2018-07-31 11:48:08 +02:00
if ( ! mod_file - > symbol_table . exists ( name ) )
mod_file - > symbol_table . addSymbol ( name , SymbolType : : modFileLocalVariable ) ;
2008-02-03 11:28:36 +01:00
2008-10-17 14:22:35 +02:00
// This check must come after the previous one!
2018-07-31 11:48:08 +02:00
if ( mod_file - > symbol_table . getType ( name ) = = SymbolType : : modelLocalVariable )
error ( " Variable " + name + " not allowed outside model declaration. Its scope is only inside model. " ) ;
2013-11-29 16:29:25 +01:00
2018-07-31 11:48:08 +02:00
if ( mod_file - > symbol_table . getType ( name ) = = SymbolType : : trend
| | mod_file - > symbol_table . getType ( name ) = = SymbolType : : logTrend )
error ( " Variable " + name + " not allowed outside model declaration, because it is a trend variable. " ) ;
2014-02-03 16:22:42 +01:00
2018-07-31 11:48:08 +02:00
if ( mod_file - > symbol_table . getType ( name ) = = SymbolType : : externalFunction )
error ( " Symbol ' " + name + " ' is the name of a MATLAB/Octave function, and cannot be used as a variable. " ) ;
2008-02-03 11:28:36 +01:00
2018-07-31 11:48:08 +02:00
int symb_id = mod_file - > symbol_table . getID ( name ) ;
return data_tree - > AddVariable ( symb_id ) ;
2008-02-03 11:28:36 +01:00
}
2010-10-15 19:05:16 +02:00
void
2022-03-30 17:40:01 +02:00
ParsingDriver : : end_nonstationary_var ( bool log_deflator , expr_t deflator , const vector < tuple < string , string , vector < pair < string , string > > > > & symbol_list , bool log_option )
2010-10-15 19:05:16 +02:00
{
mod_file - > nonstationary_variables = true ;
2022-03-28 18:11:53 +02:00
vector < int > declared_nonstationary_vars ;
for ( auto & [ name , tex_name , partition ] : symbol_list )
{
2022-03-29 16:44:04 +02:00
int symb_id = declare_endogenous ( name , tex_name , partition ) ;
declared_nonstationary_vars . push_back ( symb_id ) ;
2022-03-30 17:40:01 +02:00
if ( log_option )
mod_file - > symbol_table . markWithLogTransform ( symb_id ) ;
2022-03-28 18:11:53 +02:00
}
2010-10-15 19:05:16 +02:00
try
{
2013-03-26 16:46:18 +01:00
dynamic_model - > addNonstationaryVariables ( declared_nonstationary_vars , log_deflator , deflator ) ;
2010-10-15 19:05:16 +02:00
}
catch ( DataTree : : TrendException & e )
{
error ( " Variable " + e . name + " was listed more than once as following a trend. " ) ;
}
2013-10-29 11:47:59 +01:00
2013-11-29 15:32:49 +01:00
set < int > r ;
2018-07-17 18:34:07 +02:00
deflator - > collectVariables ( SymbolType : : endogenous , r ) ;
2018-06-04 12:26:16 +02:00
for ( int it : r )
if ( dynamic_model - > isNonstationary ( it ) )
2013-10-29 11:47:59 +01:00
error ( " The deflator contains a non-stationary endogenous variable. This is not allowed. Please use only stationary endogenous and/or {log_}trend_vars. " ) ;
2010-10-15 19:05:16 +02:00
declared_nonstationary_vars . clear ( ) ;
reset_data_tree ( ) ;
}
2008-02-03 11:28:36 +01:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : dsample ( const string & arg1 )
2008-02-03 11:28:36 +01:00
{
2018-07-31 11:48:08 +02:00
int arg1_val = stoi ( arg1 ) ;
2018-09-05 15:17:21 +02:00
mod_file - > addStatement ( make_unique < DsampleStatement > ( arg1_val ) ) ;
2008-02-03 11:28:36 +01:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : dsample ( const string & arg1 , const string & arg2 )
2008-02-03 11:28:36 +01:00
{
2018-07-31 11:48:08 +02:00
int arg1_val = stoi ( arg1 ) ;
int arg2_val = stoi ( arg2 ) ;
2018-09-05 15:17:21 +02:00
mod_file - > addStatement ( make_unique < DsampleStatement > ( arg1_val , arg2_val ) ) ;
2008-02-03 11:28:36 +01:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : init_param ( const string & name , expr_t rhs )
2008-02-03 11:28:36 +01:00
{
2011-12-11 15:35:26 +01:00
check_symbol_is_parameter ( name ) ;
2018-07-31 11:48:08 +02:00
int symb_id = mod_file - > symbol_table . getID ( name ) ;
2018-09-05 15:17:21 +02:00
mod_file - > addStatement ( make_unique < InitParamStatement > ( symb_id , rhs , mod_file - > symbol_table ) ) ;
2008-02-03 11:28:36 +01:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : init_val ( const string & name , expr_t rhs )
2008-02-03 11:28:36 +01:00
{
2022-06-02 10:50:21 +02:00
if ( nostrict & & ! mod_file - > symbol_table . exists ( name ) )
{
warning ( " discarding ' " + name + " ' as it was not recognized in the initval statement " ) ;
return ;
}
2013-09-16 22:13:56 +02:00
2022-04-21 17:59:04 +02:00
check_symbol_is_endogenous_or_exogenous ( name , true ) ;
2018-07-31 11:48:08 +02:00
int symb_id = mod_file - > symbol_table . getID ( name ) ;
2018-06-04 16:36:46 +02:00
init_values . emplace_back ( symb_id , rhs ) ;
2008-02-03 11:28:36 +01:00
}
void
2020-05-14 16:36:35 +02:00
ParsingDriver : : initval_file ( )
2008-02-03 11:28:36 +01:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < InitvalFileStatement > ( move ( options_list ) ) ) ;
2020-05-14 16:36:35 +02:00
options_list . clear ( ) ;
2008-02-03 11:28:36 +01:00
}
2022-05-03 16:52:04 +02:00
void
ParsingDriver : : end_val ( EndValLearntInStatement : : LearntEndValType type , const string & name , expr_t rhs )
{
2022-06-02 10:50:21 +02:00
if ( nostrict & & ! mod_file - > symbol_table . exists ( name ) )
{
warning ( " discarding ' " + name + " ' as it was not recognized in the endval statement " ) ;
return ;
}
2022-05-03 16:52:04 +02:00
check_symbol_is_endogenous_or_exogenous ( name , false ) ;
int symb_id = mod_file - > symbol_table . getID ( name ) ;
end_values . emplace_back ( type , symb_id , rhs ) ;
}
2008-02-03 11:28:36 +01:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : hist_val ( const string & name , const string & lag , expr_t rhs )
2008-02-03 11:28:36 +01:00
{
2022-06-02 10:50:21 +02:00
if ( nostrict & & ! mod_file - > symbol_table . exists ( name ) )
{
warning ( " discarding ' " + name + " ' as it was not recognized in the histval block " ) ;
return ;
}
2017-04-03 16:44:31 +02:00
2022-04-21 17:59:04 +02:00
check_symbol_is_endogenous_or_exogenous ( name , true ) ;
2018-07-31 11:48:08 +02:00
int symb_id = mod_file - > symbol_table . getID ( name ) ;
2008-02-03 11:28:36 +01:00
2018-07-31 11:48:08 +02:00
int ilag = stoi ( lag ) ;
2017-09-13 10:16:19 +02:00
if ( ilag > 0 )
2018-07-31 11:48:08 +02:00
error ( " histval: the lag on " + name + " should be less than or equal to 0 " ) ;
2017-09-13 10:16:19 +02:00
2022-06-03 16:21:30 +02:00
pair key { symb_id , ilag } ;
2008-02-03 11:28:36 +01:00
2022-05-04 16:01:34 +02:00
if ( hist_values . contains ( key ) )
2018-07-31 11:48:08 +02:00
error ( " hist_val: ( " + name + " , " + lag + " ) declared twice " ) ;
2008-02-03 11:28:36 +01:00
2021-07-22 16:37:18 +02:00
hist_values [ move ( key ) ] = rhs ;
2008-02-03 11:28:36 +01:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : homotopy_val ( const string & name , expr_t val1 , expr_t val2 )
2008-02-03 11:28:36 +01:00
{
2018-07-31 11:48:08 +02:00
check_symbol_existence ( name ) ;
int symb_id = mod_file - > symbol_table . getID ( name ) ;
2009-02-27 13:19:25 +01:00
SymbolType type = mod_file - > symbol_table . getType ( symb_id ) ;
2008-02-03 11:28:36 +01:00
2018-07-17 18:34:07 +02:00
if ( type ! = SymbolType : : parameter
& & type ! = SymbolType : : exogenous
& & type ! = SymbolType : : exogenousDet )
2018-07-31 11:48:08 +02:00
error ( " homotopy_val: " + name + " should be a parameter or exogenous variable " ) ;
2008-02-03 11:28:36 +01:00
2018-12-03 15:05:49 +01:00
homotopy_values . emplace_back ( symb_id , val1 , val2 ) ;
2008-02-03 11:28:36 +01:00
}
2017-10-06 14:49:14 +02:00
void
ParsingDriver : : end_generate_irfs ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < GenerateIRFsStatement > ( move ( options_list ) ,
move ( generate_irf_names ) ,
move ( generate_irf_elements ) ) ) ;
2017-10-09 11:18:42 +02:00
2017-10-06 14:49:14 +02:00
generate_irf_elements . clear ( ) ;
generate_irf_names . clear ( ) ;
options_list . clear ( ) ;
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_generate_irfs_element ( string name )
2017-10-06 14:49:14 +02:00
{
2018-07-31 11:48:08 +02:00
for ( const auto & it : generate_irf_names )
if ( it = = name )
2017-10-09 11:18:42 +02:00
error ( " Names in the generate_irfs block must be unique but you entered ' "
2018-07-31 11:48:08 +02:00
+ name + " ' more than once. " ) ;
2017-10-06 14:49:14 +02:00
2018-07-31 11:48:08 +02:00
generate_irf_names . push_back ( move ( name ) ) ;
2017-10-09 11:18:42 +02:00
generate_irf_elements . push_back ( generate_irf_exos ) ;
generate_irf_exos . clear ( ) ;
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_generate_irfs_exog_element ( string exo , const string & value )
2017-10-09 11:18:42 +02:00
{
2022-04-21 17:59:04 +02:00
check_symbol_is_exogenous ( exo , false ) ;
2022-05-04 16:01:34 +02:00
if ( generate_irf_exos . contains ( exo ) )
2018-07-31 11:48:08 +02:00
error ( " You have set the exogenous variable " + exo + " twice. " ) ;
2017-10-09 11:18:42 +02:00
2018-07-31 11:48:08 +02:00
generate_irf_exos [ move ( exo ) ] = stod ( value ) ;
2017-10-06 14:49:14 +02:00
}
2008-05-01 14:04:48 +02:00
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : forecast ( vector < string > symbol_list )
2008-05-01 14:04:48 +02:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < ForecastStatement > ( move ( symbol_list ) , move ( options_list ) ,
2022-03-28 18:11:53 +02:00
mod_file - > symbol_table ) ) ;
2008-05-01 14:04:48 +02:00
options_list . clear ( ) ;
}
2008-02-03 11:28:36 +01:00
void
ParsingDriver : : use_dll ( )
{
2009-09-02 15:36:56 +02:00
mod_file - > use_dll = true ;
2008-02-03 11:28:36 +01:00
}
void
2009-08-29 17:04:11 +02:00
ParsingDriver : : block ( )
2008-02-03 11:28:36 +01:00
{
2009-08-29 17:04:11 +02:00
mod_file - > block = true ;
2008-02-03 11:28:36 +01:00
}
2010-01-08 12:06:25 +01:00
void
ParsingDriver : : no_static ( )
{
mod_file - > no_static = true ;
}
2008-02-03 11:28:36 +01:00
void
2020-05-20 11:39:59 +02:00
ParsingDriver : : bytecode ( )
2008-02-03 11:28:36 +01:00
{
2020-05-20 11:39:59 +02:00
mod_file - > bytecode = true ;
2008-02-03 11:28:36 +01:00
}
2013-04-25 18:09:31 +02:00
void
2013-05-17 16:51:34 +02:00
ParsingDriver : : differentiate_forward_vars_all ( )
2013-04-25 18:09:31 +02:00
{
mod_file - > differentiate_forward_vars = true ;
}
2013-05-17 16:51:34 +02:00
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : differentiate_forward_vars_some ( vector < string > symbol_list )
2013-05-17 16:51:34 +02:00
{
mod_file - > differentiate_forward_vars = true ;
2022-03-28 18:11:53 +02:00
mod_file - > differentiate_forward_vars_subset = move ( symbol_list ) ;
2019-12-20 16:59:30 +01:00
for ( auto & it : mod_file - > differentiate_forward_vars_subset )
2019-12-16 19:42:59 +01:00
check_symbol_is_endogenous ( it ) ;
2013-05-17 16:51:34 +02:00
}
2009-09-03 12:10:06 +02:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : cutoff ( const string & value )
2009-09-03 12:10:06 +02:00
{
2018-07-31 11:48:08 +02:00
double val = stod ( value ) ;
2009-09-03 12:10:06 +02:00
mod_file - > dynamic_model . cutoff = val ;
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : mfs ( const string & value )
2009-09-03 12:10:06 +02:00
{
2018-07-31 11:48:08 +02:00
int val = stoi ( value ) ;
2009-09-03 12:10:06 +02:00
mod_file - > dynamic_model . mfs = val ;
}
2019-12-02 19:21:14 +01:00
void
2019-12-20 16:59:30 +01:00
ParsingDriver : : compilation_setup_substitute_flags ( const string & flags )
2019-12-02 19:21:14 +01:00
{
mod_file - > dynamic_model . user_set_subst_flags = flags ;
}
void
2019-12-20 16:59:30 +01:00
ParsingDriver : : compilation_setup_add_flags ( const string & flags )
2019-12-02 19:21:14 +01:00
{
mod_file - > dynamic_model . user_set_add_flags = flags ;
}
void
2019-12-20 16:59:30 +01:00
ParsingDriver : : compilation_setup_substitute_libs ( const string & libs )
2019-12-02 19:21:14 +01:00
{
mod_file - > dynamic_model . user_set_subst_libs = libs ;
}
void
2019-12-20 16:59:30 +01:00
ParsingDriver : : compilation_setup_add_libs ( const string & libs )
2019-12-02 19:21:14 +01:00
{
mod_file - > dynamic_model . user_set_add_libs = libs ;
}
void
2019-12-20 16:59:30 +01:00
ParsingDriver : : compilation_setup_compiler ( const string & compiler )
2019-12-02 19:21:14 +01:00
{
mod_file - > dynamic_model . user_set_compiler = compiler ;
}
2019-11-14 17:51:16 +01:00
void
ParsingDriver : : balanced_growth_test_tol ( const string & value )
{
mod_file - > dynamic_model . balanced_growth_test_tol = stod ( value ) ;
}
2008-02-03 11:28:36 +01:00
void
2012-10-31 15:23:02 +01:00
ParsingDriver : : end_initval ( bool all_values_required )
2008-02-03 11:28:36 +01:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < InitValStatement > ( move ( init_values ) , mod_file - > symbol_table ,
all_values_required ) ) ;
2009-02-27 13:19:25 +01:00
init_values . clear ( ) ;
2008-02-03 11:28:36 +01:00
}
void
2012-10-31 15:23:02 +01:00
ParsingDriver : : end_endval ( bool all_values_required )
2008-02-03 11:28:36 +01:00
{
2022-05-03 16:52:04 +02:00
InitOrEndValStatement : : init_values_t end_values_new ;
for ( auto [ type , symb_id , value ] : end_values )
switch ( type )
{
case EndValLearntInStatement : : LearntEndValType : : level :
end_values_new . emplace_back ( symb_id , value ) ;
break ;
case EndValLearntInStatement : : LearntEndValType : : add :
error ( " endval: ' " + mod_file - > symbol_table . getName ( symb_id ) + " += ...' line not allowed unless 'learnt_in' option with value >1 is passed " ) ;
case EndValLearntInStatement : : LearntEndValType : : multiply :
error ( " endval: ' " + mod_file - > symbol_table . getName ( symb_id ) + " *= ...' line not allowed unless 'learnt_in' option with value >1 is passed " ) ;
}
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < EndValStatement > ( move ( end_values_new ) , mod_file - > symbol_table ,
all_values_required ) ) ;
2022-05-03 16:52:04 +02:00
end_values . clear ( ) ;
2008-02-03 11:28:36 +01:00
}
2022-04-20 16:57:39 +02:00
void
ParsingDriver : : end_endval_learnt_in ( const string & learnt_in_period )
{
2022-04-26 11:45:22 +02:00
int learnt_in_period_int = stoi ( learnt_in_period ) ;
2022-04-29 11:17:11 +02:00
if ( learnt_in_period_int < 1 )
2022-04-26 11:45:22 +02:00
error ( " endval: value ' " + learnt_in_period + " ' is not allowed for 'learnt_in' option " ) ;
2022-04-29 11:17:11 +02:00
if ( learnt_in_period_int = = 1 )
{
end_endval ( false ) ;
return ;
}
2022-05-03 16:52:04 +02:00
for ( auto [ type , symb_id , value ] : end_values )
2022-04-20 16:57:39 +02:00
if ( mod_file - > symbol_table . getType ( symb_id ) ! = SymbolType : : exogenous )
error ( " endval(learnt_in=...): " + mod_file - > symbol_table . getName ( symb_id ) + " is not an exogenous variable " ) ;
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < EndValLearntInStatement > ( learnt_in_period_int , move ( end_values ) ,
mod_file - > symbol_table ) ) ;
2022-05-03 16:52:04 +02:00
end_values . clear ( ) ;
2022-04-20 16:57:39 +02:00
}
2008-02-03 11:28:36 +01:00
void
2016-06-02 12:57:11 +02:00
ParsingDriver : : end_histval ( bool all_values_required )
2008-02-03 11:28:36 +01:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < HistValStatement > ( move ( hist_values ) , mod_file - > symbol_table ,
all_values_required ) ) ;
2008-02-03 11:28:36 +01:00
hist_values . clear ( ) ;
}
void
ParsingDriver : : end_homotopy ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < HomotopyStatement > ( move ( homotopy_values ) , mod_file - > symbol_table ) ) ;
2008-02-03 11:28:36 +01:00
homotopy_values . clear ( ) ;
}
2018-09-03 17:16:28 +02:00
void
ParsingDriver : : begin_epilogue ( )
{
parsing_epilogue = true ;
set_current_data_tree ( & mod_file - > epilogue ) ;
}
void
ParsingDriver : : end_epilogue ( )
{
parsing_epilogue = false ;
reset_data_tree ( ) ;
}
void
2018-12-19 16:09:30 +01:00
ParsingDriver : : add_epilogue_variable ( const string & name )
2018-09-03 17:16:28 +02:00
{
2018-12-10 16:11:21 +01:00
declare_symbol ( name , SymbolType : : epilogue , " " , { } ) ;
2018-12-19 16:09:30 +01:00
}
void
ParsingDriver : : add_epilogue_equal ( const string & name , expr_t expr )
{
2018-12-10 16:11:21 +01:00
mod_file - > epilogue . addDefinition ( mod_file - > symbol_table . getID ( name ) , expr ) ;
2018-09-03 17:16:28 +02:00
}
2008-02-03 11:28:36 +01:00
void
ParsingDriver : : begin_model ( )
{
2009-04-14 16:39:53 +02:00
set_current_data_tree ( & mod_file - > dynamic_model ) ;
2008-02-03 11:28:36 +01:00
}
2016-09-23 15:22:25 +02:00
void
ParsingDriver : : end_model ( )
{
2018-03-20 09:56:22 +01:00
bool exit_after_write = false ;
2017-03-27 16:20:50 +02:00
if ( model_errors . size ( ) > 0 )
2019-12-20 16:59:30 +01:00
for ( auto & it : model_errors )
2018-03-20 09:56:22 +01:00
{
2019-12-16 19:42:59 +01:00
if ( it . first . empty ( ) )
2018-03-20 09:56:22 +01:00
exit_after_write = true ;
2019-12-16 19:42:59 +01:00
cerr < < it . second ;
2018-03-20 09:56:22 +01:00
}
2017-04-03 14:52:20 +02:00
2018-03-20 09:56:22 +01:00
if ( undeclared_model_variable_errors . size ( ) > 0 )
2019-12-20 16:59:30 +01:00
for ( auto & it : undeclared_model_variable_errors )
2018-03-20 09:56:22 +01:00
if ( nostrict )
2019-12-16 19:42:59 +01:00
warning ( it . second ) ;
2018-03-20 09:56:22 +01:00
else
{
exit_after_write = true ;
2019-12-16 19:42:59 +01:00
cerr < < it . second < < endl ;
2017-04-03 14:52:20 +02:00
}
2021-11-19 17:32:45 +01:00
undeclared_model_variable_errors . clear ( ) ;
2018-03-20 09:56:22 +01:00
if ( exit_after_write )
exit ( EXIT_FAILURE ) ;
2016-09-23 15:22:25 +02:00
reset_data_tree ( ) ;
}
2008-02-03 11:28:36 +01:00
void
2014-04-10 11:54:49 +02:00
ParsingDriver : : end_shocks ( bool overwrite )
2008-02-03 11:28:36 +01:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < ShocksStatement > ( overwrite , move ( det_shocks ) , move ( var_shocks ) ,
move ( std_shocks ) , move ( covar_shocks ) ,
move ( corr_shocks ) , mod_file - > symbol_table ) ) ;
2008-02-03 11:28:36 +01:00
det_shocks . clear ( ) ;
2022-04-26 15:21:45 +02:00
if ( ! learnt_shocks_add . empty ( ) )
2022-04-29 11:17:11 +02:00
error ( " shocks: 'add' keyword not allowed unless 'learnt_in' option with value >1 is passed " ) ;
2022-04-26 15:21:45 +02:00
if ( ! learnt_shocks_multiply . empty ( ) )
2022-04-29 11:17:11 +02:00
error ( " shocks: 'multiply' keyword not allowed unless 'learnt_in' option with value >1 is passed " ) ;
2008-02-03 11:28:36 +01:00
var_shocks . clear ( ) ;
std_shocks . clear ( ) ;
covar_shocks . clear ( ) ;
corr_shocks . clear ( ) ;
}
void
2014-04-10 11:54:49 +02:00
ParsingDriver : : end_mshocks ( bool overwrite )
2008-02-03 11:28:36 +01:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < MShocksStatement > ( overwrite , move ( det_shocks ) ,
mod_file - > symbol_table ) ) ;
2021-07-13 17:07:53 +02:00
det_shocks . clear ( ) ;
2022-04-26 15:21:45 +02:00
if ( ! learnt_shocks_add . empty ( ) )
error ( " mshocks: 'add' keyword not allowed " ) ;
if ( ! learnt_shocks_multiply . empty ( ) )
error ( " mshocks: 'multiply' keyword not allowed " ) ;
2021-07-13 17:07:53 +02:00
}
void
ParsingDriver : : end_shocks_surprise ( bool overwrite )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < ShocksSurpriseStatement > ( overwrite , move ( det_shocks ) ,
mod_file - > symbol_table ) ) ;
2008-02-03 11:28:36 +01:00
det_shocks . clear ( ) ;
2022-04-26 15:21:45 +02:00
if ( ! learnt_shocks_add . empty ( ) )
error ( " shocks(surprise): 'add' keyword not allowed " ) ;
if ( ! learnt_shocks_multiply . empty ( ) )
error ( " shocks(surprise): 'multiply' keyword not allowed " ) ;
2008-02-03 11:28:36 +01:00
}
2022-04-20 16:57:39 +02:00
void
ParsingDriver : : end_shocks_learnt_in ( const string & learnt_in_period , bool overwrite )
{
int learnt_in_period_int = stoi ( learnt_in_period ) ;
2022-04-29 11:17:11 +02:00
if ( learnt_in_period_int < 1 )
2022-04-26 11:45:22 +02:00
error ( " shocks: value ' " + learnt_in_period + " ' is not allowed for 'learnt_in' option " ) ;
2022-04-29 11:17:11 +02:00
if ( learnt_in_period_int = = 1 )
{
end_shocks ( overwrite ) ;
return ;
}
2022-04-20 16:57:39 +02:00
for ( auto & [ symb_id , vals ] : det_shocks )
for ( auto [ period1 , period2 , expr ] : vals )
if ( period1 < learnt_in_period_int )
error ( " shocks: for variable " + mod_file - > symbol_table . getName ( symb_id ) + " , shock period ( " + to_string ( period1 ) + " ) is earlier than the period in which the shock is learnt ( " + learnt_in_period + " ) " ) ;
2022-04-26 15:21:45 +02:00
// Aggregate the three types of shocks
ShocksLearntInStatement : : learnt_shocks_t learnt_shocks ;
for ( const auto & [ id , v ] : det_shocks )
{
vector < tuple < ShocksLearntInStatement : : LearntShockType , int , int , expr_t > > v2 ;
for ( auto [ period1 , period2 , value ] : v )
v2 . emplace_back ( ShocksLearntInStatement : : LearntShockType : : level , period1 , period2 , value ) ;
learnt_shocks [ id ] = v2 ;
}
for ( const auto & [ id , v ] : learnt_shocks_add )
{
vector < tuple < ShocksLearntInStatement : : LearntShockType , int , int , expr_t > > v2 ;
for ( auto [ period1 , period2 , value ] : v )
v2 . emplace_back ( ShocksLearntInStatement : : LearntShockType : : add , period1 , period2 , value ) ;
learnt_shocks [ id ] = v2 ;
}
for ( const auto & [ id , v ] : learnt_shocks_multiply )
{
vector < tuple < ShocksLearntInStatement : : LearntShockType , int , int , expr_t > > v2 ;
for ( auto [ period1 , period2 , value ] : v )
v2 . emplace_back ( ShocksLearntInStatement : : LearntShockType : : multiply , period1 , period2 , value ) ;
learnt_shocks [ id ] = v2 ;
}
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < ShocksLearntInStatement > ( learnt_in_period_int , overwrite ,
move ( learnt_shocks ) ,
mod_file - > symbol_table ) ) ;
2022-04-20 16:57:39 +02:00
det_shocks . clear ( ) ;
2022-04-26 15:21:45 +02:00
learnt_shocks_add . clear ( ) ;
learnt_shocks_multiply . clear ( ) ;
2022-04-20 16:57:39 +02:00
}
2021-05-26 18:00:06 +02:00
void
ParsingDriver : : end_heteroskedastic_shocks ( bool overwrite )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < HeteroskedasticShocksStatement > ( overwrite ,
move ( heteroskedastic_shocks_values ) ,
move ( heteroskedastic_shocks_scales ) ,
mod_file - > symbol_table ) ) ;
2021-05-26 18:00:06 +02:00
heteroskedastic_shocks_values . clear ( ) ;
heteroskedastic_shocks_scales . clear ( ) ;
}
2008-02-03 11:28:36 +01:00
void
2022-04-26 15:21:45 +02:00
ParsingDriver : : add_det_shock ( const string & var , const vector < pair < int , int > > & periods , const vector < expr_t > & values , DetShockType type )
2008-02-03 11:28:36 +01:00
{
2022-04-26 15:21:45 +02:00
switch ( type )
{
case DetShockType : : conditional_forecast :
check_symbol_is_endogenous ( var ) ;
break ;
case DetShockType : : standard :
// Allow exo_det, for stochastic context
check_symbol_is_exogenous ( var , true ) ;
break ;
case DetShockType : : add :
case DetShockType : : multiply :
check_symbol_is_exogenous ( var , false ) ;
break ;
}
2018-08-01 10:47:09 +02:00
int symb_id = mod_file - > symbol_table . getID ( var ) ;
2008-02-03 11:28:36 +01:00
2022-05-04 16:01:34 +02:00
if ( det_shocks . contains ( symb_id ) | | learnt_shocks_add . contains ( symb_id )
| | learnt_shocks_multiply . contains ( symb_id ) )
2018-07-31 11:48:08 +02:00
error ( " shocks/conditional_forecast_paths: variable " + var + " declared twice " ) ;
2008-02-03 11:28:36 +01:00
2021-05-26 17:00:07 +02:00
if ( periods . size ( ) ! = values . size ( ) )
2018-07-31 11:48:08 +02:00
error ( " shocks/conditional_forecast_paths: variable " + var + " : number of periods is different from number of shock values " ) ;
2008-02-03 11:28:36 +01:00
2021-07-13 16:24:37 +02:00
vector < tuple < int , int , expr_t > > v ;
2008-02-03 11:28:36 +01:00
2021-05-26 17:00:07 +02:00
for ( size_t i = 0 ; i < periods . size ( ) ; i + + )
2021-07-13 16:24:37 +02:00
v . emplace_back ( periods [ i ] . first , periods [ i ] . second , values [ i ] ) ;
2008-02-03 11:28:36 +01:00
2022-04-26 15:21:45 +02:00
switch ( type )
{
case DetShockType : : standard :
case DetShockType : : conditional_forecast :
det_shocks [ symb_id ] = v ;
break ;
case DetShockType : : add :
learnt_shocks_add [ symb_id ] = v ;
break ;
case DetShockType : : multiply :
learnt_shocks_multiply [ symb_id ] = v ;
break ;
}
2008-02-03 11:28:36 +01:00
}
2021-05-26 18:00:06 +02:00
void
ParsingDriver : : add_heteroskedastic_shock ( const string & var , const vector < pair < int , int > > & periods , const vector < expr_t > & values , bool scales )
{
2022-04-21 17:59:04 +02:00
check_symbol_is_exogenous ( var , false ) ;
2021-05-26 18:00:06 +02:00
int symb_id = mod_file - > symbol_table . getID ( var ) ;
2022-05-04 16:01:34 +02:00
if ( ( ! scales & & heteroskedastic_shocks_values . contains ( symb_id ) )
| | ( scales & & heteroskedastic_shocks_scales . contains ( symb_id ) ) )
2021-05-26 18:00:06 +02:00
error ( " heteroskedastic_shocks: variable " + var + " declared twice " ) ;
if ( periods . size ( ) ! = values . size ( ) )
error ( " heteroskedastic_shocks: variable " + var + " : number of periods is different from number of shock values " ) ;
vector < tuple < int , int , expr_t > > v ;
for ( size_t i = 0 ; i < periods . size ( ) ; i + + )
2021-06-15 12:53:40 +02:00
v . emplace_back ( periods [ i ] . first , periods [ i ] . second , values [ i ] ) ;
2021-05-26 18:00:06 +02:00
if ( scales )
heteroskedastic_shocks_scales [ symb_id ] = v ;
else
heteroskedastic_shocks_values [ symb_id ] = v ;
}
2008-02-03 11:28:36 +01:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_stderr_shock ( const string & var , expr_t value )
2008-02-03 11:28:36 +01:00
{
2022-06-02 10:50:21 +02:00
if ( nostrict & & ! mod_file - > symbol_table . exists ( var ) )
{
warning ( " discarding shocks block declaration of the standard error of ' " + var + " ' as it was not declared " ) ;
return ;
}
2017-04-03 16:44:31 +02:00
2018-07-31 11:48:08 +02:00
check_symbol_existence ( var ) ;
int symb_id = mod_file - > symbol_table . getID ( var ) ;
2010-04-14 15:03:41 +02:00
2022-05-04 16:01:34 +02:00
if ( var_shocks . contains ( symb_id ) | | std_shocks . contains ( symb_id ) )
2018-07-31 11:48:08 +02:00
error ( " shocks: variance or stderr of shock on " + var + " declared twice " ) ;
2008-02-03 11:28:36 +01:00
2010-04-14 15:03:41 +02:00
std_shocks [ symb_id ] = value ;
2008-02-03 11:28:36 +01:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_var_shock ( const string & var , expr_t value )
2008-02-03 11:28:36 +01:00
{
2022-06-02 10:50:21 +02:00
if ( nostrict & & ! mod_file - > symbol_table . exists ( var ) )
{
warning ( " discarding shocks block declaration of the variance of ' " + var + " ' as it was not declared " ) ;
return ;
}
2017-04-03 16:44:31 +02:00
2018-07-31 11:48:08 +02:00
check_symbol_existence ( var ) ;
int symb_id = mod_file - > symbol_table . getID ( var ) ;
2010-04-14 15:03:41 +02:00
2022-05-04 16:01:34 +02:00
if ( var_shocks . contains ( symb_id ) | | std_shocks . contains ( symb_id ) )
2018-07-31 11:48:08 +02:00
error ( " shocks: variance or stderr of shock on " + var + " declared twice " ) ;
2008-02-03 11:28:36 +01:00
2010-04-14 15:03:41 +02:00
var_shocks [ symb_id ] = value ;
2008-02-03 11:28:36 +01:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_covar_shock ( const string & var1 , const string & var2 , expr_t value )
2008-02-03 11:28:36 +01:00
{
2022-06-02 10:50:21 +02:00
if ( nostrict & &
( ! 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 " ) ;
return ;
}
2017-04-03 16:44:31 +02:00
2018-07-31 11:48:08 +02:00
check_symbol_existence ( var1 ) ;
check_symbol_existence ( var2 ) ;
int symb_id1 = mod_file - > symbol_table . getID ( var1 ) ;
int symb_id2 = mod_file - > symbol_table . getID ( var2 ) ;
2008-02-03 11:28:36 +01:00
2022-06-03 16:21:30 +02:00
pair key { symb_id1 , symb_id2 } , key_inv { symb_id2 , symb_id1 } ;
2008-02-03 11:28:36 +01:00
2022-05-04 16:01:34 +02:00
if ( covar_shocks . contains ( key ) | | covar_shocks . contains ( key_inv )
| | corr_shocks . contains ( key ) | | corr_shocks . contains ( key_inv ) )
2018-07-31 11:48:08 +02:00
error ( " shocks: covariance or correlation shock on variable pair ( " + var1 + " , "
+ var2 + " ) declared twice " ) ;
2008-02-03 11:28:36 +01:00
covar_shocks [ key ] = value ;
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_correl_shock ( const string & var1 , const string & var2 , expr_t value )
2008-02-03 11:28:36 +01:00
{
2022-06-02 10:50:21 +02:00
if ( nostrict & &
( ! 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 " ) ;
return ;
}
2017-04-03 16:44:31 +02:00
2018-07-31 11:48:08 +02:00
check_symbol_existence ( var1 ) ;
check_symbol_existence ( var2 ) ;
int symb_id1 = mod_file - > symbol_table . getID ( var1 ) ;
int symb_id2 = mod_file - > symbol_table . getID ( var2 ) ;
2010-04-14 15:03:41 +02:00
2022-06-03 16:21:30 +02:00
pair key { symb_id1 , symb_id2 } , key_inv { symb_id2 , symb_id1 } ;
2008-02-03 11:28:36 +01:00
2022-05-04 16:01:34 +02:00
if ( covar_shocks . contains ( key ) | | covar_shocks . contains ( key_inv )
| | corr_shocks . contains ( key ) | | corr_shocks . contains ( key_inv ) )
2018-07-31 11:48:08 +02:00
error ( " shocks: covariance or correlation shock on variable pair ( " + var1 + " , "
+ var2 + " ) declared twice " ) ;
2008-02-03 11:28:36 +01:00
corr_shocks [ key ] = value ;
}
2011-08-03 11:00:11 +02:00
void
ParsingDriver : : begin_svar_identification ( )
{
svar_upper_cholesky = false ;
svar_lower_cholesky = false ;
svar_constants_exclusion = false ;
}
2009-12-04 22:32:19 +01:00
void
ParsingDriver : : end_svar_identification ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < SvarIdentificationStatement > ( move ( svar_ident_restrictions ) ,
2018-09-05 15:17:21 +02:00
svar_upper_cholesky ,
svar_lower_cholesky ,
svar_constants_exclusion ,
mod_file - > symbol_table ) ) ;
2009-12-04 22:32:19 +01:00
svar_equation_restrictions . clear ( ) ;
2011-10-10 11:45:55 +02:00
svar_ident_restrictions . clear ( ) ;
2011-11-06 17:44:50 +01:00
svar_Qi_restriction_nbr . clear ( ) ;
svar_Ri_restriction_nbr . clear ( ) ;
2009-12-04 22:32:19 +01:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : combine_lag_and_restriction ( const string & lag )
2009-12-04 22:32:19 +01:00
{
2018-07-31 11:48:08 +02:00
int current_lag = stoi ( lag ) ;
2009-12-04 22:32:19 +01:00
2018-07-31 11:48:08 +02:00
for ( const auto & it : svar_ident_restrictions )
if ( it . lag = = current_lag )
error ( " lag " + lag + " used more than once. " ) ;
2009-12-04 22:32:19 +01:00
2018-07-31 11:48:08 +02:00
for ( const auto & it : svar_equation_restrictions )
for ( auto it1 : it . second )
2011-10-10 11:45:55 +02:00
{
2017-06-01 19:58:32 +02:00
SvarIdentificationStatement : : svar_identification_restriction new_restriction ;
2018-07-31 11:48:08 +02:00
new_restriction . equation = it . first ;
2017-06-01 19:58:32 +02:00
if ( current_lag > 0 )
2018-07-31 11:48:08 +02:00
new_restriction . restriction_nbr = + + svar_Ri_restriction_nbr [ it . first ] ;
2017-06-01 19:58:32 +02:00
else
2018-07-31 11:48:08 +02:00
new_restriction . restriction_nbr = + + svar_Qi_restriction_nbr [ it . first ] ;
2017-06-01 19:58:32 +02:00
new_restriction . lag = current_lag ;
2018-07-31 11:48:08 +02:00
new_restriction . variable = it1 ;
2017-06-01 19:58:32 +02:00
new_restriction . value = data_tree - > One ;
svar_ident_restrictions . push_back ( new_restriction ) ;
}
2009-12-04 22:32:19 +01:00
svar_upper_cholesky = false ;
svar_lower_cholesky = false ;
svar_equation_restrictions . clear ( ) ;
}
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : add_restriction_in_equation ( const string & equation , const vector < string > & symbol_list )
2009-12-04 22:32:19 +01:00
{
2018-07-31 11:48:08 +02:00
int eqn = stoi ( equation ) ;
2009-12-04 22:32:19 +01:00
if ( eqn < 1 )
error ( " equation numbers must be greater than or equal to 1. " ) ;
2022-05-04 16:01:34 +02:00
if ( svar_equation_restrictions . contains ( eqn ) )
2018-07-31 11:48:08 +02:00
error ( " equation number " + equation + " referenced more than once under a single lag. " ) ;
2009-12-04 22:32:19 +01:00
2022-03-28 18:11:53 +02:00
vector < int > svar_restriction_symbols ;
for ( auto & name : symbol_list )
{
check_symbol_existence ( name ) ;
int symb_id = mod_file - > symbol_table . getID ( name ) ;
2009-12-14 16:54:00 +01:00
2022-03-28 18:11:53 +02:00
for ( const auto & viit : svar_restriction_symbols )
if ( symb_id = = viit )
error ( name + " restriction added twice. " ) ;
2009-12-04 22:32:19 +01:00
2022-03-28 18:11:53 +02:00
svar_restriction_symbols . push_back ( symb_id ) ;
}
svar_equation_restrictions [ eqn ] = svar_restriction_symbols ;
2009-12-04 22:32:19 +01:00
}
2017-06-01 19:58:32 +02:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_restriction_equation_nbr ( const string & eq_nbr )
2011-10-10 11:45:55 +02:00
{
2018-07-31 11:48:08 +02:00
svar_equation_nbr = stoi ( eq_nbr ) ;
2011-10-10 11:45:55 +02:00
svar_left_handside = true ;
2011-11-07 12:26:20 +01:00
// reinitialize restriction type that must be set from the first restriction element
2018-10-02 18:15:31 +02:00
svar_restriction_type = SvarRestrictionType : : NOT_SET ;
2011-10-10 11:45:55 +02:00
}
void
ParsingDriver : : add_restriction_equal ( )
{
if ( svar_left_handside )
svar_left_handside = false ;
else
error ( " svar_identification: there are more than one EQUAL sign in a restriction equation " ) ;
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_positive_restriction_element ( expr_t value , const string & variable , const string & lag )
2011-10-10 11:45:55 +02:00
{
// if the expression is not on the left handside, change its sign
if ( ! svar_left_handside )
value = add_uminus ( value ) ;
2017-06-01 19:58:32 +02:00
2011-11-07 12:26:20 +01:00
add_restriction_element ( value , variable , lag ) ;
2011-10-10 11:45:55 +02:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_positive_restriction_element ( const string & variable , const string & lag )
2011-10-10 11:45:55 +02:00
{
2017-06-01 19:58:32 +02:00
expr_t value ( data_tree - > One ) ;
2011-10-10 11:45:55 +02:00
// if the expression is not on the left handside, change its sign
if ( ! svar_left_handside )
value = add_uminus ( value ) ;
2011-11-07 12:26:20 +01:00
add_restriction_element ( value , variable , lag ) ;
2011-10-10 11:45:55 +02:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_negative_restriction_element ( expr_t value , const string & variable , const string & lag )
2011-10-10 11:45:55 +02:00
{
// if the expression is on the left handside, change its sign
if ( svar_left_handside )
value = add_uminus ( value ) ;
2011-11-07 12:26:20 +01:00
add_restriction_element ( value , variable , lag ) ;
2011-10-10 11:45:55 +02:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_negative_restriction_element ( const string & variable , const string & lag )
2011-10-10 11:45:55 +02:00
{
2017-06-01 19:58:32 +02:00
expr_t value ( data_tree - > One ) ;
2011-10-10 11:45:55 +02:00
// if the expression is on the left handside, change its sign
if ( svar_left_handside )
value = add_uminus ( value ) ;
2011-11-07 12:26:20 +01:00
add_restriction_element ( value , variable , lag ) ;
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_restriction_element ( expr_t value , const string & variable , const string & lag )
2011-11-07 12:26:20 +01:00
{
2018-07-31 11:48:08 +02:00
check_symbol_existence ( variable ) ;
int symb_id = mod_file - > symbol_table . getID ( variable ) ;
2011-11-07 12:26:20 +01:00
2018-07-31 11:48:08 +02:00
int current_lag = stoi ( lag ) ;
2018-10-02 18:15:31 +02:00
if ( svar_restriction_type = = SvarRestrictionType : : NOT_SET )
2011-11-07 12:26:20 +01:00
{
if ( current_lag = = 0 )
2017-06-01 19:58:32 +02:00
{
2018-10-02 18:15:31 +02:00
svar_restriction_type = SvarRestrictionType : : Qi_TYPE ;
2017-06-01 19:58:32 +02:00
+ + svar_Qi_restriction_nbr [ svar_equation_nbr ] ;
}
2011-11-07 12:26:20 +01:00
else
2017-06-01 19:58:32 +02:00
{
2018-10-02 18:15:31 +02:00
svar_restriction_type = SvarRestrictionType : : Ri_TYPE ;
2017-06-01 19:58:32 +02:00
+ + svar_Ri_restriction_nbr [ svar_equation_nbr ] ;
}
2011-11-07 12:26:20 +01:00
}
else
{
2018-10-02 18:15:31 +02:00
if ( ( svar_restriction_type = = SvarRestrictionType : : Qi_TYPE & & current_lag > 0 )
| | ( svar_restriction_type = = SvarRestrictionType : : Ri_TYPE & & current_lag = = 0 ) )
2017-06-01 19:58:32 +02:00
error ( " SVAR_IDENTIFICATION: a single restrictions must affect either Qi or Ri, but not both " ) ;
2011-11-07 12:26:20 +01:00
}
2011-10-10 11:45:55 +02:00
SvarIdentificationStatement : : svar_identification_restriction new_restriction ;
new_restriction . equation = svar_equation_nbr ;
2011-11-06 17:44:50 +01:00
if ( current_lag > 0 )
2011-11-07 12:26:20 +01:00
new_restriction . restriction_nbr = svar_Ri_restriction_nbr [ svar_equation_nbr ] ;
2011-11-06 17:44:50 +01:00
else
2011-11-07 12:26:20 +01:00
new_restriction . restriction_nbr = svar_Qi_restriction_nbr [ svar_equation_nbr ] ;
2011-11-06 17:44:50 +01:00
new_restriction . lag = current_lag ;
2011-10-10 11:45:55 +02:00
new_restriction . variable = symb_id ;
new_restriction . value = value ;
svar_ident_restrictions . push_back ( new_restriction ) ;
}
2011-11-06 17:44:50 +01:00
void
ParsingDriver : : check_restriction_expression_constant ( expr_t value )
{
2019-12-16 19:42:59 +01:00
if ( value - > eval ( { } ) ! = 0 )
2011-11-06 17:44:50 +01:00
error ( " SVAR_INDENTIFICATION restrictions must be homogenous " ) ;
}
2009-12-04 22:32:19 +01:00
void
ParsingDriver : : add_upper_cholesky ( )
{
svar_upper_cholesky = true ;
}
void
ParsingDriver : : add_lower_cholesky ( )
{
svar_lower_cholesky = true ;
}
2011-08-03 11:00:11 +02:00
void
ParsingDriver : : add_constants_exclusion ( )
{
svar_constants_exclusion = true ;
}
2015-08-24 11:21:06 +02:00
void
ParsingDriver : : add_svar_global_identification_check ( )
{
2018-09-05 15:17:21 +02:00
mod_file - > addStatement ( make_unique < SvarGlobalIdentificationCheckStatement > ( ) ) ;
2015-08-24 11:21:06 +02:00
}
2008-02-03 11:28:36 +01:00
void
ParsingDriver : : steady ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < SteadyStatement > ( move ( options_list ) ) ) ;
2008-02-03 11:28:36 +01:00
options_list . clear ( ) ;
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : option_num ( string name_option , string opt1 , string opt2 )
2008-02-03 11:28:36 +01:00
{
2022-09-18 09:30:13 +02:00
if ( options_list . contains ( name_option ) )
2008-02-03 11:28:36 +01:00
error ( " option " + name_option + " declared twice " ) ;
2022-09-18 09:30:13 +02:00
options_list . set ( move ( name_option ) , pair { move ( opt1 ) , move ( opt2 ) } ) ;
2008-02-03 11:28:36 +01:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : option_num ( string name_option , string opt )
2008-02-03 11:28:36 +01:00
{
2022-09-18 09:30:13 +02:00
if ( options_list . contains ( name_option ) )
2008-02-03 11:28:36 +01:00
error ( " option " + name_option + " declared twice " ) ;
2022-09-18 09:30:13 +02:00
options_list . set ( move ( name_option ) , OptionsList : : NumVal { move ( opt ) } ) ;
2008-02-03 11:28:36 +01:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : option_str ( string name_option , string opt )
2008-02-03 11:28:36 +01:00
{
2022-09-18 09:30:13 +02:00
if ( options_list . contains ( name_option ) )
2008-02-03 11:28:36 +01:00
error ( " option " + name_option + " declared twice " ) ;
2022-09-18 09:30:13 +02:00
options_list . set ( move ( name_option ) , OptionsList : : StringVal { move ( opt ) } ) ;
2011-11-29 17:14:26 +01:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : option_date ( string name_option , string opt )
2011-11-29 17:14:26 +01:00
{
2022-09-18 09:30:13 +02:00
if ( options_list . contains ( name_option ) )
2011-11-29 17:14:26 +01:00
error ( " option " + name_option + " declared twice " ) ;
2022-09-18 09:30:13 +02:00
options_list . set ( move ( name_option ) , OptionsList : : DateVal { move ( opt ) } ) ;
2011-11-29 17:14:26 +01:00
}
2008-04-04 20:40:20 +02:00
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : option_symbol_list ( string name_option , vector < string > symbol_list )
2008-04-04 20:40:20 +02:00
{
2022-09-18 09:30:13 +02:00
if ( options_list . contains ( name_option ) )
2008-04-04 20:40:20 +02:00
error ( " option " + name_option + " declared twice " ) ;
2022-07-20 10:44:29 +02:00
if ( name_option = = " irf_shocks " )
2022-06-02 10:50:21 +02:00
for ( auto & shock : symbol_list )
{
if ( ! mod_file - > symbol_table . exists ( shock ) )
error ( " Unknown symbol: " + shock ) ;
if ( mod_file - > symbol_table . getType ( shock ) ! = SymbolType : : exogenous )
error ( " Variables passed to irf_shocks must be exogenous. Caused by: " + shock ) ;
}
2011-03-31 16:33:47 +02:00
2022-07-20 10:44:29 +02:00
if ( name_option = = " ms.parameters " )
2022-06-02 10:50:21 +02:00
for ( auto & it : symbol_list )
if ( mod_file - > symbol_table . getType ( it ) ! = SymbolType : : parameter )
error ( " Variables passed to the parameters option of the markov_switching statement must be parameters. Caused by: " + it ) ;
2011-12-24 16:58:16 +01:00
2022-09-18 09:30:13 +02:00
options_list . set ( move ( name_option ) , OptionsList : : SymbolListVal { move ( symbol_list ) } ) ;
2008-04-04 20:40:20 +02:00
}
2009-12-10 23:49:50 +01:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : option_vec_int ( string name_option , vector < int > opt )
2009-12-10 23:49:50 +01:00
{
2022-09-18 09:30:13 +02:00
if ( options_list . contains ( name_option ) )
2009-12-10 23:49:50 +01:00
error ( " option " + name_option + " declared twice " ) ;
2018-07-31 11:48:08 +02:00
if ( opt . empty ( ) )
2009-12-14 16:54:00 +01:00
error ( " option " + name_option + " was passed an empty vector. " ) ;
2022-09-18 09:30:13 +02:00
options_list . set ( move ( name_option ) , move ( opt ) ) ;
2009-12-10 23:49:50 +01:00
}
2018-01-12 16:54:17 +01:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : option_vec_str ( string name_option , vector < string > opt )
2018-01-12 16:54:17 +01:00
{
2022-09-18 09:30:13 +02:00
if ( options_list . contains ( name_option ) )
2018-01-12 16:54:17 +01:00
error ( " option " + name_option + " declared twice " ) ;
2018-07-31 11:48:08 +02:00
if ( opt . empty ( ) )
2018-01-12 16:54:17 +01:00
error ( " option " + name_option + " was passed an empty vector. " ) ;
2022-09-18 09:30:13 +02:00
options_list . set ( move ( name_option ) , OptionsList : : VecStrVal { move ( opt ) } ) ;
2018-01-12 16:54:17 +01:00
}
2020-07-08 18:42:14 +02:00
void
ParsingDriver : : option_vec_cellstr ( string name_option , vector < string > opt )
{
2022-09-18 09:30:13 +02:00
if ( options_list . contains ( name_option ) )
2020-07-08 18:42:14 +02:00
error ( " option " + name_option + " declared twice " ) ;
if ( opt . empty ( ) )
error ( " option " + name_option + " was passed an empty vector. " ) ;
2022-09-18 09:30:13 +02:00
options_list . set ( move ( name_option ) , OptionsList : : VecCellStrVal { move ( opt ) } ) ;
2020-07-08 18:42:14 +02:00
}
2022-05-18 17:22:01 +02:00
void
ParsingDriver : : option_vec_value ( string name_option , vector < string > opt )
{
2022-09-18 09:30:13 +02:00
if ( options_list . contains ( name_option ) )
2022-05-18 17:22:01 +02:00
error ( " option " + name_option + " declared twice " ) ;
if ( opt . empty ( ) )
error ( " option " + name_option + " was passed an empty vector. " ) ;
2022-09-18 09:30:13 +02:00
options_list . set ( move ( name_option ) , OptionsList : : VecValueVal { move ( opt ) } ) ;
2022-05-18 17:22:01 +02:00
}
void
ParsingDriver : : option_vec_of_vec_value ( string name_option , vector < vector < string > > opt )
{
2022-09-18 09:30:13 +02:00
if ( options_list . contains ( name_option ) )
2022-05-18 17:22:01 +02:00
error ( " option " + name_option + " declared twice " ) ;
if ( opt . empty ( ) )
error ( " option " + name_option + " was passed an empty vector. " ) ;
2022-09-18 09:30:13 +02:00
options_list . set ( move ( name_option ) , move ( opt ) ) ;
2022-05-18 17:22:01 +02:00
}
2008-02-03 11:28:36 +01:00
void
ParsingDriver : : linear ( )
{
mod_file - > linear = true ;
}
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : rplot ( vector < string > symbol_list )
2008-02-03 11:28:36 +01:00
{
2022-03-28 18:11:53 +02:00
mod_file - > addStatement ( make_unique < RplotStatement > ( move ( symbol_list ) , mod_file - > symbol_table ) ) ;
2008-02-03 11:28:36 +01:00
}
2009-12-16 18:13:23 +01:00
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : stoch_simul ( SymbolList symbol_list )
2008-02-03 11:28:36 +01:00
{
2020-07-17 09:43:28 +02:00
//make sure default order is known to preprocessor, see #49
2022-09-18 09:30:13 +02:00
if ( ! options_list . contains ( " order " ) )
options_list . set ( " order " , OptionsList : : NumVal { " 2 " } ) ;
2020-07-17 09:43:28 +02:00
2022-03-28 18:11:53 +02:00
symbol_list . removeDuplicates ( " stoch_simul " , warnings ) ;
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < StochSimulStatement > ( move ( symbol_list ) , move ( options_list ) ,
2022-03-28 18:11:53 +02:00
mod_file - > symbol_table ) ) ;
2008-02-03 11:28:36 +01:00
options_list . clear ( ) ;
}
2018-08-14 14:23:21 +02:00
void
ParsingDriver : : trend_component_model ( )
{
2022-09-18 09:30:13 +02:00
try
{
mod_file - > trend_component_model_table . addTrendComponentModel ( options_list . get < OptionsList : : StringVal > ( " trend_component.name " ) ,
options_list . get < OptionsList : : VecStrVal > ( " trend_component.eqtags " ) ,
options_list . get < OptionsList : : VecStrVal > ( " trend_component.targets " ) ) ;
}
catch ( OptionsList : : UnknownOptionException & e )
{
string name { e . name . substr ( 16 ) } ;
if ( name = = " name " )
name = " model_name " ;
error ( " You must pass the ' " + name + " ' option to the 'trend_component_model' statement. " ) ;
}
2018-08-14 14:23:21 +02:00
options_list . clear ( ) ;
}
2016-10-26 18:19:33 +02:00
void
ParsingDriver : : var_model ( )
{
2022-09-18 09:30:13 +02:00
try
{
mod_file - > var_model_table . addVarModel ( options_list . get < OptionsList : : StringVal > ( " var.model_name " ) ,
options_list . get_if < OptionsList : : NumVal > ( " var.structural " ) . value_or ( OptionsList : : NumVal { " false " } ) = = " true " ,
options_list . get < OptionsList : : VecStrVal > ( " var.eqtags " ) ) ;
}
catch ( OptionsList : : UnknownOptionException & e )
{
error ( " You must pass the ' " + e . name . substr ( 4 ) + " ' option to the 'var_model' statement. " ) ;
}
2016-10-26 18:19:33 +02:00
options_list . clear ( ) ;
}
2008-02-03 11:28:36 +01:00
void
ParsingDriver : : simul ( )
{
2019-12-13 15:54:38 +01:00
warning ( " The 'simul' statement is deprecated. Please use 'perfect_foresight_setup' and 'perfect_foresight_solver' instead. " ) ;
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < SimulStatement > ( move ( options_list ) ) ) ;
2008-02-03 11:28:36 +01:00
options_list . clear ( ) ;
}
2008-08-25 17:06:36 +02:00
void
ParsingDriver : : model_info ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < ModelInfoStatement > ( move ( options_list ) ) ) ;
2008-08-25 17:06:36 +02:00
options_list . clear ( ) ;
}
2008-02-03 11:28:36 +01:00
void
ParsingDriver : : check ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < CheckStatement > ( move ( options_list ) ) ) ;
2008-02-03 11:28:36 +01:00
options_list . clear ( ) ;
}
void
ParsingDriver : : add_estimated_params_element ( )
{
2010-06-21 18:40:36 +02:00
if ( estim_params . name ! = " dsge_prior_weight " )
{
check_symbol_existence ( estim_params . name ) ;
2014-02-28 18:01:03 +01:00
SymbolType type = mod_file - > symbol_table . getType ( estim_params . name ) ;
switch ( estim_params . type )
{
case 1 :
2018-07-17 18:34:07 +02:00
if ( type ! = SymbolType : : endogenous & & type ! = SymbolType : : exogenous )
2014-02-28 18:01:03 +01:00
error ( estim_params . name + " must be an endogenous or an exogenous variable " ) ;
break ;
case 2 :
2018-07-31 11:48:08 +02:00
check_symbol_is_parameter ( estim_params . name ) ;
2014-02-28 18:01:03 +01:00
break ;
case 3 :
check_symbol_existence ( estim_params . name2 ) ;
SymbolType type2 = mod_file - > symbol_table . getType ( estim_params . name2 ) ;
2018-07-17 18:34:07 +02:00
if ( ( type ! = SymbolType : : endogenous & & type ! = SymbolType : : exogenous ) | | type ! = type2 )
2014-02-28 18:01:03 +01:00
error ( estim_params . name + " and " + estim_params . name2 + " must either be both endogenous variables or both exogenous " ) ;
break ;
}
2010-06-21 18:40:36 +02:00
}
2008-02-03 11:28:36 +01:00
estim_params_list . push_back ( estim_params ) ;
2009-01-22 16:05:38 +01:00
estim_params . init ( * data_tree ) ;
2008-02-03 11:28:36 +01:00
}
void
2021-12-16 14:22:31 +01:00
ParsingDriver : : estimated_params ( bool overwrite )
2008-02-03 11:28:36 +01:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < EstimatedParamsStatement > ( move ( estim_params_list ) ,
mod_file - > symbol_table , overwrite ) ) ;
2008-02-03 11:28:36 +01:00
estim_params_list . clear ( ) ;
}
void
2013-11-06 10:36:58 +01:00
ParsingDriver : : estimated_params_init ( bool use_calibration )
2008-02-03 11:28:36 +01:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < EstimatedParamsInitStatement > ( move ( estim_params_list ) ,
mod_file - > symbol_table ,
use_calibration ) ) ;
2008-02-03 11:28:36 +01:00
estim_params_list . clear ( ) ;
}
void
ParsingDriver : : estimated_params_bounds ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < EstimatedParamsBoundsStatement > ( move ( estim_params_list ) ,
mod_file - > symbol_table ) ) ;
2008-02-03 11:28:36 +01:00
estim_params_list . clear ( ) ;
}
2021-12-15 15:59:18 +01:00
void
ParsingDriver : : estimated_params_remove ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < EstimatedParamsRemoveStatement > ( move ( estim_params_list ) ,
mod_file - > symbol_table ) ) ;
2021-12-15 15:59:18 +01:00
estim_params_list . clear ( ) ;
}
2016-05-10 18:01:00 +02:00
void
ParsingDriver : : add_osr_params_element ( )
{
check_symbol_existence ( osr_params . name ) ;
SymbolType type = mod_file - > symbol_table . getType ( osr_params . name ) ;
2018-07-17 18:34:07 +02:00
if ( type ! = SymbolType : : parameter )
2016-05-10 18:01:00 +02:00
error ( osr_params . name + " must be a parameter to be used in the osr_bounds block " ) ;
osr_params_list . push_back ( osr_params ) ;
osr_params . init ( * data_tree ) ;
}
void
ParsingDriver : : osr_params_bounds ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < OsrParamsBoundsStatement > ( move ( osr_params_list ) ) ) ;
2016-05-10 18:01:00 +02:00
osr_params_list . clear ( ) ;
}
2008-02-03 11:28:36 +01:00
void
ParsingDriver : : set_unit_root_vars ( )
{
2018-09-05 15:17:21 +02:00
mod_file - > addStatement ( make_unique < UnitRootVarsStatement > ( ) ) ;
2012-02-10 16:59:47 +01:00
warning ( " ''unit_root_vars'' is now obsolete; use the ''diffuse_filter'' option of ''estimation'' instead " ) ;
2008-02-03 11:28:36 +01:00
}
2011-11-29 17:14:26 +01:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : set_time ( const string & arg )
2011-11-29 17:14:26 +01:00
{
2013-10-11 16:28:14 +02:00
option_date ( " initial_period " , arg ) ;
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < SetTimeStatement > ( move ( options_list ) ) ) ;
2011-11-29 17:14:26 +01:00
options_list . clear ( ) ;
}
2011-12-06 15:42:57 +01:00
void
ParsingDriver : : estimation_data ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < EstimationDataStatement > ( move ( options_list ) ) ) ;
2011-12-06 15:42:57 +01:00
options_list . clear ( ) ;
}
2011-12-15 11:49:04 +01:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : set_subsamples ( string name1 , string name2 )
2011-12-15 11:49:04 +01:00
{
2018-07-31 11:48:08 +02:00
check_symbol_existence ( name1 ) ;
if ( ! name2 . empty ( ) )
check_symbol_existence ( name2 ) ;
2012-03-26 16:46:44 +02:00
2018-09-05 15:17:21 +02:00
mod_file - > addStatement ( make_unique < SubsamplesStatement > ( name1 , name2 , subsample_declaration_map ,
mod_file - > symbol_table ) ) ;
2022-10-04 15:59:18 +02:00
subsample_declarations [ { move ( name1 ) , move ( name2 ) } ] = move ( subsample_declaration_map ) ;
2012-03-26 16:46:44 +02:00
subsample_declaration_map . clear ( ) ;
2011-12-15 11:49:04 +01:00
}
2011-12-14 13:58:21 +01:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : copy_subsamples ( string to_name1 , string to_name2 , string from_name1 , string from_name2 )
2011-12-14 13:58:21 +01:00
{
2018-07-31 11:48:08 +02:00
check_symbol_existence ( to_name1 ) ;
check_symbol_existence ( from_name1 ) ;
if ( ! to_name2 . empty ( ) )
check_symbol_existence ( to_name2 ) ;
if ( ! from_name2 . empty ( ) )
check_symbol_existence ( from_name2 ) ;
2012-03-26 16:46:44 +02:00
2022-05-04 16:01:34 +02:00
if ( ! subsample_declarations . contains ( { from_name1 , from_name2 } ) )
2012-03-26 16:46:44 +02:00
{
2018-07-31 11:48:08 +02:00
string err { from_name1 } ;
if ( ! from_name2 . empty ( ) )
err . append ( " , " ) . append ( from_name2 ) ;
2012-03-26 16:46:44 +02:00
error ( err + " does not have an associated subsample statement. " ) ;
}
2018-09-05 15:17:21 +02:00
mod_file - > addStatement ( make_unique < SubsamplesEqualStatement > ( to_name1 , to_name2 , from_name1 , from_name2 ,
mod_file - > symbol_table ) ) ;
2012-03-28 16:19:10 +02:00
2018-07-31 11:48:08 +02:00
subsample_declarations [ { move ( to_name1 ) , move ( to_name2 ) } ]
= subsample_declarations [ { move ( from_name1 ) , move ( from_name2 ) } ] ;
2011-12-14 13:58:21 +01:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : check_symbol_is_statement_variable ( const string & name )
2011-12-14 13:58:21 +01:00
{
2018-07-31 11:48:08 +02:00
check_symbol_existence ( name ) ;
int symb_id = mod_file - > symbol_table . getID ( name ) ;
2018-07-17 18:34:07 +02:00
if ( mod_file - > symbol_table . getType ( symb_id ) ! = SymbolType : : statementDeclaredVariable )
2018-07-31 11:48:08 +02:00
error ( name + " is not a variable assigned in a statement " ) ;
2011-12-14 13:58:21 +01:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : set_subsample_name_equal_to_date_range ( string name , string date1 , string date2 )
2011-12-14 13:58:21 +01:00
{
2022-05-04 16:01:34 +02:00
if ( subsample_declaration_map . contains ( name ) )
2018-07-31 11:48:08 +02:00
error ( " Symbol " + name + " may only be assigned once in a SUBSAMPLE statement " ) ;
subsample_declaration_map [ move ( name ) ] = { move ( date1 ) , move ( date2 ) } ;
2011-12-14 13:58:21 +01:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : check_subsample_declaration_exists ( const string & name1 , const string & subsample_name )
2011-12-14 13:58:21 +01:00
{
2018-07-31 11:48:08 +02:00
if ( subsample_name . empty ( ) )
2012-03-28 16:19:10 +02:00
return ;
2018-07-31 11:48:08 +02:00
check_subsample_declaration_exists ( name1 , " " , subsample_name ) ;
2012-03-28 16:19:10 +02:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : check_subsample_declaration_exists ( const string & name1 , const string & name2 , const string & subsample_name )
2012-03-28 16:19:10 +02:00
{
2018-07-31 11:48:08 +02:00
if ( subsample_name . empty ( ) )
2012-03-28 16:19:10 +02:00
return ;
2018-07-31 11:48:08 +02:00
check_symbol_existence ( name1 ) ;
if ( ! name2 . empty ( ) )
check_symbol_existence ( name2 ) ;
2012-03-26 16:46:44 +02:00
2018-07-31 11:48:08 +02:00
auto it = subsample_declarations . find ( { name1 , name2 } ) ;
2011-12-14 13:58:21 +01:00
if ( it = = subsample_declarations . end ( ) )
2012-03-26 16:46:44 +02:00
{
2018-07-31 11:48:08 +02:00
it = subsample_declarations . find ( { name2 , name1 } ) ;
2017-06-01 19:58:32 +02:00
if ( it = = subsample_declarations . end ( ) )
2012-03-28 16:19:10 +02:00
{
2018-07-31 11:48:08 +02:00
string err { name1 } ;
if ( ! name2 . empty ( ) )
err . append ( " , " ) . append ( name2 ) ;
2012-03-28 16:19:10 +02:00
error ( " A subsample statement has not been issued for " + err ) ;
}
2012-03-26 16:46:44 +02:00
}
2018-07-31 11:48:08 +02:00
auto tmp_map = it - > second ;
2022-05-04 16:01:34 +02:00
if ( ! tmp_map . contains ( subsample_name ) )
2018-07-31 11:48:08 +02:00
error ( " The subsample name " + subsample_name + " was not previously declared in a subsample statement. " ) ;
2011-12-14 13:58:21 +01:00
}
2011-12-11 15:35:26 +01:00
void
2022-10-04 15:59:18 +02:00
ParsingDriver : : set_prior ( string name , string subsample_name )
2011-12-11 15:35:26 +01:00
{
check_symbol_is_parameter ( name ) ;
2012-03-28 16:19:10 +02:00
check_subsample_declaration_exists ( name , subsample_name ) ;
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < PriorStatement > ( move ( name ) , move ( subsample_name ) , prior_shape ,
prior_variance , move ( options_list ) ) ) ;
2011-12-11 15:35:26 +01:00
options_list . clear ( ) ;
2011-12-22 15:14:00 +01:00
set_prior_variance ( ) ;
2018-07-18 16:52:12 +02:00
prior_shape = PriorDistributions : : noShape ;
2011-12-11 15:35:26 +01:00
}
2015-03-03 15:08:33 +01:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : set_joint_prior ( const vector < string > & symbol_vec )
2015-03-03 15:08:33 +01:00
{
2018-07-31 11:48:08 +02:00
for ( auto & it : symbol_vec )
add_joint_parameter ( it ) ;
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < JointPriorStatement > ( move ( joint_parameters ) , prior_shape ,
move ( options_list ) ) ) ;
2015-03-03 15:08:33 +01:00
joint_parameters . clear ( ) ;
options_list . clear ( ) ;
2018-07-18 16:52:12 +02:00
prior_shape = PriorDistributions : : noShape ;
2015-03-03 15:08:33 +01:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_joint_parameter ( string name )
2015-03-03 15:08:33 +01:00
{
check_symbol_is_parameter ( name ) ;
2018-07-31 11:48:08 +02:00
joint_parameters . push_back ( move ( name ) ) ;
2015-03-03 15:08:33 +01:00
}
2011-12-11 15:35:26 +01:00
void
2011-12-22 15:14:00 +01:00
ParsingDriver : : set_prior_variance ( expr_t variance )
2011-12-11 15:35:26 +01:00
{
prior_variance = variance ;
}
2012-03-30 14:55:25 +02:00
void
2022-10-04 15:59:18 +02:00
ParsingDriver : : copy_prior ( string to_declaration_type , string to_name1 ,
string to_name2 , string to_subsample_name ,
string from_declaration_type , string from_name1 ,
string from_name2 , string from_subsample_name )
2012-03-30 14:55:25 +02:00
{
2018-07-31 11:48:08 +02:00
if ( to_declaration_type = = " par " )
2012-04-04 10:43:29 +02:00
check_symbol_is_parameter ( to_name1 ) ;
else
{
2022-04-21 17:59:04 +02:00
check_symbol_is_endogenous_or_exogenous ( to_name1 , false ) ;
2018-07-31 11:48:08 +02:00
if ( ! to_name2 . empty ( ) )
2022-04-21 17:59:04 +02:00
check_symbol_is_endogenous_or_exogenous ( to_name2 , false ) ;
2012-04-04 10:43:29 +02:00
}
2012-03-30 14:55:25 +02:00
2018-07-31 11:48:08 +02:00
if ( from_declaration_type = = " par " )
2012-04-04 10:43:29 +02:00
check_symbol_is_parameter ( from_name1 ) ;
else
{
2022-04-21 17:59:04 +02:00
check_symbol_is_endogenous_or_exogenous ( from_name1 , false ) ;
2018-07-31 11:48:08 +02:00
if ( ! from_name2 . empty ( ) )
2022-04-21 17:59:04 +02:00
check_symbol_is_endogenous_or_exogenous ( from_name2 , false ) ;
2012-04-04 10:43:29 +02:00
}
2012-03-30 14:55:25 +02:00
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < PriorEqualStatement > ( move ( to_declaration_type ) , move ( to_name1 ) ,
move ( to_name2 ) , move ( to_subsample_name ) ,
move ( from_declaration_type ) , move ( from_name1 ) ,
move ( from_name2 ) , move ( from_subsample_name ) ,
2018-09-05 15:17:21 +02:00
mod_file - > symbol_table ) ) ;
2012-03-30 14:55:25 +02:00
}
2011-12-14 17:19:14 +01:00
void
2022-10-04 15:59:18 +02:00
ParsingDriver : : set_options ( string name , string subsample_name )
2011-12-14 17:19:14 +01:00
{
check_symbol_is_parameter ( name ) ;
2012-03-28 16:19:10 +02:00
check_subsample_declaration_exists ( name , subsample_name ) ;
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < OptionsStatement > ( move ( name ) , move ( subsample_name ) ,
move ( options_list ) ) ) ;
2011-12-14 17:19:14 +01:00
options_list . clear ( ) ;
}
2012-03-30 15:36:58 +02:00
void
2022-10-04 15:59:18 +02:00
ParsingDriver : : copy_options ( string to_declaration_type , string to_name1 ,
string to_name2 , string to_subsample_name ,
string from_declaration_type , string from_name1 ,
string from_name2 , string from_subsample_name )
2012-03-30 15:36:58 +02:00
{
2018-07-31 11:48:08 +02:00
if ( to_declaration_type = = " par " )
2012-04-04 10:43:29 +02:00
check_symbol_is_parameter ( to_name1 ) ;
else
{
2022-04-21 17:59:04 +02:00
check_symbol_is_endogenous_or_exogenous ( to_name1 , false ) ;
2018-07-31 11:48:08 +02:00
if ( ! to_name2 . empty ( ) )
2022-04-21 17:59:04 +02:00
check_symbol_is_endogenous_or_exogenous ( to_name2 , false ) ;
2012-04-04 10:43:29 +02:00
}
2012-03-30 15:36:58 +02:00
2018-07-31 11:48:08 +02:00
if ( from_declaration_type = = " par " )
2012-04-04 10:43:29 +02:00
check_symbol_is_parameter ( from_name1 ) ;
else
{
2022-04-21 17:59:04 +02:00
check_symbol_is_endogenous_or_exogenous ( from_name1 , false ) ;
2018-07-31 11:48:08 +02:00
if ( ! from_name2 . empty ( ) )
2022-04-21 17:59:04 +02:00
check_symbol_is_endogenous_or_exogenous ( from_name2 , false ) ;
2012-04-04 10:43:29 +02:00
}
2012-03-30 15:36:58 +02:00
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < OptionsEqualStatement > ( move ( to_declaration_type ) , move ( to_name1 ) ,
move ( to_name2 ) , move ( to_subsample_name ) ,
move ( from_declaration_type ) , move ( from_name1 ) ,
move ( from_name2 ) , move ( from_subsample_name ) ,
2018-09-05 15:17:21 +02:00
mod_file - > symbol_table ) ) ;
2012-03-30 15:36:58 +02:00
}
2011-12-11 15:35:26 +01:00
void
2022-04-21 17:59:04 +02:00
ParsingDriver : : check_symbol_is_endogenous_or_exogenous ( const string & name , bool allow_det )
2011-12-11 15:35:26 +01:00
{
2018-07-31 11:48:08 +02:00
check_symbol_existence ( name ) ;
2018-08-01 10:47:09 +02:00
switch ( mod_file - > symbol_table . getType ( name ) )
2011-12-11 15:35:26 +01:00
{
2018-07-17 18:34:07 +02:00
case SymbolType : : endogenous :
case SymbolType : : exogenous :
2022-04-21 17:59:04 +02:00
break ;
2018-07-17 18:34:07 +02:00
case SymbolType : : exogenousDet :
2022-04-21 17:59:04 +02:00
if ( ! allow_det )
error ( name + " is an exogenous deterministic. " ) ;
2011-12-11 15:35:26 +01:00
break ;
default :
2018-07-31 11:48:08 +02:00
error ( name + " is neither endogenous or exogenous. " ) ;
2011-12-11 15:35:26 +01:00
}
}
2018-08-01 10:47:09 +02:00
void
ParsingDriver : : check_symbol_is_endogenous ( const string & name )
{
check_symbol_existence ( name ) ;
if ( mod_file - > symbol_table . getType ( name ) ! = SymbolType : : endogenous )
error ( name + " is not endogenous. " ) ;
}
2017-10-06 14:49:14 +02:00
void
2022-04-21 17:59:04 +02:00
ParsingDriver : : check_symbol_is_exogenous ( const string & name , bool allow_exo_det )
2017-10-06 14:49:14 +02:00
{
2018-07-31 11:48:08 +02:00
check_symbol_existence ( name ) ;
2018-08-01 10:47:09 +02:00
switch ( mod_file - > symbol_table . getType ( name ) )
2017-10-06 14:49:14 +02:00
{
2018-07-17 18:34:07 +02:00
case SymbolType : : exogenous :
2022-04-21 17:59:04 +02:00
break ;
2018-07-17 18:34:07 +02:00
case SymbolType : : exogenousDet :
2022-04-21 17:59:04 +02:00
if ( ! allow_exo_det )
error ( name + " is an exogenous deterministic. " ) ;
2017-10-06 14:49:14 +02:00
break ;
default :
2018-07-31 11:48:08 +02:00
error ( name + " is not exogenous. " ) ;
2017-10-06 14:49:14 +02:00
}
}
2011-12-11 15:35:26 +01:00
void
2022-10-04 15:59:18 +02:00
ParsingDriver : : set_std_prior ( string name , string subsample_name )
2011-12-11 15:35:26 +01:00
{
2022-04-21 17:59:04 +02:00
check_symbol_is_endogenous_or_exogenous ( name , false ) ;
2012-03-28 16:19:10 +02:00
check_subsample_declaration_exists ( name , subsample_name ) ;
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < StdPriorStatement > ( move ( name ) , move ( subsample_name ) ,
prior_shape , prior_variance ,
move ( options_list ) , mod_file - > symbol_table ) ) ;
2011-12-11 15:35:26 +01:00
options_list . clear ( ) ;
2011-12-22 15:14:00 +01:00
set_prior_variance ( ) ;
2018-07-18 16:52:12 +02:00
prior_shape = PriorDistributions : : noShape ;
2011-12-11 15:35:26 +01:00
}
2011-12-14 17:19:14 +01:00
void
2022-10-04 15:59:18 +02:00
ParsingDriver : : set_std_options ( string name , string subsample_name )
2011-12-14 17:19:14 +01:00
{
2022-04-21 17:59:04 +02:00
check_symbol_is_endogenous_or_exogenous ( name , false ) ;
2012-03-28 16:19:10 +02:00
check_subsample_declaration_exists ( name , subsample_name ) ;
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < StdOptionsStatement > ( move ( name ) , move ( subsample_name ) ,
move ( options_list ) , mod_file - > symbol_table ) ) ;
2011-12-14 17:19:14 +01:00
options_list . clear ( ) ;
}
2011-12-11 15:35:26 +01:00
void
2022-10-04 15:59:18 +02:00
ParsingDriver : : set_corr_prior ( string name1 , string name2 , string subsample_name )
2011-12-11 15:35:26 +01:00
{
2022-04-21 17:59:04 +02:00
check_symbol_is_endogenous_or_exogenous ( name1 , false ) ;
check_symbol_is_endogenous_or_exogenous ( name2 , false ) ;
2012-03-28 16:19:10 +02:00
check_subsample_declaration_exists ( name1 , name2 , subsample_name ) ;
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < CorrPriorStatement > ( move ( name1 ) , move ( name2 ) ,
move ( subsample_name ) , prior_shape , prior_variance ,
move ( options_list ) , mod_file - > symbol_table ) ) ;
2011-12-11 15:35:26 +01:00
options_list . clear ( ) ;
2011-12-22 15:14:00 +01:00
set_prior_variance ( ) ;
2018-07-18 16:52:12 +02:00
prior_shape = PriorDistributions : : noShape ;
2011-12-11 15:35:26 +01:00
}
2011-12-14 17:19:14 +01:00
void
2022-10-04 15:59:18 +02:00
ParsingDriver : : set_corr_options ( string name1 , string name2 , string subsample_name )
2011-12-14 17:19:14 +01:00
{
2022-04-21 17:59:04 +02:00
check_symbol_is_endogenous_or_exogenous ( name1 , false ) ;
check_symbol_is_endogenous_or_exogenous ( name2 , false ) ;
2012-03-28 16:19:10 +02:00
check_subsample_declaration_exists ( name1 , name2 , subsample_name ) ;
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < CorrOptionsStatement > ( move ( name1 ) , move ( name2 ) ,
move ( subsample_name ) , move ( options_list ) ,
mod_file - > symbol_table ) ) ;
2011-12-14 17:19:14 +01:00
options_list . clear ( ) ;
}
2008-02-03 11:28:36 +01:00
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : run_estimation ( vector < string > symbol_list )
2008-02-03 11:28:36 +01:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < EstimationStatement > ( mod_file - > symbol_table , move ( symbol_list ) ,
move ( options_list ) ) ) ;
2008-02-03 11:28:36 +01:00
options_list . clear ( ) ;
}
void
ParsingDriver : : dynare_sensitivity ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < DynareSensitivityStatement > ( move ( options_list ) ) ) ;
2008-02-03 11:28:36 +01:00
options_list . clear ( ) ;
}
void
2010-04-14 15:03:41 +02:00
ParsingDriver : : check_varobs ( )
2008-02-03 11:28:36 +01:00
{
2010-04-14 15:03:41 +02:00
if ( mod_file - > symbol_table . observedVariablesNbr ( ) > 0 )
error ( " varobs: you cannot have several 'varobs' statements in the same MOD file " ) ;
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_varobs ( const string & name )
2010-04-14 15:03:41 +02:00
{
2018-08-01 10:47:09 +02:00
check_symbol_is_endogenous ( name ) ;
2018-07-31 11:48:08 +02:00
int symb_id = mod_file - > symbol_table . getID ( name ) ;
2010-04-14 15:03:41 +02:00
mod_file - > symbol_table . addObservedVariable ( symb_id ) ;
2008-02-03 11:28:36 +01:00
}
2016-10-13 18:19:38 +02:00
void
ParsingDriver : : check_varexobs ( )
{
if ( mod_file - > symbol_table . observedExogenousVariablesNbr ( ) > 0 )
error ( " varexobs: you cannot have several 'varexobs' statements in the same MOD file " ) ;
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_varexobs ( const string & name )
2016-10-13 18:19:38 +02:00
{
2018-07-31 11:48:08 +02:00
check_symbol_existence ( name ) ;
int symb_id = mod_file - > symbol_table . getID ( name ) ;
2018-07-17 18:34:07 +02:00
if ( mod_file - > symbol_table . getType ( symb_id ) ! = SymbolType : : exogenous )
2018-07-31 11:48:08 +02:00
error ( " varexobs: " + name + " is not an exogenous variable " ) ;
2016-10-13 18:19:38 +02:00
mod_file - > symbol_table . addObservedExogenousVariable ( symb_id ) ;
}
2008-02-03 11:28:36 +01:00
void
ParsingDriver : : set_trends ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < ObservationTrendsStatement > ( move ( trend_elements ) ,
mod_file - > symbol_table ) ) ;
2008-02-03 11:28:36 +01:00
trend_elements . clear ( ) ;
}
2021-01-18 16:42:20 +01:00
void
2020-06-29 11:38:41 +02:00
ParsingDriver : : set_deterministic_trends ( )
2021-01-18 16:42:20 +01:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < DeterministicTrendsStatement > ( move ( trend_elements ) ,
mod_file - > symbol_table ) ) ;
2020-06-29 11:38:41 +02:00
trend_elements . clear ( ) ;
2021-01-18 16:42:20 +01:00
}
2008-02-03 11:28:36 +01:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : set_trend_element ( string arg1 , expr_t arg2 )
2008-02-03 11:28:36 +01:00
{
2018-07-31 11:48:08 +02:00
check_symbol_existence ( arg1 ) ;
2022-05-04 16:01:34 +02:00
if ( trend_elements . contains ( arg1 ) )
2018-07-31 11:48:08 +02:00
error ( " observation_trends: " + arg1 + " declared twice " ) ;
trend_elements [ move ( arg1 ) ] = arg2 ;
2008-02-03 11:28:36 +01:00
}
2020-06-29 11:38:41 +02:00
void
ParsingDriver : : set_filter_initial_state ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < FilterInitialStateStatement > ( move ( filter_initial_state_elements ) ,
mod_file - > symbol_table ) ) ;
2020-06-29 11:38:41 +02:00
filter_initial_state_elements . clear ( ) ;
}
2021-01-18 16:42:20 +01:00
void
ParsingDriver : : set_filter_initial_state_element ( const string & name , const string & lag , expr_t rhs )
{
check_symbol_existence ( name ) ;
int symb_id = mod_file - > symbol_table . getID ( name ) ;
SymbolType type = mod_file - > symbol_table . getType ( symb_id ) ;
int ilag = stoi ( lag ) ;
if ( type ! = SymbolType : : endogenous
& & type ! = SymbolType : : exogenous
& & type ! = SymbolType : : exogenousDet )
error ( " filter_initial_state: " + name + " should be an endogenous or exogenous variable " ) ;
if ( ( type = = SymbolType : : exogenous | | type = = SymbolType : : exogenousDet ) & & ilag = = 0 )
error ( " filter_initial_state: exogenous variable " + name + " must be provided with a lag " ) ;
2022-05-04 16:01:34 +02:00
if ( filter_initial_state_elements . contains ( { symb_id , ilag } ) )
2021-01-18 16:42:20 +01:00
error ( " filter_initial_state: ( " + name + " , " + lag + " ) declared twice " ) ;
if ( mod_file - > dynamic_model . minLagForSymbol ( symb_id ) > ilag - 1 )
error ( " filter_initial_state: variable " + name + " does not appear in the model with the lag " + to_string ( ilag - 1 ) + " (see the reference manual for the timing convention in 'filter_initial_state') " ) ;
filter_initial_state_elements [ { symb_id , ilag } ] = rhs ;
}
2008-02-03 11:28:36 +01:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : set_optim_weights ( string name , expr_t value )
2008-02-03 11:28:36 +01:00
{
2018-08-01 10:47:09 +02:00
check_symbol_is_endogenous ( name ) ;
2022-05-04 16:01:34 +02:00
if ( var_weights . contains ( name ) )
2018-07-31 11:48:08 +02:00
error ( " optim_weights: " + name + " declared twice " ) ;
var_weights [ move ( name ) ] = move ( value ) ;
2008-02-03 11:28:36 +01:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : set_optim_weights ( const string & name1 , const string & name2 , expr_t value )
2008-02-03 11:28:36 +01:00
{
2018-08-01 10:47:09 +02:00
check_symbol_is_endogenous ( name1 ) ;
check_symbol_is_endogenous ( name2 ) ;
2008-02-03 11:28:36 +01:00
2022-06-03 16:21:30 +02:00
pair covar_key { name1 , name2 } ;
2008-02-03 11:28:36 +01:00
2022-05-04 16:01:34 +02:00
if ( covar_weights . contains ( covar_key ) )
2018-07-31 11:48:08 +02:00
error ( " optim_weights: pair of variables ( " + name1 + " , " + name2
2008-02-03 11:28:36 +01:00
+ " ) declared twice " ) ;
covar_weights [ covar_key ] = value ;
}
void
ParsingDriver : : optim_weights ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < OptimWeightsStatement > ( move ( var_weights ) , move ( covar_weights ) ,
mod_file - > symbol_table ) ) ;
2008-02-03 11:28:36 +01:00
var_weights . clear ( ) ;
covar_weights . clear ( ) ;
}
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : set_osr_params ( vector < string > symbol_list )
2008-02-03 11:28:36 +01:00
{
2022-03-28 18:11:53 +02:00
mod_file - > addStatement ( make_unique < OsrParamsStatement > ( move ( symbol_list ) , mod_file - > symbol_table ) ) ;
2008-02-03 11:28:36 +01:00
}
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : run_osr ( vector < string > symbol_list )
2008-02-03 11:28:36 +01:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < OsrStatement > ( move ( symbol_list ) , move ( options_list ) ,
2022-03-28 18:11:53 +02:00
mod_file - > symbol_table ) ) ;
2008-02-03 11:28:36 +01:00
options_list . clear ( ) ;
}
void
2022-10-04 15:59:18 +02:00
ParsingDriver : : run_dynatype ( string filename , vector < string > symbol_list )
2008-02-03 11:28:36 +01:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < DynaTypeStatement > ( move ( symbol_list ) , move ( filename ) ,
2022-03-28 18:11:53 +02:00
mod_file - > symbol_table ) ) ;
2008-02-03 11:28:36 +01:00
}
void
2022-10-04 15:59:18 +02:00
ParsingDriver : : run_dynasave ( string filename , vector < string > symbol_list )
2008-02-03 11:28:36 +01:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < DynaSaveStatement > ( move ( symbol_list ) , move ( filename ) ,
2022-03-28 18:11:53 +02:00
mod_file - > symbol_table ) ) ;
2008-02-03 11:28:36 +01:00
}
2008-12-31 20:29:17 +01:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : run_load_params_and_steady_state ( const string & filename )
2008-12-31 20:29:17 +01:00
{
2018-09-05 15:17:21 +02:00
mod_file - > addStatement ( make_unique < LoadParamsAndSteadyStateStatement > ( filename , mod_file - > symbol_table , warnings ) ) ;
2008-12-31 20:29:17 +01:00
}
void
2022-10-04 15:59:18 +02:00
ParsingDriver : : run_save_params_and_steady_state ( string filename )
2008-12-31 20:29:17 +01:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < SaveParamsAndSteadyStateStatement > ( move ( filename ) ) ) ;
2008-12-31 20:29:17 +01:00
}
2009-04-20 15:58:15 +02:00
void
ParsingDriver : : run_identification ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < IdentificationStatement > ( move ( options_list ) ) ) ;
2009-10-14 18:16:43 +02:00
options_list . clear ( ) ;
2009-04-20 15:58:15 +02:00
}
2008-02-03 11:28:36 +01:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_mc_filename ( string filename , string prior )
2008-02-03 11:28:36 +01:00
{
2019-12-20 16:59:30 +01:00
for ( auto & it : filename_list )
2018-07-31 11:48:08 +02:00
if ( it . first = = filename )
error ( " model_comparison: filename " + filename + " declared twice " ) ;
filename_list . emplace_back ( move ( filename ) , move ( prior ) ) ;
2008-02-03 11:28:36 +01:00
}
void
ParsingDriver : : run_model_comparison ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < ModelComparisonStatement > ( move ( filename_list ) ,
move ( options_list ) ) ) ;
2008-02-03 11:28:36 +01:00
filename_list . clear ( ) ;
options_list . clear ( ) ;
}
void
ParsingDriver : : begin_planner_objective ( )
{
2022-09-13 15:43:13 +02:00
planner_objective = make_unique < PlannerObjective > ( mod_file - > symbol_table ,
mod_file - > num_constants ,
mod_file - > external_functions_table ) ;
2018-10-09 18:27:19 +02:00
set_current_data_tree ( planner_objective . get ( ) ) ;
2008-02-03 11:28:36 +01:00
}
void
2010-09-16 19:18:45 +02:00
ParsingDriver : : end_planner_objective ( expr_t expr )
2008-02-03 11:28:36 +01:00
{
// Add equation corresponding to expression
2010-09-16 19:18:45 +02:00
expr_t eq = model_tree - > AddEqual ( expr , model_tree - > Zero ) ;
2014-01-27 16:41:43 +01:00
model_tree - > addEquation ( eq , location . begin . line ) ;
2008-02-03 11:28:36 +01:00
2018-10-09 18:27:19 +02:00
mod_file - > addStatement ( make_unique < PlannerObjectiveStatement > ( * planner_objective ) ) ;
2008-02-03 11:28:36 +01:00
2021-11-19 17:32:45 +01:00
// Handle undeclared variables (see #81)
bool exit_after_write = false ;
if ( undeclared_model_variable_errors . size ( ) > 0 )
for ( auto & it : undeclared_model_variable_errors )
if ( nostrict )
warning ( it . second ) ;
else
{
exit_after_write = true ;
cerr < < it . second < < endl ;
}
undeclared_model_variable_errors . clear ( ) ;
if ( exit_after_write )
exit ( EXIT_FAILURE ) ;
2008-02-03 11:28:36 +01:00
reset_data_tree ( ) ;
}
2014-03-08 09:55:00 +01:00
void
ParsingDriver : : ramsey_model ( )
{
2022-02-21 16:43:18 +01:00
// Some checks to ensure correct error messages (see #90)
if ( ramsey_policy_seen )
error ( " A 'ramsey_model' statement cannot follow a 'ramsey_policy' statement. " ) ;
if ( ramsey_model_seen )
error ( " Several 'ramsey_model' statements cannot appear in a given .mod file. " ) ;
ramsey_model_seen = true ;
2014-03-08 09:55:00 +01:00
if ( ! mod_file - > symbol_table . exists ( " optimal_policy_discount_factor " ) )
2019-12-18 17:32:41 +01:00
{
if ( ! planner_discount )
planner_discount = data_tree - > One ;
declare_parameter ( " optimal_policy_discount_factor " , planner_discount_latex_name ) ;
init_param ( " optimal_policy_discount_factor " , planner_discount ) ;
}
else if ( planner_discount )
error ( " ramsey_model: the 'planner_discount' option cannot be used when the 'optimal_policy_discount_factor' parameter is explicitly declared. " ) ;
2021-09-21 17:17:36 +02:00
// Check that instruments are declared endogenous (#72)
2022-09-18 09:30:13 +02:00
if ( options_list . contains ( " instruments " ) )
for ( const auto & s : options_list . get < OptionsList : : SymbolListVal > ( " instruments " ) . getSymbols ( ) )
2021-09-21 17:17:36 +02:00
check_symbol_is_endogenous ( s ) ;
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < RamseyModelStatement > ( move ( options_list ) ) ) ;
2014-03-08 09:55:00 +01:00
options_list . clear ( ) ;
2019-12-18 17:32:41 +01:00
planner_discount = nullptr ;
planner_discount_latex_name . clear ( ) ;
2014-03-08 09:55:00 +01:00
}
2008-02-03 11:28:36 +01:00
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : ramsey_policy ( vector < string > symbol_list )
2008-02-03 11:28:36 +01:00
{
2019-12-13 16:03:37 +01:00
warning ( " The 'ramsey_policy' statement is deprecated. Please use 'ramsey_model', 'stoch_simul', and 'evaluate_planner_objective' instead. " ) ;
2019-12-18 17:32:41 +01:00
2022-02-21 16:43:18 +01:00
// Some checks to ensure correct error messages (see #90)
if ( ramsey_model_seen )
error ( " A 'ramsey_policy' statement cannot follow a 'ramsey_model' statement. " ) ;
if ( ramsey_policy_seen )
error ( " Several 'ramsey_policy' statements cannot appear in a given .mod file. " ) ;
ramsey_policy_seen = true ;
2011-05-24 15:34:03 +02:00
if ( ! mod_file - > symbol_table . exists ( " optimal_policy_discount_factor " ) )
2019-12-18 17:32:41 +01:00
{
if ( ! planner_discount )
planner_discount = data_tree - > One ;
declare_parameter ( " optimal_policy_discount_factor " ) ;
init_param ( " optimal_policy_discount_factor " , planner_discount ) ;
}
else if ( planner_discount )
error ( " ramsey_policy: the 'planner_discount' option cannot be used when the 'optimal_policy_discount_factor' parameter is explicitly declared. " ) ;
2021-09-21 17:17:36 +02:00
// Check that instruments are declared endogenous (#72)
2022-09-18 09:30:13 +02:00
if ( options_list . contains ( " instruments " ) )
for ( const auto & s : options_list . get < OptionsList : : SymbolListVal > ( " instruments " ) . getSymbols ( ) )
2021-09-21 17:17:36 +02:00
check_symbol_is_endogenous ( s ) ;
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < RamseyPolicyStatement > ( move ( symbol_list ) , move ( options_list ) ,
2022-03-28 18:11:53 +02:00
mod_file - > symbol_table ) ) ;
2008-02-03 11:28:36 +01:00
options_list . clear ( ) ;
2019-12-18 17:32:41 +01:00
planner_discount = nullptr ;
2016-12-27 13:46:01 +01:00
}
2019-12-12 11:28:07 +01:00
void
ParsingDriver : : evaluate_planner_objective ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < EvaluatePlannerObjectiveStatement > ( move ( options_list ) ) ) ;
2021-12-03 13:17:34 +01:00
options_list . clear ( ) ;
2019-12-12 11:28:07 +01:00
}
2021-07-13 15:38:25 +02:00
void
ParsingDriver : : occbin_setup ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < OccbinSetupStatement > ( move ( options_list ) ) ) ;
2021-07-13 15:38:25 +02:00
options_list . clear ( ) ;
}
void
ParsingDriver : : occbin_solver ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < OccbinSolverStatement > ( move ( options_list ) ) ) ;
2021-07-13 15:38:25 +02:00
options_list . clear ( ) ;
}
void
ParsingDriver : : occbin_write_regimes ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < OccbinWriteRegimesStatement > ( move ( options_list ) ) ) ;
2021-07-13 15:38:25 +02:00
options_list . clear ( ) ;
}
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : occbin_graph ( vector < string > symbol_list )
2021-07-13 15:38:25 +02:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < OccbinGraphStatement > ( move ( symbol_list ) , move ( options_list ) ) ) ;
2021-07-13 15:38:25 +02:00
options_list . clear ( ) ;
}
2011-03-13 21:19:55 +01:00
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : discretionary_policy ( vector < string > symbol_list )
2011-03-13 21:19:55 +01:00
{
2020-01-30 15:42:39 +01:00
/* The logic here is different from “ramsey_policy” and “ramsey_model”,
because we want to allow several instances of “ discretionary_policy ” in
the same . mod file . */
2011-05-24 15:34:03 +02:00
if ( ! mod_file - > symbol_table . exists ( " optimal_policy_discount_factor " ) )
2020-01-30 15:42:39 +01:00
declare_parameter ( " optimal_policy_discount_factor " ) ;
if ( ! planner_discount )
planner_discount = data_tree - > One ;
init_param ( " optimal_policy_discount_factor " , planner_discount ) ;
2021-09-21 17:17:36 +02:00
// Check that instruments are declared endogenous (#72)
2022-09-18 09:30:13 +02:00
if ( options_list . contains ( " instruments " ) )
for ( const auto & s : options_list . get < OptionsList : : SymbolListVal > ( " instruments " ) . getSymbols ( ) )
2021-09-21 17:17:36 +02:00
check_symbol_is_endogenous ( s ) ;
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < DiscretionaryPolicyStatement > ( move ( symbol_list ) ,
move ( options_list ) ,
2022-03-28 18:11:53 +02:00
mod_file - > symbol_table ) ) ;
2011-03-13 21:19:55 +01:00
options_list . clear ( ) ;
2020-01-30 15:42:39 +01:00
planner_discount = nullptr ;
2011-03-13 21:19:55 +01:00
}
2009-04-30 15:14:33 +02:00
void
2017-04-04 15:28:27 +02:00
ParsingDriver : : write_latex_dynamic_model ( bool write_equation_tags )
2009-04-30 15:14:33 +02:00
{
2018-09-05 15:17:21 +02:00
mod_file - > addStatement ( make_unique < WriteLatexDynamicModelStatement > ( mod_file - > dynamic_model , write_equation_tags ) ) ;
2009-04-30 15:14:33 +02:00
}
void
2017-08-24 15:35:10 +02:00
ParsingDriver : : write_latex_static_model ( bool write_equation_tags )
2009-04-30 15:14:33 +02:00
{
2018-09-05 15:17:21 +02:00
mod_file - > addStatement ( make_unique < WriteLatexStaticModelStatement > ( mod_file - > static_model , write_equation_tags ) ) ;
2009-04-30 15:14:33 +02:00
}
2015-02-16 08:31:30 +01:00
void
2017-08-24 15:35:10 +02:00
ParsingDriver : : write_latex_original_model ( bool write_equation_tags )
2015-02-16 08:31:30 +01:00
{
2018-09-05 15:17:21 +02:00
mod_file - > addStatement ( make_unique < WriteLatexOriginalModelStatement > ( mod_file - > original_model , write_equation_tags ) ) ;
2015-02-16 08:31:30 +01:00
}
2017-08-30 11:32:01 +02:00
void
ParsingDriver : : write_latex_steady_state_model ( )
{
2018-09-05 15:17:21 +02:00
mod_file - > addStatement ( make_unique < WriteLatexSteadyStateModelStatement > ( mod_file - > steady_state_model ) ) ;
2017-08-30 11:32:01 +02:00
}
2008-02-03 11:28:36 +01:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : bvar_density ( const string & maxnlags )
2008-02-03 11:28:36 +01:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < BVARDensityStatement > ( stoi ( maxnlags ) , move ( options_list ) ) ) ;
2008-02-03 11:28:36 +01:00
options_list . clear ( ) ;
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : bvar_forecast ( const string & nlags )
2008-02-03 11:28:36 +01:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < BVARForecastStatement > ( stoi ( nlags ) , move ( options_list ) ) ) ;
2008-02-03 11:28:36 +01:00
options_list . clear ( ) ;
}
2009-07-26 19:07:07 +02:00
void
ParsingDriver : : sbvar ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < SBVARStatement > ( move ( options_list ) ) ) ;
2009-07-26 19:07:07 +02:00
options_list . clear ( ) ;
}
void
2011-05-11 19:02:39 +02:00
ParsingDriver : : ms_estimation ( )
2009-07-26 19:07:07 +02:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < MSSBVAREstimationStatement > ( move ( options_list ) ) ) ;
2011-05-11 19:02:39 +02:00
options_list . clear ( ) ;
}
void
ParsingDriver : : ms_simulation ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < MSSBVARSimulationStatement > ( move ( options_list ) ) ) ;
2011-05-11 19:02:39 +02:00
options_list . clear ( ) ;
}
void
ParsingDriver : : ms_compute_mdd ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < MSSBVARComputeMDDStatement > ( move ( options_list ) ) ) ;
2011-05-11 19:02:39 +02:00
options_list . clear ( ) ;
}
void
ParsingDriver : : ms_compute_probabilities ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < MSSBVARComputeProbabilitiesStatement > ( move ( options_list ) ) ) ;
2011-05-11 19:02:39 +02:00
options_list . clear ( ) ;
}
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : ms_irf ( vector < string > symbol_list )
2011-05-11 19:02:39 +02:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < MSSBVARIrfStatement > ( move ( symbol_list ) , move ( options_list ) ,
2022-03-28 18:11:53 +02:00
mod_file - > symbol_table ) ) ;
2011-05-11 19:02:39 +02:00
options_list . clear ( ) ;
}
void
ParsingDriver : : ms_forecast ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < MSSBVARForecastStatement > ( move ( options_list ) ) ) ;
2011-05-11 19:02:39 +02:00
options_list . clear ( ) ;
}
void
ParsingDriver : : ms_variance_decomposition ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < MSSBVARVarianceDecompositionStatement > ( move ( options_list ) ) ) ;
2009-07-26 19:07:07 +02:00
options_list . clear ( ) ;
}
2009-12-09 01:38:53 +01:00
void
ParsingDriver : : svar ( )
{
2022-09-18 09:30:13 +02:00
bool has_coefficients = options_list . contains ( " ms.coefficients " ) ,
has_variances = options_list . contains ( " ms.variances " ) ,
has_constants = options_list . contains ( " ms.constants " ) ;
2022-05-04 14:42:03 +02:00
if ( ! has_coefficients & & ! has_variances & & ! has_constants )
2009-12-09 01:38:53 +01:00
error ( " You must pass one of 'coefficients', 'variances', or 'constants'. " ) ;
2022-05-04 14:42:03 +02:00
if ( ( has_coefficients & & has_variances ) | | ( has_variances & & has_constants )
| | ( has_coefficients & & has_constants ) )
2011-09-15 20:18:37 +02:00
error ( " You may only pass one of 'coefficients', 'variances', or 'constants'. " ) ;
2009-12-09 01:38:53 +01:00
2022-09-18 09:30:13 +02:00
try
{
if ( stoi ( options_list . get < OptionsList : : NumVal > ( " ms.chain " ) ) < = 0 )
error ( " The value passed to the 'chain' option must be greater than zero. " ) ;
}
catch ( OptionsList : : UnknownOptionException & )
{
error ( " A 'chain' option must be passed to the 'svar' statement. " ) ;
}
2009-12-09 01:38:53 +01:00
2022-09-18 09:30:13 +02:00
if ( options_list . contains ( " ms.equations " ) )
for ( int viit : options_list . get < vector < int > > ( " ms.equations " ) )
2018-06-04 12:26:16 +02:00
if ( viit < = 0 )
2022-09-18 09:30:13 +02:00
error ( " The value(s) passed to the 'equations' option must be greater than zero. " ) ;
2009-12-09 01:38:53 +01:00
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < SvarStatement > ( move ( options_list ) ) ) ;
2009-12-09 01:38:53 +01:00
options_list . clear ( ) ;
}
2009-12-08 17:46:13 +01:00
void
ParsingDriver : : markov_switching ( )
{
2022-09-18 09:30:13 +02:00
try
{
if ( stoi ( options_list . get < OptionsList : : NumVal > ( " ms.chain " ) ) < = 0 )
error ( " The value passed to the chain option must be greater than zero. " ) ;
if ( stoi ( options_list . get < OptionsList : : NumVal > ( " ms.number_of_regimes " ) ) < = 0 )
error ( " The value passed to the number_of_regimes option must be greater than zero. " ) ;
options_list . get < OptionsList : : NumVal > ( " ms.duration " ) ; // Just check its presence
}
catch ( OptionsList : : UnknownOptionException & e )
{
error ( " A ' " + e . name . substr ( 3 ) + " ' option must be passed to the 'markov_switching' statement. " ) ;
}
2009-12-08 17:46:13 +01:00
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < MarkovSwitchingStatement > ( move ( options_list ) ) ) ;
2009-12-08 17:46:13 +01:00
options_list . clear ( ) ;
}
2009-08-29 17:04:11 +02:00
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : shock_decomposition ( vector < string > symbol_list )
2009-07-23 10:31:48 +02:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < ShockDecompositionStatement > ( move ( symbol_list ) ,
move ( options_list ) ,
2022-03-28 18:11:53 +02:00
mod_file - > symbol_table ) ) ;
2009-07-23 10:31:48 +02:00
options_list . clear ( ) ;
}
2009-08-29 17:04:11 +02:00
2017-03-21 14:58:15 +01:00
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : realtime_shock_decomposition ( vector < string > symbol_list )
2017-03-21 14:58:15 +01:00
{
2022-03-28 18:11:53 +02:00
mod_file - > addStatement ( make_unique < RealtimeShockDecompositionStatement > ( move ( symbol_list ) ,
2022-10-04 15:59:18 +02:00
move ( options_list ) ,
2022-03-28 18:11:53 +02:00
mod_file - > symbol_table ) ) ;
2017-03-21 14:58:15 +01:00
options_list . clear ( ) ;
}
2017-03-22 11:30:35 +01:00
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : plot_shock_decomposition ( vector < string > symbol_list )
2017-03-22 11:30:35 +01:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < PlotShockDecompositionStatement > ( move ( symbol_list ) ,
move ( options_list ) ,
2022-03-28 18:11:53 +02:00
mod_file - > symbol_table ) ) ;
2017-03-22 11:30:35 +01:00
options_list . clear ( ) ;
}
2017-03-31 12:50:17 +02:00
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : initial_condition_decomposition ( vector < string > symbol_list )
2017-03-31 12:50:17 +02:00
{
2022-03-28 18:11:53 +02:00
mod_file - > addStatement ( make_unique < InitialConditionDecompositionStatement > ( move ( symbol_list ) ,
2022-10-04 15:59:18 +02:00
move ( options_list ) ,
2022-03-28 18:11:53 +02:00
mod_file - > symbol_table ) ) ;
2017-03-31 12:50:17 +02:00
options_list . clear ( ) ;
}
2019-12-14 08:42:09 +01:00
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : squeeze_shock_decomposition ( vector < string > symbol_list )
2019-12-14 08:42:09 +01:00
{
2022-03-28 18:11:53 +02:00
mod_file - > addStatement ( make_unique < SqueezeShockDecompositionStatement > ( move ( symbol_list ) ,
mod_file - > symbol_table ) ) ;
2019-12-14 08:42:09 +01:00
}
2009-10-16 19:23:57 +02:00
void
ParsingDriver : : conditional_forecast ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < ConditionalForecastStatement > ( move ( options_list ) ) ) ;
2009-10-16 19:23:57 +02:00
options_list . clear ( ) ;
}
void
2022-05-16 14:52:47 +02:00
ParsingDriver : : plot_conditional_forecast ( const optional < string > & periods , vector < string > symbol_list )
2009-10-16 19:23:57 +02:00
{
2022-05-16 14:52:47 +02:00
optional < int > iperiods ;
if ( periods )
iperiods = stoi ( * periods ) ;
mod_file - > addStatement ( make_unique < PlotConditionalForecastStatement > ( move ( iperiods ) , move ( symbol_list ) ,
2022-03-28 18:11:53 +02:00
mod_file - > symbol_table ) ) ;
2009-10-16 19:23:57 +02:00
}
void
ParsingDriver : : conditional_forecast_paths ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < ConditionalForecastPathsStatement > ( move ( det_shocks ) ,
mod_file - > symbol_table ) ) ;
2009-10-16 19:23:57 +02:00
det_shocks . clear ( ) ;
2022-04-26 15:21:45 +02:00
if ( ! learnt_shocks_add . empty ( ) )
error ( " conditional_forecast_paths: 'add' keyword not allowed " ) ;
if ( ! learnt_shocks_multiply . empty ( ) )
error ( " conditional_forecast_paths: 'multiply' keyword not allowed " ) ;
2009-10-16 19:23:57 +02:00
}
2012-05-30 16:28:00 +02:00
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : calib_smoother ( vector < string > symbol_list )
2012-05-30 16:28:00 +02:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < CalibSmootherStatement > ( move ( symbol_list ) , move ( options_list ) ,
2022-03-28 18:11:53 +02:00
mod_file - > symbol_table ) ) ;
2012-05-30 16:28:00 +02:00
options_list . clear ( ) ;
}
2012-06-08 17:36:32 +02:00
void
ParsingDriver : : extended_path ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < ExtendedPathStatement > ( move ( options_list ) ) ) ;
2012-06-08 17:36:32 +02:00
options_list . clear ( ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_model_equal ( expr_t arg1 , expr_t arg2 )
2008-02-03 11:28:36 +01:00
{
2010-09-16 19:18:45 +02:00
expr_t id = model_tree - > AddEqual ( arg1 , arg2 ) ;
2013-04-11 17:07:39 +02:00
2022-05-04 16:01:34 +02:00
if ( eq_tags . contains ( " static " ) )
2013-04-11 17:07:39 +02:00
{
2021-07-20 18:18:24 +02:00
// If the equation is tagged [static]
2013-04-11 17:07:39 +02:00
if ( ! id - > isInStaticForm ( ) )
error ( " An equation tagged [static] cannot contain leads, lags, expectations or STEADY_STATE operators " ) ;
2017-06-01 19:58:32 +02:00
2017-08-24 15:35:10 +02:00
dynamic_model - > addStaticOnlyEquation ( id , location . begin . line , eq_tags ) ;
2013-04-11 17:07:39 +02:00
}
2022-05-04 16:01:34 +02:00
else if ( eq_tags . contains ( " bind " ) | | eq_tags . contains ( " relax " ) )
2021-07-20 18:18:24 +02:00
{
// If the equation has a “bind” or “relax” tag (occbin case)
2022-05-04 16:01:34 +02:00
if ( ! eq_tags . contains ( " name " ) )
2021-07-20 18:18:24 +02:00
error ( " An equation with a 'bind' or 'relax' tag must have a 'name' tag " ) ;
2022-10-11 14:30:53 +02:00
auto regimes_bind = DataTree : : strsplit ( eq_tags [ " bind " ] , ' , ' ) ;
auto regimes_relax = DataTree : : strsplit ( eq_tags [ " relax " ] , ' , ' ) ;
2021-07-20 18:18:24 +02:00
auto regimes_all = regimes_bind ;
regimes_all . insert ( regimes_all . end ( ) , regimes_relax . begin ( ) , regimes_relax . end ( ) ) ; // Concatenate the two vectors
for ( const auto & regime : regimes_all )
{
if ( ! isSymbolIdentifier ( regime ) )
error ( " The string ' " + regime + " ' is not a valid Occbin regime name (contains unauthorized characters) " ) ;
string param_name = buildOccbinBindParamName ( regime ) ;
try
{
if ( mod_file - > symbol_table . getType ( param_name ) ! = SymbolType : : parameter )
error ( " The name ' " + param_name + " ' is already used. Please use another name for Occbin regime ' " + regime + " ' " ) ;
}
catch ( SymbolTable : : UnknownSymbolNameException & e )
{
// Declare and initialize the new parameter
int symb_id = mod_file - > symbol_table . addSymbol ( param_name , SymbolType : : parameter ) ;
mod_file - > addStatement ( make_unique < InitParamStatement > ( symb_id , dynamic_model - > Zero , mod_file - > symbol_table ) ) ;
}
}
eq_tags . erase ( " bind " ) ;
eq_tags . erase ( " relax " ) ;
dynamic_model - > addOccbinEquation ( id , location . begin . line , eq_tags , regimes_bind , regimes_relax ) ;
}
else // General case
2014-01-27 16:41:43 +01:00
model_tree - > addEquation ( id , location . begin . line , eq_tags ) ;
2013-04-11 17:07:39 +02:00
eq_tags . clear ( ) ;
2008-02-03 11:28:36 +01:00
return id ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_model_equal_with_zero_rhs ( expr_t arg )
2008-02-03 11:28:36 +01:00
{
return add_model_equal ( arg , model_tree - > Zero ) ;
}
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : model_local_variable ( const vector < pair < string , string > > & symbol_list )
2017-08-28 15:14:11 +02:00
{
2022-03-28 18:11:53 +02:00
for ( auto & [ name , tex_name ] : symbol_list )
declare_symbol ( name , SymbolType : : modelLocalVariable , tex_name , { } ) ;
2017-08-28 15:14:11 +02:00
}
2008-02-03 11:28:36 +01:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : declare_and_init_model_local_variable ( const string & name , expr_t rhs )
2008-02-03 11:28:36 +01:00
{
2010-04-23 18:39:07 +02:00
int symb_id ;
2008-02-03 11:28:36 +01:00
try
{
2018-07-31 11:48:08 +02:00
symb_id = mod_file - > symbol_table . addSymbol ( name , SymbolType : : modelLocalVariable ) ;
2008-02-03 11:28:36 +01:00
}
2009-12-16 18:13:23 +01:00
catch ( SymbolTable : : AlreadyDeclaredException & e )
2008-02-03 11:28:36 +01:00
{
2021-04-16 17:34:13 +02:00
/* It can have already been declared in a steady_state_model block or
model_local_variable statement , check that it is indeed a
ModelLocalVariable */
2018-07-31 11:48:08 +02:00
symb_id = mod_file - > symbol_table . getID ( name ) ;
2018-07-17 18:34:07 +02:00
if ( mod_file - > symbol_table . getType ( symb_id ) ! = SymbolType : : modelLocalVariable )
2018-07-31 11:48:08 +02:00
error ( name + " has wrong type or was already used on the right-hand side. You cannot use it on the left-hand side of a pound ('#') expression " ) ;
2008-02-03 11:28:36 +01:00
}
2010-04-23 18:39:07 +02:00
try
{
model_tree - > AddLocalVariable ( symb_id , rhs ) ;
}
catch ( DataTree : : LocalVariableException & e )
{
2018-07-31 11:48:08 +02:00
error ( " Local model variable " + name + " declared twice. " ) ;
2010-04-23 18:39:07 +02:00
}
2008-02-03 11:28:36 +01:00
}
2009-03-11 12:43:18 +01:00
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : change_type ( SymbolType new_type , const vector < string > & symbol_list )
2009-03-11 12:43:18 +01:00
{
2022-03-28 18:11:53 +02:00
for ( auto & it : symbol_list )
2009-03-11 12:43:18 +01:00
{
int id ;
try
{
2018-07-31 11:48:08 +02:00
id = mod_file - > symbol_table . getID ( it ) ;
2009-03-11 12:43:18 +01:00
}
2009-12-16 18:13:23 +01:00
catch ( SymbolTable : : UnknownSymbolNameException & e )
2009-03-11 12:43:18 +01:00
{
2018-07-31 11:48:08 +02:00
error ( " Unknown variable " + it ) ;
2009-03-11 12:43:18 +01:00
}
// Check if symbol already used in a VariableNode
if ( mod_file - > expressions_tree . isSymbolUsed ( id )
2009-04-14 16:39:53 +02:00
| | mod_file - > dynamic_model . isSymbolUsed ( id ) )
2018-07-31 11:48:08 +02:00
error ( " You cannot modify the type of symbol " + it + " after having used it in an expression " ) ;
2009-03-11 12:43:18 +01:00
mod_file - > symbol_table . changeType ( id , new_type ) ;
}
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_plus ( expr_t arg1 , expr_t arg2 )
2008-02-03 11:28:36 +01:00
{
return data_tree - > AddPlus ( arg1 , arg2 ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_minus ( expr_t arg1 , expr_t arg2 )
2008-02-03 11:28:36 +01:00
{
return data_tree - > AddMinus ( arg1 , arg2 ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_uminus ( expr_t arg1 )
2008-02-03 11:28:36 +01:00
{
return data_tree - > AddUMinus ( arg1 ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_times ( expr_t arg1 , expr_t arg2 )
2008-02-03 11:28:36 +01:00
{
return data_tree - > AddTimes ( arg1 , arg2 ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_divide ( expr_t arg1 , expr_t arg2 )
2008-02-03 11:28:36 +01:00
{
2014-10-03 16:54:59 +02:00
try
{
return data_tree - > AddDivide ( arg1 , arg2 ) ;
}
catch ( DataTree : : DivisionByZeroException )
{
2017-11-07 12:02:31 +01:00
error ( " Division by zero error encountered when reading model from .mod file " ) ;
2014-10-03 16:54:59 +02:00
}
2008-02-03 11:28:36 +01:00
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_less ( expr_t arg1 , expr_t arg2 )
2008-02-03 11:28:36 +01:00
{
return data_tree - > AddLess ( arg1 , arg2 ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_greater ( expr_t arg1 , expr_t arg2 )
2008-02-03 11:28:36 +01:00
{
return data_tree - > AddGreater ( arg1 , arg2 ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_less_equal ( expr_t arg1 , expr_t arg2 )
2008-02-03 11:28:36 +01:00
{
return data_tree - > AddLessEqual ( arg1 , arg2 ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_greater_equal ( expr_t arg1 , expr_t arg2 )
2008-02-03 11:28:36 +01:00
{
return data_tree - > AddGreaterEqual ( arg1 , arg2 ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_equal_equal ( expr_t arg1 , expr_t arg2 )
2008-02-03 11:28:36 +01:00
{
return data_tree - > AddEqualEqual ( arg1 , arg2 ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_different ( expr_t arg1 , expr_t arg2 )
2008-02-03 11:28:36 +01:00
{
return data_tree - > AddDifferent ( arg1 , arg2 ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_power ( expr_t arg1 , expr_t arg2 )
2008-02-03 11:28:36 +01:00
{
return data_tree - > AddPower ( arg1 , arg2 ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_expectation ( const string & arg1 , expr_t arg2 )
2009-10-29 18:16:10 +01:00
{
2021-07-21 16:16:39 +02:00
if ( data_tree = = occbin_constraints_tree . get ( ) )
error ( " The 'expectation' operator is forbidden in 'occbin_constraints'. " ) ;
2018-07-31 11:48:08 +02:00
return data_tree - > AddExpectation ( stoi ( arg1 ) , arg2 ) ;
2009-10-29 18:16:10 +01:00
}
2016-11-03 17:08:06 +01:00
expr_t
2018-08-01 19:41:44 +02:00
ParsingDriver : : add_var_expectation ( const string & model_name )
2016-11-03 17:08:06 +01:00
{
2021-07-21 16:16:39 +02:00
if ( data_tree = = occbin_constraints_tree . get ( ) )
error ( " The 'var_expectation' operator is forbidden in 'occbin_constraints'. " ) ;
2018-08-01 19:41:44 +02:00
return data_tree - > AddVarExpectation ( model_name ) ;
2016-11-03 17:08:06 +01:00
}
2018-01-30 16:33:16 +01:00
expr_t
2021-10-29 14:08:03 +02:00
ParsingDriver : : add_pac_expectation ( const string & model_name )
2018-01-30 16:33:16 +01:00
{
2021-07-21 16:16:39 +02:00
if ( data_tree = = occbin_constraints_tree . get ( ) )
2021-10-29 14:08:03 +02:00
error ( " The 'pac_expectation' operator is forbidden in 'occbin_constraints'. " ) ;
2021-07-21 16:16:39 +02:00
2021-10-29 14:08:03 +02:00
return data_tree - > AddPacExpectation ( model_name ) ;
2018-02-07 16:50:49 +01:00
}
2021-10-26 18:06:26 +02:00
expr_t
ParsingDriver : : add_pac_target_nonstationary ( const string & model_name )
{
if ( data_tree = = occbin_constraints_tree . get ( ) )
error ( " The 'pac_target_nonstationary' operator is forbidden in 'occbin_constraints'. " ) ;
return data_tree - > AddPacTargetNonstationary ( model_name ) ;
}
2019-02-28 19:22:34 +01:00
void
ParsingDriver : : begin_pac_model ( )
{
parsing_pac_model = true ;
pac_growth = nullptr ;
2021-11-18 17:08:08 +01:00
pac_auxname . clear ( ) ;
pac_kind = PacTargetKind : : unspecified ;
2019-02-28 19:22:34 +01:00
}
2018-02-07 16:50:49 +01:00
void
2018-03-28 18:46:15 +02:00
ParsingDriver : : pac_model ( )
2018-02-07 16:50:49 +01:00
{
2022-09-18 09:30:13 +02:00
try
{
auto discount { options_list . get < OptionsList : : StringVal > ( " pac.discount " ) } ;
check_symbol_is_parameter ( discount ) ;
mod_file - > pac_model_table . addPacModel ( options_list . get < OptionsList : : StringVal > ( " pac.model_name " ) ,
options_list . get_if < OptionsList : : StringVal > ( " pac.aux_model_name " ) . value_or ( OptionsList : : StringVal { } ) ,
move ( discount ) , pac_growth ,
pac_auxname , pac_kind ) ;
}
catch ( OptionsList : : UnknownOptionException & e )
{
error ( " You must pass the ' " + e . name . substr ( 4 ) + " ' option to the 'pac_model' statement. " ) ;
}
2018-03-28 18:46:15 +02:00
2022-06-13 14:26:55 +02:00
options_list . clear ( ) ;
2019-02-28 19:22:34 +01:00
parsing_pac_model = false ;
2018-01-30 16:33:16 +01:00
}
2019-01-24 19:35:30 +01:00
void
2019-02-28 19:22:34 +01:00
ParsingDriver : : set_pac_growth ( expr_t pac_growth_arg )
2019-01-24 19:35:30 +01:00
{
2019-02-28 19:22:34 +01:00
pac_growth = pac_growth_arg ;
reset_data_tree ( ) ;
2019-01-24 19:35:30 +01:00
}
2021-11-18 17:08:08 +01:00
void
ParsingDriver : : set_pac_auxname ( string auxname )
{
pac_auxname = move ( auxname ) ;
}
void
ParsingDriver : : set_pac_kind ( PacTargetKind kind )
{
pac_kind = kind ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_exp ( expr_t arg1 )
2008-02-03 11:28:36 +01:00
{
return data_tree - > AddExp ( arg1 ) ;
}
2017-06-12 14:56:44 +02:00
expr_t
ParsingDriver : : add_diff ( expr_t arg1 )
{
return data_tree - > AddDiff ( arg1 ) ;
}
expr_t
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_adl ( expr_t arg1 , const string & name , const string & lag )
2017-06-12 14:56:44 +02:00
{
2018-07-31 11:48:08 +02:00
vector < int > lags ;
for ( int i = 1 ; i < = stoi ( lag ) ; i + + )
lags . push_back ( i ) ;
2018-02-28 11:31:08 +01:00
return add_adl ( arg1 , name , lags ) ;
2017-06-12 14:56:44 +02:00
}
2017-07-03 17:21:11 +02:00
expr_t
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_adl ( expr_t arg1 , const string & name , const vector < int > & lags )
2017-07-03 17:21:11 +02:00
{
2018-07-31 11:48:08 +02:00
expr_t id = data_tree - > AddAdl ( arg1 , name , lags ) ;
2017-07-03 17:21:11 +02:00
// Declare parameters here so that parameters can be initialized after the model block
2018-07-31 11:48:08 +02:00
for ( auto i : lags )
declare_parameter ( name + " _lag_ " + to_string ( i ) ) ;
2017-07-03 17:21:11 +02:00
return id ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_log ( expr_t arg1 )
2008-02-03 11:28:36 +01:00
{
return data_tree - > AddLog ( arg1 ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_log10 ( expr_t arg1 )
2008-02-03 11:28:36 +01:00
{
return data_tree - > AddLog10 ( arg1 ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_cos ( expr_t arg1 )
2008-02-03 11:28:36 +01:00
{
return data_tree - > AddCos ( arg1 ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_sin ( expr_t arg1 )
2008-02-03 11:28:36 +01:00
{
return data_tree - > AddSin ( arg1 ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_tan ( expr_t arg1 )
2008-02-03 11:28:36 +01:00
{
return data_tree - > AddTan ( arg1 ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_acos ( expr_t arg1 )
2008-02-03 11:28:36 +01:00
{
2009-04-16 12:33:30 +02:00
return data_tree - > AddAcos ( arg1 ) ;
2008-02-03 11:28:36 +01:00
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_asin ( expr_t arg1 )
2008-02-03 11:28:36 +01:00
{
2009-04-16 12:33:30 +02:00
return data_tree - > AddAsin ( arg1 ) ;
2008-02-03 11:28:36 +01:00
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_atan ( expr_t arg1 )
2008-02-03 11:28:36 +01:00
{
2009-04-16 12:33:30 +02:00
return data_tree - > AddAtan ( arg1 ) ;
2008-02-03 11:28:36 +01:00
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_cosh ( expr_t arg1 )
2008-02-03 11:28:36 +01:00
{
2009-04-16 12:33:30 +02:00
return data_tree - > AddCosh ( arg1 ) ;
2008-02-03 11:28:36 +01:00
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_sinh ( expr_t arg1 )
2008-02-03 11:28:36 +01:00
{
2009-04-16 12:33:30 +02:00
return data_tree - > AddSinh ( arg1 ) ;
2008-02-03 11:28:36 +01:00
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_tanh ( expr_t arg1 )
2008-02-03 11:28:36 +01:00
{
2009-04-16 12:33:30 +02:00
return data_tree - > AddTanh ( arg1 ) ;
2008-02-03 11:28:36 +01:00
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_acosh ( expr_t arg1 )
2008-02-03 11:28:36 +01:00
{
2009-04-16 12:33:30 +02:00
return data_tree - > AddAcosh ( arg1 ) ;
2008-02-03 11:28:36 +01:00
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_asinh ( expr_t arg1 )
2008-02-03 11:28:36 +01:00
{
2009-04-16 12:33:30 +02:00
return data_tree - > AddAsinh ( arg1 ) ;
2008-02-03 11:28:36 +01:00
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_atanh ( expr_t arg1 )
2008-02-03 11:28:36 +01:00
{
2009-04-16 12:33:30 +02:00
return data_tree - > AddAtanh ( arg1 ) ;
2008-02-03 11:28:36 +01:00
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_sqrt ( expr_t arg1 )
2008-02-03 11:28:36 +01:00
{
2009-04-16 12:33:30 +02:00
return data_tree - > AddSqrt ( arg1 ) ;
2008-02-03 11:28:36 +01:00
}
2019-07-15 18:18:26 +02:00
expr_t
ParsingDriver : : add_cbrt ( expr_t arg1 )
{
return data_tree - > AddCbrt ( arg1 ) ;
}
2011-08-12 13:20:53 +02:00
expr_t
ParsingDriver : : add_abs ( expr_t arg1 )
{
return data_tree - > AddAbs ( arg1 ) ;
}
expr_t
ParsingDriver : : add_sign ( expr_t arg1 )
{
return data_tree - > AddSign ( arg1 ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_max ( expr_t arg1 , expr_t arg2 )
2008-02-03 11:28:36 +01:00
{
2009-12-16 18:13:23 +01:00
return data_tree - > AddMax ( arg1 , arg2 ) ;
2008-02-03 11:28:36 +01:00
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_min ( expr_t arg1 , expr_t arg2 )
2008-02-03 11:28:36 +01:00
{
2009-12-16 18:13:23 +01:00
return data_tree - > AddMin ( arg1 , arg2 ) ;
2008-02-03 11:28:36 +01:00
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_normcdf ( expr_t arg1 , expr_t arg2 , expr_t arg3 )
2008-02-03 11:28:36 +01:00
{
2009-12-16 18:13:23 +01:00
return data_tree - > AddNormcdf ( arg1 , arg2 , arg3 ) ;
2008-02-03 11:28:36 +01:00
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_normcdf ( expr_t arg )
2008-09-04 10:10:42 +02:00
{
return add_normcdf ( arg , data_tree - > Zero , data_tree - > One ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_normpdf ( expr_t arg1 , expr_t arg2 , expr_t arg3 )
2010-03-11 09:43:16 +01:00
{
return data_tree - > AddNormpdf ( arg1 , arg2 , arg3 ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_normpdf ( expr_t arg )
2010-03-11 09:43:16 +01:00
{
return add_normpdf ( arg , data_tree - > Zero , data_tree - > One ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_erf ( expr_t arg1 )
2010-03-11 11:57:34 +01:00
{
return data_tree - > AddErf ( arg1 ) ;
}
2021-12-07 15:19:40 +01:00
expr_t
ParsingDriver : : add_erfc ( expr_t arg1 )
{
return data_tree - > AddErfc ( arg1 ) ;
}
2010-09-16 19:18:45 +02:00
expr_t
ParsingDriver : : add_steady_state ( expr_t arg1 )
2009-09-10 22:09:16 +02:00
{
2019-11-27 17:26:16 +01:00
// Forbid exogenous variables, see dynare#825
2021-07-20 12:10:58 +02:00
if ( arg1 - > hasExogenous ( ) )
2019-11-27 17:26:16 +01:00
error ( " Exogenous variables are not allowed in the context of the STEADY_STATE() operator. " ) ;
2009-09-10 22:09:16 +02:00
return data_tree - > AddSteadyState ( arg1 ) ;
}
2010-02-22 17:33:38 +01:00
void
ParsingDriver : : external_function_option ( const string & name_option , const string & opt )
{
if ( name_option = = " name " )
{
if ( opt . empty ( ) )
error ( " An argument must be passed to the 'name' option of the external_function() statement. " ) ;
2018-07-31 11:48:08 +02:00
declare_symbol ( opt , SymbolType : : externalFunction , " " , { } ) ;
2010-02-24 15:10:11 +01:00
current_external_function_id = mod_file - > symbol_table . getID ( opt ) ;
2010-02-22 17:33:38 +01:00
}
else if ( name_option = = " first_deriv_provided " )
{
if ( opt . empty ( ) )
2018-10-02 18:10:12 +02:00
current_external_function_options . firstDerivSymbID = ExternalFunctionsTable : : IDSetButNoNameProvided ;
2010-02-22 17:33:38 +01:00
else
{
2022-03-29 16:44:04 +02:00
int symb_id = declare_symbol ( opt , SymbolType : : externalFunction , " " , { } ) ;
current_external_function_options . firstDerivSymbID = symb_id ;
2010-02-22 17:33:38 +01:00
}
}
else if ( name_option = = " second_deriv_provided " )
{
if ( opt . empty ( ) )
2018-10-02 18:10:12 +02:00
current_external_function_options . secondDerivSymbID = ExternalFunctionsTable : : IDSetButNoNameProvided ;
2010-02-22 17:33:38 +01:00
else
{
2022-03-29 16:44:04 +02:00
int symb_id = declare_symbol ( opt , SymbolType : : externalFunction , " " , { } ) ;
current_external_function_options . secondDerivSymbID = symb_id ;
2010-02-22 17:33:38 +01:00
}
}
else if ( name_option = = " nargs " )
2018-07-04 12:40:57 +02:00
current_external_function_options . nargs = stoi ( opt ) ;
2010-02-22 17:33:38 +01:00
else
error ( " Unexpected error in ParsingDriver::external_function_option(): Please inform Dynare Team. " ) ;
}
void
ParsingDriver : : external_function ( )
{
2018-10-02 18:10:12 +02:00
if ( current_external_function_id = = ExternalFunctionsTable : : IDNotSet )
2010-02-22 17:33:38 +01:00
error ( " The 'name' option must be passed to external_function(). " ) ;
2011-02-04 16:25:38 +01:00
if ( current_external_function_options . secondDerivSymbID > = 0
2019-12-20 16:59:30 +01:00
& & current_external_function_options . firstDerivSymbID = = ExternalFunctionsTable : : IDNotSet )
2010-02-22 17:33:38 +01:00
error ( " If the second derivative is provided to the external_function command, the first derivative must also be provided. " ) ;
2018-10-02 18:10:12 +02:00
if ( current_external_function_options . secondDerivSymbID = = ExternalFunctionsTable : : IDSetButNoNameProvided
2019-12-20 16:59:30 +01:00
& & current_external_function_options . firstDerivSymbID ! = ExternalFunctionsTable : : IDSetButNoNameProvided )
2010-02-24 15:10:11 +01:00
error ( " If the second derivative is provided in the top-level function, the first derivative must also be provided in that function. " ) ;
2010-03-03 11:40:13 +01:00
mod_file - > external_functions_table . addExternalFunction ( current_external_function_id , current_external_function_options , true ) ;
2010-02-22 17:33:38 +01:00
reset_current_external_function_options ( ) ;
}
void
ParsingDriver : : push_external_function_arg_vector_onto_stack ( )
2008-02-03 11:28:36 +01:00
{
2022-06-02 10:50:21 +02:00
stack_external_function_args . push ( { } ) ;
2010-02-22 17:33:38 +01:00
}
void
2010-09-16 19:18:45 +02:00
ParsingDriver : : add_external_function_arg ( expr_t arg )
2010-02-22 17:33:38 +01:00
{
stack_external_function_args . top ( ) . push_back ( arg ) ;
2008-02-03 11:28:36 +01:00
}
2022-06-08 12:34:25 +02:00
optional < int >
2016-10-07 15:02:42 +02:00
ParsingDriver : : is_there_one_integer_argument ( ) const
{
if ( stack_external_function_args . top ( ) . size ( ) ! = 1 )
2022-06-08 12:34:25 +02:00
return nullopt ;
2016-10-07 15:02:42 +02:00
2019-12-16 19:42:59 +01:00
auto numNode = dynamic_cast < NumConstNode * > ( stack_external_function_args . top ( ) . front ( ) ) ;
auto unaryNode = dynamic_cast < UnaryOpNode * > ( stack_external_function_args . top ( ) . front ( ) ) ;
2016-10-07 15:02:42 +02:00
2019-12-16 19:42:59 +01:00
if ( ! numNode & & ! unaryNode )
2022-06-08 12:34:25 +02:00
return nullopt ;
2016-10-07 15:02:42 +02:00
eval_context_t ectmp ;
double model_var_arg ;
2019-12-16 19:42:59 +01:00
if ( ! unaryNode )
2016-10-07 15:02:42 +02:00
{
try
{
model_var_arg = numNode - > eval ( ectmp ) ;
}
catch ( ExprNode : : EvalException & e )
{
2022-06-08 12:34:25 +02:00
return nullopt ;
2016-10-07 15:02:42 +02:00
}
}
else
2018-11-28 14:32:26 +01:00
if ( unaryNode - > op_code ! = UnaryOpcode : : uminus )
2022-06-08 12:34:25 +02:00
return nullopt ;
2016-10-07 15:02:42 +02:00
else
{
try
{
model_var_arg = unaryNode - > eval ( ectmp ) ;
}
catch ( ExprNode : : EvalException & e )
{
2022-06-08 12:34:25 +02:00
return nullopt ;
2016-10-07 15:02:42 +02:00
}
}
if ( model_var_arg ! = floor ( model_var_arg ) )
2022-06-08 12:34:25 +02:00
return nullopt ;
return static_cast < int > ( model_var_arg ) ;
2016-10-07 15:02:42 +02:00
}
2010-09-16 19:18:45 +02:00
expr_t
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_model_var_or_external_function ( const string & function_name , bool in_model_block )
2008-02-03 11:28:36 +01:00
{
2010-09-16 19:18:45 +02:00
expr_t nid ;
2018-07-31 11:48:08 +02:00
if ( mod_file - > symbol_table . exists ( function_name ) )
if ( mod_file - > symbol_table . getType ( function_name ) ! = SymbolType : : externalFunction )
2019-02-28 19:22:34 +01:00
if ( ! in_model_block & & ! parsing_epilogue & & ! parsing_pac_model )
2010-03-15 10:47:44 +01:00
{
2018-03-20 09:56:22 +01:00
if ( stack_external_function_args . top ( ) . size ( ) > 0 )
2022-06-22 12:47:11 +02:00
error ( " Symbol " + function_name + " cannot take arguments. " ) ;
2010-03-15 10:47:44 +01:00
else
2018-03-20 09:56:22 +01:00
return add_expression_variable ( function_name ) ;
2010-02-22 17:33:38 +01:00
}
else
2018-03-20 09:56:22 +01:00
{ // e.g. model_var(lag) => ADD MODEL VARIABLE WITH LEAD (NumConstNode)/LAG (UnaryOpNode)
2022-05-04 16:01:34 +02:00
if ( undeclared_model_vars . contains ( function_name ) )
2018-07-31 11:48:08 +02:00
undeclared_model_variable_error ( " Unknown symbol: " + function_name , function_name ) ;
2018-03-20 09:56:22 +01:00
2022-06-08 12:34:25 +02:00
optional < int > rv { is_there_one_integer_argument ( ) } ;
if ( ! rv )
2019-12-20 16:59:30 +01:00
model_error ( " Symbol " + function_name
+ " is being treated as if it were a function (i.e., takes an argument that is not an integer). " , " " ) ;
2018-03-20 09:56:22 +01:00
2022-06-08 12:34:25 +02:00
nid = add_model_variable ( mod_file - > symbol_table . getID ( function_name ) , * rv ) ;
2018-03-20 09:56:22 +01:00
stack_external_function_args . pop ( ) ;
return nid ;
2019-12-16 19:42:59 +01:00
}
2018-03-20 09:56:22 +01:00
else
{ // e.g. this function has already been referenced (either ad hoc or through the external_function() statement
// => check that the information matches previously declared info
2018-07-31 11:48:08 +02:00
int symb_id = mod_file - > symbol_table . getID ( function_name ) ;
2018-03-20 09:56:22 +01:00
if ( ! mod_file - > external_functions_table . exists ( symb_id ) )
2018-07-31 11:48:08 +02:00
error ( " Using a derivative of an external function ( " + function_name + " ) in the model block is currently not allowed. " ) ;
2018-03-20 09:56:22 +01:00
2018-09-03 17:16:28 +02:00
if ( in_model_block | | parsing_epilogue )
2018-10-02 18:10:12 +02:00
if ( mod_file - > external_functions_table . getNargs ( symb_id ) = = ExternalFunctionsTable : : IDNotSet )
2018-07-31 11:48:08 +02:00
error ( " Before using " + function_name
2018-03-20 09:56:22 +01:00
+ " () in the model block, you must first declare it via the external_function() statement " ) ;
2019-04-23 11:07:32 +02:00
else if ( static_cast < int > ( stack_external_function_args . top ( ) . size ( ) ) ! = mod_file - > external_functions_table . getNargs ( symb_id ) )
2018-07-31 11:48:08 +02:00
error ( " The number of arguments passed to " + function_name
2018-03-20 09:56:22 +01:00
+ " () does not match those of a previous call or declaration of this function. " ) ;
}
2008-02-03 11:28:36 +01:00
else
2010-02-22 17:33:38 +01:00
{ //First time encountering this external function i.e., not previously declared or encountered
2018-09-03 17:16:28 +02:00
if ( parsing_epilogue )
error ( " Variable " + function_name + " used in the epilogue block but was not declared. " ) ;
2010-03-03 11:40:13 +01:00
if ( in_model_block )
2016-10-07 15:02:42 +02:00
{
// Continue processing, noting that it was not declared
2018-03-20 09:56:22 +01:00
// Processing will end at the end of the model block if nostrict was not passed
2018-07-31 11:48:08 +02:00
undeclared_model_vars . insert ( function_name ) ;
undeclared_model_variable_error ( " Unknown symbol: " + function_name , function_name ) ;
2018-03-20 09:56:22 +01:00
2022-06-08 12:34:25 +02:00
optional < int > rv { is_there_one_integer_argument ( ) } ;
if ( rv )
2016-10-07 15:02:42 +02:00
{
// assume it's a lead/lagged variable
2022-03-29 16:44:04 +02:00
int symb_id = declare_exogenous ( function_name ) ;
2022-06-08 12:34:25 +02:00
return add_model_variable ( symb_id , * rv ) ;
2016-10-07 15:02:42 +02:00
}
else
2019-12-20 16:59:30 +01:00
error ( " To use an external function ( " + function_name
+ " ) within the model block, you must first declare it via the external_function() statement. " ) ;
2016-10-07 15:02:42 +02:00
}
2022-03-29 16:44:04 +02:00
int symb_id = declare_symbol ( function_name , SymbolType : : externalFunction , " " , { } ) ;
2016-10-07 15:48:18 +02:00
current_external_function_options . nargs = stack_external_function_args . top ( ) . size ( ) ;
2022-03-29 16:44:04 +02:00
mod_file - > external_functions_table . addExternalFunction ( symb_id ,
2016-10-07 15:48:18 +02:00
current_external_function_options , in_model_block ) ;
reset_current_external_function_options ( ) ;
2010-02-22 17:33:38 +01:00
}
2008-02-03 11:28:36 +01:00
2010-02-22 17:33:38 +01:00
//By this point, we're sure that this function exists in the External Functions Table and is not a mod var
2018-07-31 11:48:08 +02:00
int symb_id = mod_file - > symbol_table . getID ( function_name ) ;
2010-03-16 12:17:17 +01:00
nid = data_tree - > AddExternalFunction ( symb_id , stack_external_function_args . top ( ) ) ;
2010-02-22 17:33:38 +01:00
stack_external_function_args . pop ( ) ;
2010-03-03 11:40:13 +01:00
return nid ;
2008-02-03 11:28:36 +01:00
}
void
2022-10-04 15:59:18 +02:00
ParsingDriver : : add_native ( string s )
2010-06-18 12:39:29 +02:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < NativeStatement > ( move ( s ) ) ) ;
2010-06-18 12:39:29 +02:00
}
void
2022-10-04 16:34:43 +02:00
ParsingDriver : : add_native_remove_charset ( string_view str , string_view token )
2008-02-03 11:28:36 +01:00
{
2010-06-17 12:47:38 +02:00
size_t found = str . find ( token ) ;
2022-10-04 16:34:43 +02:00
assert ( found ! = string_view : : npos ) ;
add_native ( string { str . substr ( 0 , found ) } ) ;
2008-02-03 11:28:36 +01:00
}
2010-04-23 18:39:07 +02:00
2015-06-16 12:48:32 +02:00
void
2022-10-04 15:59:18 +02:00
ParsingDriver : : add_verbatim ( string s )
2015-06-16 12:48:32 +02:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < VerbatimStatement > ( move ( s ) ) ) ;
2015-06-16 12:48:32 +02:00
}
void
2022-10-04 16:34:43 +02:00
ParsingDriver : : add_verbatim_remove_charset ( string_view str , string_view token )
2015-06-16 12:48:32 +02:00
{
size_t found = str . find ( token ) ;
2022-10-04 16:34:43 +02:00
assert ( found ! = string_view : : npos ) ;
add_verbatim ( string { str . substr ( 0 , found ) } ) ;
2015-06-16 12:48:32 +02:00
}
2010-04-23 18:39:07 +02:00
void
ParsingDriver : : begin_steady_state_model ( )
{
set_current_data_tree ( & mod_file - > steady_state_model ) ;
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_steady_state_model_equal ( const string & varname , expr_t expr )
2010-04-23 18:39:07 +02:00
{
int id ;
try
{
2018-07-31 11:48:08 +02:00
id = mod_file - > symbol_table . getID ( varname ) ;
2010-04-23 18:39:07 +02:00
}
catch ( SymbolTable : : UnknownSymbolNameException & e )
{
// Unknown symbol, declare it as a ModFileLocalVariable
2018-07-31 11:48:08 +02:00
id = mod_file - > symbol_table . addSymbol ( varname , SymbolType : : modFileLocalVariable ) ;
2010-04-23 18:39:07 +02:00
}
2022-06-02 10:50:21 +02:00
if ( SymbolType type = mod_file - > symbol_table . getType ( id ) ;
type ! = SymbolType : : endogenous & & type ! = SymbolType : : modFileLocalVariable & & type ! = SymbolType : : parameter )
2018-07-31 11:48:08 +02:00
error ( varname + " has incorrect type " ) ;
2010-04-23 18:39:07 +02:00
2010-05-31 17:43:17 +02:00
mod_file - > steady_state_model . addDefinition ( id , expr ) ;
2010-04-23 18:39:07 +02:00
}
2011-01-26 19:55:01 +01:00
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : add_steady_state_model_equal_multiple ( const vector < string > & symbol_list , expr_t expr )
2011-01-26 19:55:01 +01:00
{
vector < int > ids ;
2022-03-28 18:11:53 +02:00
for ( const auto & symb : symbol_list )
2011-01-26 19:55:01 +01:00
{
int id ;
try
{
2018-06-04 12:26:16 +02:00
id = mod_file - > symbol_table . getID ( symb ) ;
2011-01-26 19:55:01 +01:00
}
catch ( SymbolTable : : UnknownSymbolNameException & e )
{
// Unknown symbol, declare it as a ModFileLocalVariable
2018-07-17 18:34:07 +02:00
id = mod_file - > symbol_table . addSymbol ( symb , SymbolType : : modFileLocalVariable ) ;
2011-01-26 19:55:01 +01:00
}
2022-06-02 10:50:21 +02:00
if ( SymbolType type = mod_file - > symbol_table . getType ( id ) ;
type ! = SymbolType : : endogenous & & type ! = SymbolType : : modFileLocalVariable & & type ! = SymbolType : : parameter )
2018-06-04 12:26:16 +02:00
error ( symb + " has incorrect type " ) ;
2011-01-26 19:55:01 +01:00
ids . push_back ( id ) ;
}
mod_file - > steady_state_model . addMultipleDefinitions ( ids , expr ) ;
}
2012-09-11 14:26:53 +02:00
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : add_graph_format ( string name )
2012-09-11 14:26:53 +02:00
{
2022-03-28 18:11:53 +02:00
graph_formats . emplace_back ( move ( name ) ) ;
2012-09-11 14:26:53 +02:00
}
void
ParsingDriver : : process_graph_format_option ( )
{
2022-09-18 09:30:13 +02:00
options_list . set ( " graph_format " , OptionsList : : SymbolListVal { move ( graph_formats ) } ) ;
2012-09-11 14:26:53 +02:00
graph_formats . clear ( ) ;
2019-12-06 10:40:44 +01:00
}
void
ParsingDriver : : initial_condition_decomp_process_graph_format_option ( )
{
2022-09-18 09:30:13 +02:00
options_list . set ( " initial_condition_decomp.graph_format " , OptionsList : : SymbolListVal { move ( graph_formats ) } ) ;
2019-12-06 10:40:44 +01:00
graph_formats . clear ( ) ;
2012-09-11 14:26:53 +02:00
}
2017-03-22 11:30:35 +01:00
void
ParsingDriver : : plot_shock_decomp_process_graph_format_option ( )
{
2022-09-18 09:30:13 +02:00
options_list . set ( " plot_shock_decomp.graph_format " , OptionsList : : SymbolListVal { move ( graph_formats ) } ) ;
2017-03-22 11:30:35 +01:00
graph_formats . clear ( ) ;
}
2012-11-16 12:34:49 +01:00
void
ParsingDriver : : model_diagnostics ( )
{
2018-09-05 15:17:21 +02:00
mod_file - > addStatement ( make_unique < ModelDiagnosticsStatement > ( ) ) ;
2012-11-16 12:34:49 +01:00
}
2013-05-31 14:47:28 +02:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_parallel_local_file ( string filename )
2013-05-31 14:47:28 +02:00
{
2018-07-31 11:48:08 +02:00
mod_file - > parallel_local_files . push_back ( move ( filename ) ) ;
2013-05-31 14:47:28 +02:00
}
2014-02-10 19:22:54 +01:00
void
2019-09-25 12:02:44 +02:00
ParsingDriver : : add_moment_calibration_item ( const string & endo1 , const string & endo2 , string lags , const pair < expr_t , expr_t > & range )
2014-02-10 19:22:54 +01:00
{
MomentCalibration : : Constraint c ;
2018-08-01 10:47:09 +02:00
check_symbol_is_endogenous ( endo1 ) ;
2018-07-31 11:48:08 +02:00
c . endo1 = mod_file - > symbol_table . getID ( endo1 ) ;
2014-02-10 19:22:54 +01:00
2018-08-01 10:47:09 +02:00
check_symbol_is_endogenous ( endo2 ) ;
2018-07-31 11:48:08 +02:00
c . endo2 = mod_file - > symbol_table . getID ( endo2 ) ;
2014-02-10 19:22:54 +01:00
2018-07-31 11:48:08 +02:00
c . lags = move ( lags ) ;
2017-06-01 19:58:32 +02:00
2018-07-31 11:48:08 +02:00
c . lower_bound = range . first ;
c . upper_bound = range . second ;
2017-06-01 19:58:32 +02:00
2022-06-13 14:15:47 +02:00
moment_calibration_constraints . push_back ( move ( c ) ) ;
2014-02-10 19:22:54 +01:00
}
2017-06-01 19:58:32 +02:00
void
ParsingDriver : : end_moment_calibration ( )
2014-02-10 19:22:54 +01:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < MomentCalibration > ( move ( moment_calibration_constraints ) ,
2018-09-05 15:17:21 +02:00
mod_file - > symbol_table ) ) ;
2014-02-10 19:22:54 +01:00
moment_calibration_constraints . clear ( ) ;
}
void
2019-09-25 12:02:44 +02:00
ParsingDriver : : add_irf_calibration_item ( const string & endo , string periods , const string & exo , const pair < expr_t , expr_t > & range )
2014-02-10 19:22:54 +01:00
{
IrfCalibration : : Constraint c ;
2018-08-01 10:47:09 +02:00
check_symbol_is_endogenous ( endo ) ;
2018-07-31 11:48:08 +02:00
c . endo = mod_file - > symbol_table . getID ( endo ) ;
2014-02-10 19:22:54 +01:00
2018-07-31 11:48:08 +02:00
c . periods = move ( periods ) ;
2014-02-10 19:22:54 +01:00
2018-07-31 11:48:08 +02:00
check_symbol_existence ( exo ) ;
c . exo = mod_file - > symbol_table . getID ( exo ) ;
if ( mod_file - > symbol_table . getType ( exo ) ! = SymbolType : : exogenous )
error ( " Variable " + endo + " is not an exogenous. " ) ;
2017-06-01 19:58:32 +02:00
2018-07-31 11:48:08 +02:00
c . lower_bound = range . first ;
c . upper_bound = range . second ;
2017-06-01 19:58:32 +02:00
2022-06-13 14:15:47 +02:00
irf_calibration_constraints . push_back ( move ( c ) ) ;
2014-02-10 19:22:54 +01:00
}
2017-06-01 19:58:32 +02:00
void
ParsingDriver : : end_irf_calibration ( )
2014-02-10 19:22:54 +01:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < IrfCalibration > ( move ( irf_calibration_constraints ) ,
2018-09-05 15:17:21 +02:00
mod_file - > symbol_table ,
2022-10-04 15:59:18 +02:00
move ( options_list ) ) ) ;
2014-02-10 19:22:54 +01:00
irf_calibration_constraints . clear ( ) ;
2022-10-04 15:58:10 +02:00
options_list . clear ( ) ;
2014-02-10 19:22:54 +01:00
}
2014-04-03 15:05:20 +02:00
void
ParsingDriver : : smoother2histval ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < Smoother2histvalStatement > ( move ( options_list ) ) ) ;
2014-04-03 15:05:20 +02:00
options_list . clear ( ) ;
}
void
2020-05-14 16:36:35 +02:00
ParsingDriver : : histval_file ( )
2014-04-03 15:05:20 +02:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < HistvalFileStatement > ( move ( options_list ) ) ) ;
2020-05-14 16:36:35 +02:00
options_list . clear ( ) ;
2014-04-03 15:05:20 +02:00
}
2014-04-09 17:57:17 +02:00
void
ParsingDriver : : perfect_foresight_setup ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < PerfectForesightSetupStatement > ( move ( options_list ) ) ) ;
2014-04-09 17:57:17 +02:00
options_list . clear ( ) ;
}
void
ParsingDriver : : perfect_foresight_solver ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < PerfectForesightSolverStatement > ( move ( options_list ) ) ) ;
2014-04-09 17:57:17 +02:00
options_list . clear ( ) ;
}
2015-05-31 12:18:06 +02:00
2021-07-09 17:14:22 +02:00
void
ParsingDriver : : perfect_foresight_with_expectation_errors_setup ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < PerfectForesightWithExpectationErrorsSetupStatement > ( move ( options_list ) ) ) ;
2021-07-09 17:14:22 +02:00
options_list . clear ( ) ;
}
void
ParsingDriver : : perfect_foresight_with_expectation_errors_solver ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < PerfectForesightWithExpectationErrorsSolverStatement > ( move ( options_list ) ) ) ;
2021-07-09 17:14:22 +02:00
options_list . clear ( ) ;
}
2017-10-05 15:09:04 +02:00
void
2020-07-08 18:42:14 +02:00
ParsingDriver : : method_of_moments ( )
2017-10-05 15:09:04 +02:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < MethodOfMomentsStatement > ( move ( options_list ) ) ) ;
2017-10-05 15:09:04 +02:00
options_list . clear ( ) ;
}
2015-10-13 17:16:10 +02:00
void
2015-10-14 11:02:35 +02:00
ParsingDriver : : prior_posterior_function ( bool prior_func )
2015-10-13 17:16:10 +02:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < PriorPosteriorFunctionStatement > ( static_cast < bool > ( prior_func ) ,
move ( options_list ) ) ) ;
2015-10-13 17:16:10 +02:00
options_list . clear ( ) ;
}
2015-05-31 12:18:06 +02:00
void
ParsingDriver : : add_ramsey_constraints_statement ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < RamseyConstraintsStatement > ( mod_file - > symbol_table ,
move ( ramsey_constraints ) ) ) ;
2015-05-31 12:18:06 +02:00
ramsey_constraints . clear ( ) ;
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : ramsey_constraint_add_less ( const string & name , const expr_t rhs )
2015-05-31 12:18:06 +02:00
{
2018-07-18 16:18:26 +02:00
add_ramsey_constraint ( name , BinaryOpcode : : less , rhs ) ;
2015-05-31 12:18:06 +02:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : ramsey_constraint_add_greater ( const string & name , const expr_t rhs )
2015-05-31 12:18:06 +02:00
{
2018-07-18 16:18:26 +02:00
add_ramsey_constraint ( name , BinaryOpcode : : greater , rhs ) ;
2015-05-31 12:18:06 +02:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : ramsey_constraint_add_less_equal ( const string & name , const expr_t rhs )
2015-05-31 12:18:06 +02:00
{
2018-07-18 16:18:26 +02:00
add_ramsey_constraint ( name , BinaryOpcode : : lessEqual , rhs ) ;
2015-05-31 12:18:06 +02:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : ramsey_constraint_add_greater_equal ( const string & name , const expr_t rhs )
2015-05-31 12:18:06 +02:00
{
2018-07-18 16:18:26 +02:00
add_ramsey_constraint ( name , BinaryOpcode : : greaterEqual , rhs ) ;
2015-05-31 12:18:06 +02:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_ramsey_constraint ( const string & name , BinaryOpcode op_code , const expr_t rhs )
2015-05-31 12:18:06 +02:00
{
2018-08-01 10:47:09 +02:00
check_symbol_is_endogenous ( name ) ;
2018-07-31 11:48:08 +02:00
int symb_id = mod_file - > symbol_table . getID ( name ) ;
2015-05-31 12:18:06 +02:00
RamseyConstraintsStatement : : Constraint C ;
C . endo = symb_id ;
C . code = op_code ;
C . expression = rhs ;
ramsey_constraints . push_back ( C ) ;
}
2016-04-10 18:55:17 +02:00
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_shock_group_element ( string name )
2016-04-10 18:55:17 +02:00
{
2018-07-31 11:48:08 +02:00
check_symbol_existence ( name ) ;
int symb_id = mod_file - > symbol_table . getID ( name ) ;
2016-04-10 18:55:17 +02:00
2022-06-02 10:50:21 +02:00
if ( mod_file - > symbol_table . getType ( symb_id ) ! = SymbolType : : exogenous )
2018-07-31 11:48:08 +02:00
error ( " shock_groups: " + name + " should be an exogenous variable " ) ;
2016-04-10 18:55:17 +02:00
2018-07-31 11:48:08 +02:00
shock_group . push_back ( move ( name ) ) ;
2016-04-10 18:55:17 +02:00
}
void
2018-07-31 11:48:08 +02:00
ParsingDriver : : add_shock_group ( string name )
2016-04-10 18:55:17 +02:00
{
ShockGroupsStatement : : Group G ;
2018-07-31 11:48:08 +02:00
G . name = move ( name ) ;
2016-04-10 18:55:17 +02:00
G . list = shock_group ;
2022-06-13 14:15:47 +02:00
shock_groups . push_back ( move ( G ) ) ;
2016-04-10 18:55:17 +02:00
shock_group . clear ( ) ;
}
void
2022-10-04 15:59:18 +02:00
ParsingDriver : : end_shock_groups ( string name )
2016-04-10 18:55:17 +02:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < ShockGroupsStatement > ( move ( shock_groups ) , move ( name ) ) ) ;
2016-04-10 18:55:17 +02:00
shock_groups . clear ( ) ;
}
2018-08-01 19:41:44 +02:00
2019-12-02 11:18:21 +01:00
void
ParsingDriver : : add_init2shocks ( const string & endo_name , const string & exo_name )
{
check_symbol_existence ( endo_name ) ;
check_symbol_existence ( exo_name ) ;
int symb_id_endo = mod_file - > symbol_table . getID ( endo_name ) ;
if ( mod_file - > symbol_table . getType ( symb_id_endo ) ! = SymbolType : : endogenous )
error ( " init2shocks: " + endo_name + " should be an endogenous variable " ) ;
int symb_id_exo = mod_file - > symbol_table . getID ( exo_name ) ;
if ( mod_file - > symbol_table . getType ( symb_id_exo ) ! = SymbolType : : exogenous )
error ( " init2shocks: " + exo_name + " should be an exogenous variable " ) ;
2019-12-16 19:42:59 +01:00
init2shocks . emplace_back ( symb_id_endo , symb_id_exo ) ;
2019-12-02 11:18:21 +01:00
}
void
2022-10-04 15:59:18 +02:00
ParsingDriver : : end_init2shocks ( string name )
2019-12-02 11:18:21 +01:00
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < Init2shocksStatement > ( move ( init2shocks ) , move ( name ) ,
mod_file - > symbol_table ) ) ;
2019-12-02 11:18:21 +01:00
init2shocks . clear ( ) ;
}
2018-08-01 19:41:44 +02:00
void
ParsingDriver : : var_expectation_model ( )
{
2022-09-18 09:30:13 +02:00
try
2018-11-28 17:32:55 +01:00
{
2022-09-18 09:30:13 +02:00
string v { options_list . get < OptionsList : : StringVal > ( " variable " ) } ;
2018-11-28 17:32:55 +01:00
if ( var_expectation_model_expression )
error ( " You can't pass both the 'variable' or the 'expression' options to the var_expectation_model statement. " ) ;
2022-09-18 09:30:13 +02:00
var_expectation_model_expression = data_tree - > AddVariable ( mod_file - > symbol_table . getID ( v ) ) ;
}
catch ( OptionsList : : UnknownOptionException & )
{
if ( ! var_expectation_model_expression )
error ( " You must pass either the 'variable' or the 'expression' option to the var_expectation_model statement. " ) ;
2018-11-28 17:32:55 +01:00
}
2018-08-01 19:41:44 +02:00
if ( var_expectation_model_discount )
{
VariableNode * var ;
if ( ! dynamic_cast < NumConstNode * > ( var_expectation_model_discount )
& & ! ( ( var = dynamic_cast < VariableNode * > ( var_expectation_model_discount ) )
& & var - > get_type ( ) = = SymbolType : : parameter ) )
error ( " The discount factor must be a constant expression or a parameter " ) ;
}
else
var_expectation_model_discount = data_tree - > One ;
2022-09-18 09:30:13 +02:00
int time_shift { stoi ( options_list . get_if < OptionsList : : NumVal > ( " time_shift " ) . value_or ( OptionsList : : NumVal { " 0 " } ) ) } ;
2021-07-06 16:40:20 +02:00
if ( time_shift > 0 )
error ( " The 'time_shift' option must be a non-positive integer " ) ;
2021-07-01 17:56:07 +02:00
2022-09-18 09:30:13 +02:00
try
{
mod_file - > var_expectation_model_table . addVarExpectationModel ( options_list . get < OptionsList : : StringVal > ( " model_name " ) ,
var_expectation_model_expression ,
options_list . get < OptionsList : : StringVal > ( " auxiliary_model_name " ) ,
options_list . get < OptionsList : : NumVal > ( " horizon " ) ,
var_expectation_model_discount ,
time_shift ) ;
}
catch ( OptionsList : : UnknownOptionException & e )
{
error ( " You must pass the ' " + e . name + " ' option to the 'var_expectation_model' statement. " ) ;
}
2018-08-01 19:41:44 +02:00
options_list . clear ( ) ;
var_expectation_model_discount = nullptr ;
2018-11-28 17:32:55 +01:00
var_expectation_model_expression = nullptr ;
2018-08-01 19:41:44 +02:00
}
2020-07-28 18:29:45 +02:00
void
ParsingDriver : : begin_matched_moments ( )
{
set_current_data_tree ( & mod_file - > dynamic_model ) ;
}
void
ParsingDriver : : end_matched_moments ( const vector < expr_t > & moments )
{
vector < tuple < vector < int > , vector < int > , vector < int > > > parsed_moments ;
for ( auto m : moments )
try
{
vector < int > symb_ids , lags , powers ;
m - > matchMatchedMoment ( symb_ids , lags , powers ) ;
2022-06-02 10:50:21 +02:00
parsed_moments . emplace_back ( move ( symb_ids ) , move ( lags ) , move ( powers ) ) ;
2020-07-28 18:29:45 +02:00
}
catch ( ExprNode : : MatchFailureException & e )
{
error ( " Matched moment expression has incorrect format: " + e . message ) ;
}
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < MatchedMomentsStatement > ( mod_file - > symbol_table ,
move ( parsed_moments ) ) ) ;
2020-07-28 18:29:45 +02:00
reset_data_tree ( ) ;
}
2021-07-15 16:24:21 +02:00
void
ParsingDriver : : begin_occbin_constraints ( )
{
2021-07-21 16:16:39 +02:00
/* We use a separate data tree, because we will add inequality constraints,
and those would trigger the non - linearity warning in a stochastic context
if added to the main DynamicModel tree . It also simplifies the
enforcement of various constraints at parsing time . */
occbin_constraints_tree = make_unique < DataTree > ( mod_file - > symbol_table ,
mod_file - > num_constants ,
mod_file - > external_functions_table ,
false ) ;
set_current_data_tree ( occbin_constraints_tree . get ( ) ) ;
2021-07-15 16:24:21 +02:00
}
void
2022-10-04 15:59:18 +02:00
ParsingDriver : : end_occbin_constraints ( vector < tuple < string , BinaryOpNode * , BinaryOpNode * , expr_t , expr_t > > constraints )
2021-07-15 16:24:21 +02:00
{
// Perform a few checks
for ( const auto & [ name , bind , relax , error_bind , error_relax ] : constraints )
{
2021-07-20 18:18:24 +02:00
string param_name = buildOccbinBindParamName ( name ) ;
if ( ! mod_file - > symbol_table . exists ( param_name ) )
error ( " No equation has been declared for regime ' " + name + " ' " ) ;
2021-07-15 16:24:21 +02:00
if ( ! bind )
error ( " The 'bind' expression is missing in constraint ' " + name + " ' " ) ;
}
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < OccbinConstraintsStatement > ( * occbin_constraints_tree ,
move ( constraints ) ) ) ;
2021-07-15 16:24:21 +02:00
reset_data_tree ( ) ;
}
2021-07-20 18:18:24 +02:00
2021-10-26 18:06:26 +02:00
void
ParsingDriver : : begin_pac_target_info ( string name )
{
pac_target_info_name = move ( name ) ;
set_current_data_tree ( & mod_file - > dynamic_model ) ;
}
void
ParsingDriver : : end_pac_target_info ( )
{
reset_data_tree ( ) ;
}
void
ParsingDriver : : set_pac_target_info_target ( expr_t target )
{
mod_file - > pac_model_table . setTargetExpr ( pac_target_info_name , target ) ;
}
void
ParsingDriver : : set_pac_target_info_auxname_target_nonstationary ( string auxname )
{
mod_file - > pac_model_table . setTargetAuxnameNonstationary ( pac_target_info_name , move ( auxname ) ) ;
}
void
ParsingDriver : : add_pac_target_info_component ( expr_t component_expr )
{
get < 0 > ( pac_target_info_component ) = component_expr ;
2022-06-13 14:15:47 +02:00
mod_file - > pac_model_table . addTargetComponent ( pac_target_info_name , exchange ( pac_target_info_component , { } ) ) ;
2021-10-26 18:06:26 +02:00
}
void
ParsingDriver : : set_pac_target_info_component_growth ( expr_t growth )
{
get < 1 > ( pac_target_info_component ) = growth ;
}
void
ParsingDriver : : set_pac_target_info_component_auxname ( string auxname )
{
get < 2 > ( pac_target_info_component ) = move ( auxname ) ;
}
void
ParsingDriver : : set_pac_target_info_component_kind ( PacTargetKind kind )
{
get < 3 > ( pac_target_info_component ) = kind ;
}
2021-07-20 18:18:24 +02:00
bool
ParsingDriver : : isSymbolIdentifier ( const string & str )
{
if ( str . empty ( ) )
return false ;
auto myisalpha = [ ] ( char ch )
{
// We cannot use std::isalpha(), because it is locale-dependent
return ( ch > = ' a ' & & ch < = ' z ' ) | | ( ch > = ' A ' & & ch < = ' Z ' ) ;
} ;
if ( ! ( myisalpha ( str [ 0 ] ) | | str [ 0 ] = = ' _ ' ) )
return false ;
for ( size_t i = 1 ; i < str . size ( ) ; i + + )
if ( ! ( myisalpha ( str [ i ] ) | | isdigit ( static_cast < unsigned char > ( str [ i ] ) ) | | str [ i ] = = ' _ ' ) )
return false ;
return true ;
}
2021-12-14 17:24:14 +01:00
void
ParsingDriver : : model_remove ( const vector < pair < string , string > > & listed_eqs_by_tags )
{
mod_file - > dynamic_model . removeEquations ( listed_eqs_by_tags , true , true ) ;
}
void
ParsingDriver : : begin_model_replace ( const vector < pair < string , string > > & listed_eqs_by_tags )
{
mod_file - > dynamic_model . removeEquations ( listed_eqs_by_tags , true , false ) ;
set_current_data_tree ( & mod_file - > dynamic_model ) ;
}
2021-12-14 18:10:10 +01:00
void
2022-03-28 18:11:53 +02:00
ParsingDriver : : var_remove ( const vector < string > & symbol_list )
2021-12-14 18:10:10 +01:00
{
2022-03-28 18:11:53 +02:00
for ( const auto & name : symbol_list )
2021-12-14 18:10:10 +01:00
{
check_symbol_existence ( name ) ;
int symb_id = mod_file - > symbol_table . getID ( name ) ;
mod_file - > symbol_table . changeType ( symb_id , SymbolType : : excludedVariable ) ;
}
}
2022-03-01 12:29:21 +01:00
void
ParsingDriver : : resid ( )
{
2022-10-04 15:59:18 +02:00
mod_file - > addStatement ( make_unique < ResidStatement > ( move ( options_list ) ) ) ;
2022-03-01 12:29:21 +01:00
options_list . clear ( ) ;
}