Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • normann/preprocessor
  • Dynare/preprocessor
  • FerhatMihoubi/preprocessor
  • MichelJuillard/preprocessor
  • sebastien/preprocessor
  • lnsongxf/preprocessor
  • albop/preprocessor
  • DoraK/preprocessor
  • amg/preprocessor
  • wmutschl/preprocessor
  • JohannesPfeifer/preprocessor
11 results
Select Git revision
Show changes
Commits on Source (56)
Showing with 397 additions and 319 deletions
...@@ -11,9 +11,12 @@ BreakInheritanceList: AfterColon ...@@ -11,9 +11,12 @@ BreakInheritanceList: AfterColon
Cpp11BracedListStyle: true Cpp11BracedListStyle: true
DeriveLineEnding: false DeriveLineEnding: false
IndentPPDirectives: AfterHash IndentPPDirectives: AfterHash
InsertNewlineAtEOF: true
PackConstructorInitializers: NextLine PackConstructorInitializers: NextLine
PPIndentWidth: 1 PPIndentWidth: 1
PointerAlignment: Left PointerAlignment: Left
# RemoveParentheses: ReturnStatement
# RemoveSemicolon: true
SpaceAfterTemplateKeyword: false SpaceAfterTemplateKeyword: false
SpaceBeforeParens: ControlStatements SpaceBeforeParens: ControlStatements
SpaceBeforeCpp11BracedList: true SpaceBeforeCpp11BracedList: true
variables: variables:
TERM: linux TERM: linux
MINGW64_BOOST_VERSION: 1.85.0-2 MINGW64_BOOST_VERSION: 1.88.0-2
WGET_OPTIONS: '--no-verbose --no-use-server-timestamps --retry-connrefused --retry-on-host-error' WGET_OPTIONS: '--no-verbose --no-use-server-timestamps --retry-connrefused --retry-on-host-error'
# To ensure that "false && true" fails, see https://gitlab.com/gitlab-org/gitlab-runner/-/issues/25394#note_412609647 # To ensure that "false && true" fails, see https://gitlab.com/gitlab-org/gitlab-runner/-/issues/25394#note_412609647
FF_ENABLE_BASH_EXIT_CODE_CHECK: 'true' FF_ENABLE_BASH_EXIT_CODE_CHECK: 'true'
...@@ -47,9 +47,6 @@ build_macos_x86_64: ...@@ -47,9 +47,6 @@ build_macos_x86_64:
tags: tags:
- macOS - macOS
script: script:
# Workaround for bug in Xcode 15.3 which does not include m4
# See https://github.com/Homebrew/homebrew-core/issues/165388 and https://trac.macports.org/ticket/69639
- export PATH="/usr/local/opt/m4/bin/:$PATH"
- arch -x86_64 meson setup -D buildtype=release --native-file scripts/homebrew-native-x86_64.ini build - arch -x86_64 meson setup -D buildtype=release --native-file scripts/homebrew-native-x86_64.ini build
- arch -x86_64 meson compile -C build -v - arch -x86_64 meson compile -C build -v
artifacts: artifacts:
...@@ -62,9 +59,6 @@ build_macos_arm64: ...@@ -62,9 +59,6 @@ build_macos_arm64:
- macOS - macOS
script: script:
- export PATH="/opt/homebrew/bin:$PATH" - export PATH="/opt/homebrew/bin:$PATH"
# Workaround for bug in Xcode 15.3 which does not include m4
# See https://github.com/Homebrew/homebrew-core/issues/165388 and https://trac.macports.org/ticket/69639
- export PATH="/opt/homebrew/opt/m4/bin/:$PATH"
- arch -arm64 meson setup -D buildtype=release --native-file scripts/homebrew-native-arm64.ini build - arch -arm64 meson setup -D buildtype=release --native-file scripts/homebrew-native-arm64.ini build
- arch -arm64 meson compile -C build -v - arch -arm64 meson compile -C build -v
artifacts: artifacts:
...@@ -77,3 +71,16 @@ test_clang_format: ...@@ -77,3 +71,16 @@ test_clang_format:
- meson setup build-clang-format - meson setup build-clang-format
- ninja -C build-clang-format clang-format-check - ninja -C build-clang-format clang-format-check
needs: [] needs: []
test_clang_tidy:
stage: test
script:
# Hack needed for meson < 1.6.0 which only looks for unversioned clang-tidy
- mkdir -p ~/.local/bin && ln -s /usr/bin/clang-tidy-19 ~/.local/bin/clang-tidy
- export PATH="$HOME/.local/bin:$PATH"
- meson setup build-clang-tidy
# Generate Flex and Bison files
- meson compile -C build-clang-tidy
- ninja -C build-clang-tidy clang-tidy
needs: []
when: manual
...@@ -283,7 +283,9 @@ PerfectForesightWithExpectationErrorsSolverStatement::writeOutput( ...@@ -283,7 +283,9 @@ PerfectForesightWithExpectationErrorsSolverStatement::writeOutput(
[[maybe_unused]] bool minimal_workspace) const [[maybe_unused]] bool minimal_workspace) const
{ {
options_list.writeOutput(output); options_list.writeOutput(output);
output << "oo_ = perfect_foresight_with_expectation_errors_solver(M_, options_, oo_);" << endl; output << "[oo_, Simulated_time_series] = perfect_foresight_with_expectation_errors_solver(M_, "
"options_, oo_);"
<< endl;
} }
void void
...@@ -3713,8 +3715,7 @@ SvarGlobalIdentificationCheckStatement::writeJsonOutput(ostream& output) const ...@@ -3713,8 +3715,7 @@ SvarGlobalIdentificationCheckStatement::writeJsonOutput(ostream& output) const
output << R"({"statementName": "svar_global_identification"})"; output << R"({"statementName": "svar_global_identification"})";
} }
SetTimeStatement::SetTimeStatement(OptionsList options_list_arg) : SetTimeStatement::SetTimeStatement(string period_arg) : period {move(period_arg)}
options_list {move(options_list_arg)}
{ {
} }
...@@ -3722,19 +3723,13 @@ void ...@@ -3722,19 +3723,13 @@ void
SetTimeStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, SetTimeStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename,
[[maybe_unused]] bool minimal_workspace) const [[maybe_unused]] bool minimal_workspace) const
{ {
options_list.writeOutput(output); output << "options_.initial_period = " << period << endl;
} }
void void
SetTimeStatement::writeJsonOutput(ostream& output) const SetTimeStatement::writeJsonOutput(ostream& output) const
{ {
output << R"({"statementName": "set_time")"; output << R"({"statementName": "set_time", "period": ")" << period << R"("})";
if (!options_list.empty())
{
output << ", ";
options_list.writeJsonOutput(output);
}
output << "}";
} }
EstimationDataStatement::EstimationDataStatement(OptionsList options_list_arg) : EstimationDataStatement::EstimationDataStatement(OptionsList options_list_arg) :
...@@ -5347,8 +5342,8 @@ void ...@@ -5347,8 +5342,8 @@ void
ResidStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename, ResidStatement::writeOutput(ostream& output, [[maybe_unused]] const string& basename,
[[maybe_unused]] bool minimal_workspace) const [[maybe_unused]] bool minimal_workspace) const
{ {
options_list.writeOutput(output, "options_resid_"); options_list.writeOutput(output);
output << "display_static_residuals(M_, options_, oo_, options_resid_);" << endl; output << "display_static_residuals(M_, options_, oo_);" << endl;
} }
void void
......
...@@ -524,7 +524,7 @@ public: ...@@ -524,7 +524,7 @@ public:
blockName() const override blockName() const override
{ {
return "estimated_params"; return "estimated_params";
}; }
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override; void writeJsonOutput(ostream& output) const override;
...@@ -542,7 +542,7 @@ public: ...@@ -542,7 +542,7 @@ public:
blockName() const override blockName() const override
{ {
return "estimated_params_init"; return "estimated_params_init";
}; }
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override; void writeJsonOutput(ostream& output) const override;
...@@ -557,7 +557,7 @@ public: ...@@ -557,7 +557,7 @@ public:
blockName() const override blockName() const override
{ {
return "estimated_params_bounds"; return "estimated_params_bounds";
}; }
void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override; void checkPass(ModFileStructure& mod_file_struct, WarningConsolidation& warnings) override;
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override; void writeJsonOutput(ostream& output) const override;
...@@ -1007,10 +1007,10 @@ public: ...@@ -1007,10 +1007,10 @@ public:
class SetTimeStatement : public Statement class SetTimeStatement : public Statement
{ {
private: private:
const OptionsList options_list; const string period;
public: public:
explicit SetTimeStatement(OptionsList options_list_arg); explicit SetTimeStatement(string period_arg);
void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override; void writeOutput(ostream& output, const string& basename, bool minimal_workspace) const override;
void writeJsonOutput(ostream& output) const override; void writeJsonOutput(ostream& output) const override;
}; };
......
...@@ -47,7 +47,7 @@ private: ...@@ -47,7 +47,7 @@ private:
get_paths() const get_paths() const
{ {
return paths; return paths;
}; }
private: private:
map<string, vector<string>> paths; map<string, vector<string>> paths;
......
/* /*
* Copyright © 2003-2024 Dynare Team * Copyright © 2003-2025 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <iterator> #include <iterator>
#include <ranges>
#include "DataTree.hh" #include "DataTree.hh"
...@@ -69,13 +70,14 @@ DataTree::DataTree(const DataTree& d) : ...@@ -69,13 +70,14 @@ DataTree::DataTree(const DataTree& d) :
// Constants must be initialized first because they are used in some Add* methods // Constants must be initialized first because they are used in some Add* methods
initConstants(); initConstants();
// See commment in DataTree::operator=() for the rationale
for (int symb_id : d.local_variables_vector)
local_variables_table[symb_id] = d.local_variables_table.at(symb_id)->clone(*this);
for (const auto& it : d.node_list) for (const auto& it : d.node_list)
it->clone(*this); it->clone(*this);
assert(node_list.size() == d.node_list.size()); assert(node_list.size() == d.node_list.size());
for (const auto& [symb_id, value] : d.local_variables_table)
local_variables_table[symb_id] = value->clone(*this);
} }
DataTree& DataTree&
...@@ -804,9 +806,9 @@ DataTree::AddSum(expr_t arg) ...@@ -804,9 +806,9 @@ DataTree::AddSum(expr_t arg)
bool bool
DataTree::isSymbolUsed(int symb_id) const DataTree::isSymbolUsed(int symb_id) const
{ {
for (const auto& [symb_lag, expr] : variable_node_map) if (ranges::any_of(views::keys(variable_node_map),
if (symb_lag.first == symb_id) [=](const auto& symb_lag) { return symb_lag.first == symb_id; }))
return true; return true;
if (local_variables_table.contains(symb_id)) if (local_variables_table.contains(symb_id))
return true; return true;
...@@ -852,18 +854,18 @@ DataTree::addAllParamDerivId([[maybe_unused]] set<int>& deriv_id_set) ...@@ -852,18 +854,18 @@ DataTree::addAllParamDerivId([[maybe_unused]] set<int>& deriv_id_set)
bool bool
DataTree::isUnaryOpUsed(UnaryOpcode opcode) const DataTree::isUnaryOpUsed(UnaryOpcode opcode) const
{ {
return ranges::any_of(unary_op_node_map, return ranges::any_of(views::keys(unary_op_node_map),
[=](const auto& it) { return get<1>(it.first) == opcode; }); [=](const auto& key) { return get<1>(key) == opcode; });
} }
bool bool
DataTree::isUnaryOpUsedOnType(SymbolType type, UnaryOpcode opcode) const DataTree::isUnaryOpUsedOnType(SymbolType type, UnaryOpcode opcode) const
{ {
set<int> var; set<int> var;
for (const auto& it : unary_op_node_map) for (const auto& [key, value] : unary_op_node_map)
if (get<1>(it.first) == opcode) if (get<1>(key) == opcode)
{ {
it.second->collectVariables(type, var); value->collectVariables(type, var);
if (!var.empty()) if (!var.empty())
return true; return true;
} }
...@@ -873,18 +875,18 @@ DataTree::isUnaryOpUsedOnType(SymbolType type, UnaryOpcode opcode) const ...@@ -873,18 +875,18 @@ DataTree::isUnaryOpUsedOnType(SymbolType type, UnaryOpcode opcode) const
bool bool
DataTree::isBinaryOpUsed(BinaryOpcode opcode) const DataTree::isBinaryOpUsed(BinaryOpcode opcode) const
{ {
return ranges::any_of(binary_op_node_map, return ranges::any_of(views::keys(binary_op_node_map),
[=](const auto& it) { return get<2>(it.first) == opcode; }); [=](const auto& key) { return get<2>(key) == opcode; });
} }
bool bool
DataTree::isBinaryOpUsedOnType(SymbolType type, BinaryOpcode opcode) const DataTree::isBinaryOpUsedOnType(SymbolType type, BinaryOpcode opcode) const
{ {
set<int> var; set<int> var;
for (const auto& it : binary_op_node_map) for (const auto& [key, value] : binary_op_node_map)
if (get<2>(it.first) == opcode) if (get<2>(key) == opcode)
{ {
it.second->collectVariables(type, var); value->collectVariables(type, var);
if (!var.empty()) if (!var.empty())
return true; return true;
} }
...@@ -910,7 +912,7 @@ DataTree::writeCHelpersDefinition(ostream& output) const ...@@ -910,7 +912,7 @@ DataTree::writeCHelpersDefinition(ostream& output) const
<< "getPowerDeriv(double x, double p, int k)" << endl << "getPowerDeriv(double x, double p, int k)" << endl
<< "{" << endl << "{" << endl
<< " if (fabs(x) < " << power_deriv_near_zero << " if (fabs(x) < " << power_deriv_near_zero
<< " && p > 0 && k > p && fabs(p-nearbyint(p)) < " << power_deriv_near_zero << ')' << " && p >= 0 && k > p && fabs(p-nearbyint(p)) < " << power_deriv_near_zero << ')'
<< endl << endl
<< " return 0.0;" << endl << " return 0.0;" << endl
<< " else" << endl << " else" << endl
......
...@@ -367,7 +367,13 @@ public: ...@@ -367,7 +367,13 @@ public:
if (it == local_variables_table.end()) if (it == local_variables_table.end())
throw UnknownLocalVariableException {symb_id}; throw UnknownLocalVariableException {symb_id};
return it->second->decreaseLeadsLags(-lead_lag); /* In the following, the case without lead/lag is optimized. It makes a difference on models
with many nested model-local variables, see e.g.
https://forum.dynare.org/t/pre-processing-takes-very-long/26865 */
if (lead_lag == 0)
return it->second;
else
return it->second->decreaseLeadsLags(-lead_lag);
} }
static void static void
...@@ -396,7 +402,7 @@ DataTree::AddPossiblyNegativeConstant(double v) ...@@ -396,7 +402,7 @@ DataTree::AddPossiblyNegativeConstant(double v)
if (isnan(v)) if (isnan(v))
return NaN; return NaN;
if (isinf(v)) if (isinf(v))
return (v < 0 ? MinusInfinity : Infinity); return v < 0 ? MinusInfinity : Infinity;
bool neg = false; bool neg = false;
if (v < 0) if (v < 0)
......
/* /*
* Copyright © 2003-2024 Dynare Team * Copyright © 2003-2025 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -731,9 +731,9 @@ DynamicModel::removeEquationsHelper( ...@@ -731,9 +731,9 @@ DynamicModel::removeEquationsHelper(
} }
int n_excl = all_equations.size() - new_equations.size(); int n_excl = all_equations.size() - new_equations.size();
all_equations = new_equations; all_equations = move(new_equations);
all_equations_lineno = new_equations_lineno; all_equations_lineno = move(new_equations_lineno);
all_complementarity_conditions = new_complementarity_conditions; all_complementarity_conditions = move(new_complementarity_conditions);
all_equation_tags.erase(eqs_to_delete_by_number, old_eqn_num_2_new); all_equation_tags.erase(eqs_to_delete_by_number, old_eqn_num_2_new);
...@@ -1043,14 +1043,8 @@ DynamicModel::writeDriverOutput(ostream& output, bool compute_xrefs) const ...@@ -1043,14 +1043,8 @@ DynamicModel::writeDriverOutput(ostream& output, bool compute_xrefs) const
<< (static_only_equations.size() > 0) << ";" << endl; << (static_only_equations.size() > 0) << ";" << endl;
// Say if model contains an external function call // Say if model contains an external function call
bool has_external_function = false; output << "M_.has_external_function = " << boolalpha
for (auto equation : equations) << ranges::any_of(equations, &ExprNode::containsExternalFunction) << ';' << endl;
if (equation->containsExternalFunction())
{
has_external_function = true;
break;
}
output << "M_.has_external_function = " << boolalpha << has_external_function << ';' << endl;
// Compute list of state variables, ordered in block-order // Compute list of state variables, ordered in block-order
vector<int> state_var; vector<int> state_var;
...@@ -1768,7 +1762,7 @@ DynamicModel::getUndiffLHSForPac(const string& aux_model_name, ...@@ -1768,7 +1762,7 @@ DynamicModel::getUndiffLHSForPac(const string& aux_model_name,
for (auto eqn : nontrend_eqnums) for (auto eqn : nontrend_eqnums)
{ {
auto i = distance(eqnumber.begin(), ranges::find(eqnumber, eqn)); auto i = ranges::distance(eqnumber.begin(), ranges::find(eqnumber, eqn));
if (eqnumber[i] != eqn) if (eqnumber[i] != eqn)
{ {
...@@ -1784,7 +1778,6 @@ DynamicModel::getUndiffLHSForPac(const string& aux_model_name, ...@@ -1784,7 +1778,6 @@ DynamicModel::getUndiffLHSForPac(const string& aux_model_name,
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
bool printerr = false;
expr_t node = nullptr; expr_t node = nullptr;
expr_t aux_var = lhs_expr_t.at(i); expr_t aux_var = lhs_expr_t.at(i);
for (const auto& it : diff_subst_table) for (const auto& it : diff_subst_table)
...@@ -1801,11 +1794,8 @@ DynamicModel::getUndiffLHSForPac(const string& aux_model_name, ...@@ -1801,11 +1794,8 @@ DynamicModel::getUndiffLHSForPac(const string& aux_model_name,
} }
node = node->undiff(); node = node->undiff();
auto it1 = diff_subst_table.find(node);
if (it1 == diff_subst_table.end())
printerr = true;
if (printerr) if (auto it1 = diff_subst_table.find(node); it1 == diff_subst_table.end())
{ // we have undiffed something like diff(x), hence x is not in diff_subst_table { // we have undiffed something like diff(x), hence x is not in diff_subst_table
lhs_expr_t.at(i) = node; lhs_expr_t.at(i) = node;
lhs.at(i) = dynamic_cast<VariableNode*>(node)->symb_id; lhs.at(i) = dynamic_cast<VariableNode*>(node)->symb_id;
...@@ -1826,7 +1816,7 @@ DynamicModel::analyzePacEquationStructure(const string& name, map<string, string ...@@ -1826,7 +1816,7 @@ DynamicModel::analyzePacEquationStructure(const string& name, map<string, string
for (auto& equation : equations) for (auto& equation : equations)
if (equation->containsPacExpectation(name)) if (equation->containsPacExpectation(name))
{ {
if (!pac_eq_name[name].empty()) if (pac_eq_name.contains(name))
{ {
cerr << "It is not possible to use 'pac_expectation(" << name cerr << "It is not possible to use 'pac_expectation(" << name
<< ")' in several equations." << endl; << ")' in several equations." << endl;
...@@ -1925,6 +1915,13 @@ DynamicModel::analyzePacEquationStructure(const string& name, map<string, string ...@@ -1925,6 +1915,13 @@ DynamicModel::analyzePacEquationStructure(const string& name, map<string, string
move(additive_vars_params_and_constants), move(additive_vars_params_and_constants),
move(optim_additive_vars_params_and_constants)}; move(optim_additive_vars_params_and_constants)};
} }
if (!pac_eq_name.contains(name))
{
cerr << "ERROR: the model does not contain the 'pac_expectation(" << name << ")' operator."
<< endl;
exit(EXIT_FAILURE);
}
} }
int int
...@@ -3751,18 +3748,18 @@ void ...@@ -3751,18 +3748,18 @@ void
DynamicModel::detrendEquations() DynamicModel::detrendEquations()
{ {
// We go backwards in the list of trend_vars, to deal correctly with I(2) processes // We go backwards in the list of trend_vars, to deal correctly with I(2) processes
for (const auto& it : std::ranges::reverse_view(nonstationary_symbols_map)) for (const auto& [symb_id, deflator] : std::ranges::reverse_view(nonstationary_symbols_map))
{ {
for (auto& equation : equations) for (auto& equation : equations)
{ {
equation = dynamic_cast<BinaryOpNode*>( equation = dynamic_cast<BinaryOpNode*>(
equation->detrend(it.first, it.second.first, it.second.second)); equation->detrend(symb_id, deflator.first, deflator.second));
assert(equation); assert(equation);
} }
for (auto& equation : static_only_equations) for (auto& equation : static_only_equations)
{ {
equation = dynamic_cast<BinaryOpNode*>( equation = dynamic_cast<BinaryOpNode*>(
equation->detrend(it.first, it.second.first, it.second.second)); equation->detrend(symb_id, deflator.first, deflator.second));
assert(equation); assert(equation);
} }
} }
...@@ -4368,7 +4365,7 @@ DynamicModel::OccbinRegimeTracker::addRegime(const vector<string>& constraints_b ...@@ -4368,7 +4365,7 @@ DynamicModel::OccbinRegimeTracker::addRegime(const vector<string>& constraints_b
vector<bool> new_regime_template(constraints.size(), false); vector<bool> new_regime_template(constraints.size(), false);
for (const auto& c : constraints_bind) for (const auto& c : constraints_bind)
{ {
int i = distance(constraints.begin(), ranges::find(constraints, c)); int i = ranges::distance(constraints.begin(), ranges::find(constraints, c));
new_regime_template[i] = true; new_regime_template[i] = true;
} }
set<vector<bool>> new_regimes {new_regime_template}; set<vector<bool>> new_regimes {new_regime_template};
...@@ -4378,7 +4375,7 @@ DynamicModel::OccbinRegimeTracker::addRegime(const vector<string>& constraints_b ...@@ -4378,7 +4375,7 @@ DynamicModel::OccbinRegimeTracker::addRegime(const vector<string>& constraints_b
back_inserter(constraints_not_mentioned)); back_inserter(constraints_not_mentioned));
for (const auto& c : constraints_not_mentioned) for (const auto& c : constraints_not_mentioned)
{ {
int i = distance(constraints.begin(), ranges::find(constraints, c)); int i = ranges::distance(constraints.begin(), ranges::find(constraints, c));
auto new_regimes_copy = new_regimes; auto new_regimes_copy = new_regimes;
for (const auto& r : new_regimes_copy) for (const auto& r : new_regimes_copy)
{ {
......
...@@ -73,7 +73,8 @@ public: ...@@ -73,7 +73,8 @@ public:
void checkAllRegimesPresent() const noexcept(false); void checkAllRegimesPresent() const noexcept(false);
private: private:
pair<vector<string>, vector<string>> convertBitVectorToRegimes(const vector<bool>& r) const; [[nodiscard]] pair<vector<string>, vector<string>>
convertBitVectorToRegimes(const vector<bool>& r) const;
}; };
private: private:
...@@ -713,7 +714,7 @@ public: ...@@ -713,7 +714,7 @@ public:
{ {
return tuple {static_only_equations, static_only_equations_lineno, return tuple {static_only_equations, static_only_equations_lineno,
static_only_complementarity_conditions, static_only_equations_equation_tags}; static_only_complementarity_conditions, static_only_equations_equation_tags};
}; }
//! Returns true if a parameter was used in the model block with a lead or lag //! Returns true if a parameter was used in the model block with a lead or lag
bool ParamUsedWithLeadLag() const; bool ParamUsedWithLeadLag() const;
......
// -*- C++ -*- // -*- C++ -*-
/* /*
* Copyright © 2003-2024 Dynare Team * Copyright © 2003-2025 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -28,20 +28,20 @@ ...@@ -28,20 +28,20 @@
%define parse.error verbose %define parse.error verbose
%define parse.trace %define parse.trace
%code top {
class ParsingDriver;
}
%code requires { %code requires {
// Only headers needed for the value and location types go here
// Headers needed by the Bison file itself go in the unqualified %code section
#include <string> #include <string>
#include <vector> #include <vector>
#include <map> #include <map>
#include <utility>
#include <tuple> #include <tuple>
#include <variant> #include <variant>
#include "CommonEnums.hh" #include "CommonEnums.hh"
#include "ExprNode.hh" #include "ExprNode.hh"
#include "Shocks.hh"
class ParsingDriver;
} }
%param { ParsingDriver &driver } %param { ParsingDriver &driver }
...@@ -54,6 +54,9 @@ class ParsingDriver; ...@@ -54,6 +54,9 @@ class ParsingDriver;
} }
%code { %code {
#include <ranges>
#include <utility>
/* Little hack: we redefine the macro which computes the locations, because /* Little hack: we redefine the macro which computes the locations, because
we need to access the location from within the parsing driver for error we need to access the location from within the parsing driver for error
and warning messages. */ and warning messages. */
...@@ -104,11 +107,11 @@ str_tolower(string s) ...@@ -104,11 +107,11 @@ str_tolower(string s)
%token END ENDVAL EQUAL ESTIMATION ESTIMATED_PARAMS ESTIMATED_PARAMS_BOUNDS ESTIMATED_PARAMS_INIT EXTENDED_PATH ENDOGENOUS_PRIOR EXPRESSION %token END ENDVAL EQUAL ESTIMATION ESTIMATED_PARAMS ESTIMATED_PARAMS_BOUNDS ESTIMATED_PARAMS_INIT EXTENDED_PATH ENDOGENOUS_PRIOR EXPRESSION
%token FILENAME DIRNAME FILTER_STEP_AHEAD FILTERED_VARS FIRST_OBS FIRST_SIMULATION_PERIOD LAST_SIMULATION_PERIOD LAST_OBS %token FILENAME DIRNAME FILTER_STEP_AHEAD FILTERED_VARS FIRST_OBS FIRST_SIMULATION_PERIOD LAST_SIMULATION_PERIOD LAST_OBS
%token SET_TIME OSR_PARAMS_BOUNDS KEEP_KALMAN_ALGO_IF_SINGULARITY_IS_DETECTED %token SET_TIME OSR_PARAMS_BOUNDS KEEP_KALMAN_ALGO_IF_SINGULARITY_IS_DETECTED
%token <string> FALSE FLOAT_NUMBER DATES %token <string> FALSE FLOAT_NUMBER DATE
%token DEFAULT FIXED_POINT FLIP OPT_ALGO COMPILATION_SETUP COMPILER ADD_FLAGS SUBSTITUTE_FLAGS ADD_LIBS SUBSTITUTE_LIBS %token DEFAULT FIXED_POINT FLIP OPT_ALGO COMPILATION_SETUP COMPILER ADD_FLAGS SUBSTITUTE_FLAGS ADD_LIBS SUBSTITUTE_LIBS
%token FORECAST K_ORDER_SOLVER INSTRUMENTS SHIFT MEAN STDEV VARIANCE MODE INTERVAL SHAPE DOMAINN %token FORECAST K_ORDER_SOLVER INSTRUMENTS SHIFT MEAN STDEV VARIANCE MODE INTERVAL SHAPE DOMAINN
%token GAMMA_PDF GRAPH GRAPH_FORMAT CONDITIONAL_VARIANCE_DECOMPOSITION NOCHECK STD %token GAMMA_PDF GRAPH GRAPH_FORMAT CONDITIONAL_VARIANCE_DECOMPOSITION NOCHECK STD
%token HISTVAL HISTVAL_FILE HOMOTOPY_SETUP HOMOTOPY_MODE HOMOTOPY_STEPS HOMOTOPY_FORCE_CONTINUE HP_FILTER HP_NGRID FILTERED_THEORETICAL_MOMENTS_GRID HYBRID ONE_SIDED_HP_FILTER %token HISTVAL HISTVAL_FILE HOMOTOPY_SETUP HOMOTOPY_MODE HOMOTOPY_STEPS HOMOTOPY_FORCE_CONTINUE HP_FILTER HP_NGRID FILTERED_THEORETICAL_MOMENTS_GRID HYBRID USE_FIRST_ORDER_SOLUTION ONE_SIDED_HP_FILTER
%token IDENTIFICATION INF_CONSTANT INITVAL INITVAL_FILE BOUNDS JSCALE INIT INFILE INVARS %token IDENTIFICATION INF_CONSTANT INITVAL INITVAL_FILE BOUNDS JSCALE INIT INFILE INVARS
%token <string> INT_NUMBER %token <string> INT_NUMBER
%token CONDITIONAL_LIKELIHOOD %token CONDITIONAL_LIKELIHOOD
...@@ -121,7 +124,7 @@ str_tolower(string s) ...@@ -121,7 +124,7 @@ str_tolower(string s)
%token POSTERIOR_MAX_SUBSAMPLE_DRAWS MIN MINIMAL_SOLVING_PERIODS %token POSTERIOR_MAX_SUBSAMPLE_DRAWS MIN MINIMAL_SOLVING_PERIODS
%token MODE_CHECK MODE_CHECK_NEIGHBOURHOOD_SIZE MODE_CHECK_SYMMETRIC_PLOTS MODE_CHECK_NUMBER_OF_POINTS MODE_COMPUTE MODE_FILE MODEL MODEL_COMPARISON MODEL_INFO MSHOCKS ABS SIGN %token MODE_CHECK MODE_CHECK_NEIGHBOURHOOD_SIZE MODE_CHECK_SYMMETRIC_PLOTS MODE_CHECK_NUMBER_OF_POINTS MODE_COMPUTE MODE_FILE MODEL MODEL_COMPARISON MODEL_INFO MSHOCKS ABS SIGN
%token MODEL_DIAGNOSTICS MODIFIEDHARMONICMEAN MOMENTS_VARENDO CONTEMPORANEOUS_CORRELATION DIFFUSE_FILTER SUB_DRAWS TAPER_STEPS GEWEKE_INTERVAL RAFTERY_LEWIS_QRS RAFTERY_LEWIS_DIAGNOSTICS BROOKS_GELMAN_PLOTROWS MCMC_JUMPING_COVARIANCE MOMENT_CALIBRATION %token MODEL_DIAGNOSTICS MODIFIEDHARMONICMEAN MOMENTS_VARENDO CONTEMPORANEOUS_CORRELATION DIFFUSE_FILTER SUB_DRAWS TAPER_STEPS GEWEKE_INTERVAL RAFTERY_LEWIS_QRS RAFTERY_LEWIS_DIAGNOSTICS BROOKS_GELMAN_PLOTROWS MCMC_JUMPING_COVARIANCE MOMENT_CALIBRATION
%token NUMBER_OF_PARTICLES RESAMPLING SYSTEMATIC GENERIC RESAMPLING_THRESHOLD RESAMPLING_METHOD KITAGAWA STRATIFIED SMOOTH %token NUMBER_OF_PARTICLES RESAMPLING SYSTEMATIC GENERIC RESAMPLING_THRESHOLD RESAMPLING_METHOD KITAGAWA STRATIFIED SMOOTH MULTINOMIAL
%token CPF_WEIGHTS AMISANOTRISTANI MURRAYJONESPARSLOW WRITE_EQUATION_TAGS FILTER_INITIAL_STATE %token CPF_WEIGHTS AMISANOTRISTANI MURRAYJONESPARSLOW WRITE_EQUATION_TAGS FILTER_INITIAL_STATE
%token NONLINEAR_FILTER_INITIALIZATION FILTER_ALGORITHM PROPOSAL_APPROXIMATION CUBATURE UNSCENTED MONTECARLO DISTRIBUTION_APPROXIMATION %token NONLINEAR_FILTER_INITIALIZATION FILTER_ALGORITHM PROPOSAL_APPROXIMATION CUBATURE UNSCENTED MONTECARLO DISTRIBUTION_APPROXIMATION
%token <string> NAME %token <string> NAME
...@@ -170,7 +173,8 @@ str_tolower(string s) ...@@ -170,7 +173,8 @@ str_tolower(string s)
%token VLISTLOG VLISTPER SPECTRAL_DENSITY INIT2SHOCKS %token VLISTLOG VLISTPER SPECTRAL_DENSITY INIT2SHOCKS
%token RESTRICTION RESTRICTION_FNAME CROSS_RESTRICTIONS NLAGS CONTEMP_REDUCED_FORM REAL_PSEUDO_FORECAST %token RESTRICTION RESTRICTION_FNAME CROSS_RESTRICTIONS NLAGS CONTEMP_REDUCED_FORM REAL_PSEUDO_FORECAST
%token DUMMY_OBS NSTATES INDXSCALESSTATES NO_BAYESIAN_PRIOR SPECIFICATION SIMS_ZHA %token DUMMY_OBS NSTATES INDXSCALESSTATES NO_BAYESIAN_PRIOR SPECIFICATION SIMS_ZHA
%token <string> ALPHA BETA ABAND NINV CMS NCMS CNUM GAMMA INV_GAMMA INV_GAMMA1 INV_GAMMA2 NORMAL UNIFORM EPS PDF FIG DR NONE PRIOR PRIOR_VARIANCE HESSIAN IDENTITY_MATRIX DIRICHLET DIAGONAL OPTIMAL MFS %token <string> ALPHA BETA ABAND NINV CMS NCMS CNUM GAMMA INV_GAMMA INV_GAMMA1 INV_GAMMA2 NORMAL UNIFORM EPS PDF FIG DR NONE PRIOR DIRICHLET MFS RESIDUAL
%token PRIOR_VARIANCE HESSIAN IDENTITY_MATRIX
%token GSIG2_LMDM Q_DIAG FLAT_PRIOR NCSK NSTD WEIBULL WEIBULL_PDF %token GSIG2_LMDM Q_DIAG FLAT_PRIOR NCSK NSTD WEIBULL WEIBULL_PDF
%token INDXPARR INDXOVR INDXAP APBAND INDXIMF INDXFORE FOREBAND INDXGFOREHAT INDXGIMFHAT %token INDXPARR INDXOVR INDXAP APBAND INDXIMF INDXFORE FOREBAND INDXGFOREHAT INDXGIMFHAT
%token INDXESTIMA INDXGDLS EQ_MS FILTER_COVARIANCE UPDATED_COVARIANCE FILTER_DECOMPOSITION SMOOTHED_STATE_UNCERTAINTY SMOOTHER_REDUX %token INDXESTIMA INDXGDLS EQ_MS FILTER_COVARIANCE UPDATED_COVARIANCE FILTER_DECOMPOSITION SMOOTHED_STATE_UNCERTAINTY SMOOTHER_REDUX
...@@ -216,7 +220,9 @@ str_tolower(string s) ...@@ -216,7 +220,9 @@ str_tolower(string s)
%token HOMOTOPY_MAX_COMPLETION_SHARE HOMOTOPY_MIN_STEP_SIZE HOMOTOPY_INITIAL_STEP_SIZE HOMOTOPY_STEP_SIZE_INCREASE_SUCCESS_COUNT %token HOMOTOPY_MAX_COMPLETION_SHARE HOMOTOPY_MIN_STEP_SIZE HOMOTOPY_INITIAL_STEP_SIZE HOMOTOPY_STEP_SIZE_INCREASE_SUCCESS_COUNT
%token HOMOTOPY_LINEARIZATION_FALLBACK HOMOTOPY_MARGINAL_LINEARIZATION_FALLBACK HOMOTOPY_EXCLUDE_VAREXO FROM_INITVAL_TO_ENDVAL %token HOMOTOPY_LINEARIZATION_FALLBACK HOMOTOPY_MARGINAL_LINEARIZATION_FALLBACK HOMOTOPY_EXCLUDE_VAREXO FROM_INITVAL_TO_ENDVAL
%token STATIC_MFS RELATIVE_TO_INITVAL MATCHED_IRFS MATCHED_IRFS_WEIGHTS WEIGHTS PERPENDICULAR %token STATIC_MFS RELATIVE_TO_INITVAL MATCHED_IRFS MATCHED_IRFS_WEIGHTS WEIGHTS PERPENDICULAR
%token HETEROGENEITY HETEROGENEITY_DIMENSION SUM %token HETEROGENEITY HETEROGENEITY_DIMENSION SUM PERFECT_FORESIGHT_CONTROLLED_PATHS EXOGENIZE ENDOGENIZE
%token PRECONDITIONER UMFITER ITERSTACK ILU ITER_TOL ITER_MAXIT GMRES_RESTART ITERSTACK_MAXLU ITERSTACK_NPERIODS ITERSTACK_NLU ITERSTACK_RELU
CHECK_JACOBIAN_SINGULARITY
%token <vector<string>> SYMBOL_VEC %token <vector<string>> SYMBOL_VEC
...@@ -242,22 +248,26 @@ str_tolower(string s) ...@@ -242,22 +248,26 @@ str_tolower(string s)
%type <vector<map<string, string>>> tag_pair_list_for_selection %type <vector<map<string, string>>> tag_pair_list_for_selection
%type <map<string, string>> tag_pair_list %type <map<string, string>> tag_pair_list
%type <tuple<string,string,string,string>> prior_eq_opt options_eq_opt %type <tuple<string,string,string,string>> prior_eq_opt options_eq_opt
%type <vector<pair<int, int>>> period_list %type <AbstractShocksStatement::period_range_t> period_range
%type <vector<AbstractShocksStatement::period_range_t>> period_list
%type <vector<expr_t>> matched_moments_list value_list ramsey_constraints_list %type <vector<expr_t>> matched_moments_list value_list ramsey_constraints_list
%type <tuple<string, BinaryOpNode *, BinaryOpNode *, expr_t, expr_t>> occbin_constraints_regime %type <tuple<string, BinaryOpNode*, BinaryOpNode*, expr_t, expr_t>> occbin_constraints_regime
%type <vector<tuple<string, BinaryOpNode *, BinaryOpNode *, expr_t, expr_t>>> occbin_constraints_regimes_list %type <vector<tuple<string, BinaryOpNode*, BinaryOpNode*, expr_t, expr_t>>> occbin_constraints_regimes_list
%type <map<string, expr_t>> occbin_constraints_regime_options_list %type <map<string, expr_t>> occbin_constraints_regime_options_list
%type <pair<string, expr_t>> occbin_constraints_regime_option %type <pair<string, expr_t>> occbin_constraints_regime_option
%type <PacTargetKind> pac_target_kind %type <PacTargetKind> pac_target_kind
%type <vector<tuple<string, string, vector<pair<string, string>>>>> symbol_list_with_tex_and_partition %type <vector<tuple<string, string, vector<pair<string, string>>>>> symbol_list_with_tex_and_partition
%type <map<string, variant<bool, string>>> mshocks_options_list %type <variant<int, string>> integer_or_date
%type <pair<string, variant<bool, string>>> mshocks_option %type <map<string, variant<bool, variant<int, string>>>> mshocks_options_list
%type <pair<string, variant<bool, variant<int, string>>>> mshocks_option
%type <pair<vector<expr_t>, vector<expr_t>>> matched_irfs_elem_values_weights %type <pair<vector<expr_t>, vector<expr_t>>> matched_irfs_elem_values_weights
%type <pair<pair<string, string>, vector<tuple<int, int, expr_t, expr_t>>>> matched_irfs_elem %type <pair<pair<string, string>, vector<tuple<int, int, expr_t, expr_t>>>> matched_irfs_elem
%type <map<pair<string, string>, vector<tuple<int, int, expr_t, expr_t>>>> matched_irfs_list %type <map<pair<string, string>, vector<tuple<int, int, expr_t, expr_t>>>> matched_irfs_list
%type <tuple<string, string, string>> matched_irfs_weights_elem_var_varexo %type <tuple<string, string, string>> matched_irfs_weights_elem_var_varexo
%type <pair<tuple<string, string, string, string, string, string>, expr_t>> matched_irfs_weights_elem %type <pair<tuple<string, string, string, string, string, string>, expr_t>> matched_irfs_weights_elem
%type <map<tuple<string, string, string, string, string, string>, expr_t>> matched_irfs_weights_list %type <map<tuple<string, string, string, string, string, string>, expr_t>> matched_irfs_weights_list
%type <tuple<string, vector<AbstractShocksStatement::period_range_t>, vector<expr_t>, string>> perfect_foresight_controlled_paths_elem
%type <vector<tuple<string, vector<AbstractShocksStatement::period_range_t>, vector<expr_t>, string>>> perfect_foresight_controlled_paths_list
%% %%
%start statement_list; %start statement_list;
...@@ -379,6 +389,7 @@ statement : parameters ...@@ -379,6 +389,7 @@ statement : parameters
| perfect_foresight_solver | perfect_foresight_solver
| perfect_foresight_with_expectation_errors_setup | perfect_foresight_with_expectation_errors_setup
| perfect_foresight_with_expectation_errors_solver | perfect_foresight_with_expectation_errors_solver
| perfect_foresight_controlled_paths
| prior_function | prior_function
| posterior_function | posterior_function
| method_of_moments | method_of_moments
...@@ -803,11 +814,17 @@ h_options: o_filename ...@@ -803,11 +814,17 @@ h_options: o_filename
| o_series | o_series
; ;
integer_or_date : INT_NUMBER
{ $$.emplace<int>(stoi($1)); }
| date_expr
{ $$.emplace<string>($1); }
;
endval : ENDVAL ';' endval_list END ';' endval : ENDVAL ';' endval_list END ';'
{ driver.end_endval(false); } { driver.end_endval(false); }
| ENDVAL '(' ALL_VALUES_REQUIRED ')' ';' endval_list END ';' | ENDVAL '(' ALL_VALUES_REQUIRED ')' ';' endval_list END ';'
{ driver.end_endval(true); } { driver.end_endval(true); }
| ENDVAL '(' LEARNT_IN EQUAL INT_NUMBER ')' ';' endval_list END ';' | ENDVAL '(' LEARNT_IN EQUAL integer_or_date ')' ';' endval_list END ';'
{ driver.end_endval_learnt_in($5); } { driver.end_endval_learnt_in($5); }
; ;
...@@ -1216,9 +1233,9 @@ shocks : SHOCKS ';' shock_list END ';' { driver.end_shocks(false); } ...@@ -1216,9 +1233,9 @@ shocks : SHOCKS ';' shock_list END ';' { driver.end_shocks(false); }
| SHOCKS '(' SURPRISE ')' ';' det_shock_list END ';' { driver.end_shocks_surprise(false); } | SHOCKS '(' SURPRISE ')' ';' det_shock_list END ';' { driver.end_shocks_surprise(false); }
| SHOCKS '(' SURPRISE COMMA OVERWRITE ')' ';' det_shock_list END ';' { driver.end_shocks_surprise(true); } | SHOCKS '(' SURPRISE COMMA OVERWRITE ')' ';' det_shock_list END ';' { driver.end_shocks_surprise(true); }
| SHOCKS '(' OVERWRITE COMMA SURPRISE ')' ';' det_shock_list END ';' { driver.end_shocks_surprise(true); } | SHOCKS '(' OVERWRITE COMMA SURPRISE ')' ';' det_shock_list END ';' { driver.end_shocks_surprise(true); }
| SHOCKS '(' LEARNT_IN EQUAL INT_NUMBER ')' ';' det_shock_list END ';' { driver.end_shocks_learnt_in($5, false); } | SHOCKS '(' LEARNT_IN EQUAL integer_or_date ')' ';' det_shock_list END ';' { driver.end_shocks_learnt_in($5, false); }
| SHOCKS '(' LEARNT_IN EQUAL INT_NUMBER COMMA OVERWRITE ')' ';' det_shock_list END ';' { driver.end_shocks_learnt_in($5, true); } | SHOCKS '(' LEARNT_IN EQUAL integer_or_date COMMA OVERWRITE ')' ';' det_shock_list END ';' { driver.end_shocks_learnt_in($5, true); }
| SHOCKS '(' OVERWRITE COMMA LEARNT_IN EQUAL INT_NUMBER ')' ';' det_shock_list END ';' { driver.end_shocks_learnt_in($7, true); } | SHOCKS '(' OVERWRITE COMMA LEARNT_IN EQUAL integer_or_date ')' ';' det_shock_list END ';' { driver.end_shocks_learnt_in($7, true); }
| SHOCKS '(' HETEROGENEITY EQUAL symbol ')' ';' stoch_shock_list END ';' | SHOCKS '(' HETEROGENEITY EQUAL symbol ')' ';' stoch_shock_list END ';'
{ driver.end_heterogeneous_shocks($5, false); } { driver.end_heterogeneous_shocks($5, false); }
| SHOCKS '(' HETEROGENEITY EQUAL symbol COMMA OVERWRITE ')' ';' stoch_shock_list END ';' | SHOCKS '(' HETEROGENEITY EQUAL symbol COMMA OVERWRITE ')' ';' stoch_shock_list END ';'
...@@ -1364,11 +1381,11 @@ mshocks : MSHOCKS ';' mshock_list END ';' ...@@ -1364,11 +1381,11 @@ mshocks : MSHOCKS ';' mshock_list END ';'
{ driver.end_mshocks(false, false); } { driver.end_mshocks(false, false); }
| MSHOCKS '(' mshocks_options_list ')' ';' mshock_list END ';' | MSHOCKS '(' mshocks_options_list ')' ';' mshock_list END ';'
{ {
/* NB: the following relies of the fact that bool is the first /* NB: the following relies on the fact that bool is the first
alternative in the variant, so that default initialization of the alternative in the variant, so that default initialization of the
variant by the [] operator will give false */ variant by the [] operator will give false */
if ($3.contains("learnt_in")) if ($3.contains("learnt_in"))
driver.end_mshocks_learnt_in(get<string>($3.at("learnt_in")), driver.end_mshocks_learnt_in(get<variant<int, string>>($3.at("learnt_in")),
get<bool>($3["overwrite"]), get<bool>($3["overwrite"]),
get<bool>($3["relative_to_initval"])); get<bool>($3["relative_to_initval"]));
else else
...@@ -1389,7 +1406,7 @@ mshocks_options_list : mshocks_option ...@@ -1389,7 +1406,7 @@ mshocks_options_list : mshocks_option
mshocks_option : OVERWRITE mshocks_option : OVERWRITE
{ $$ = {"overwrite", true}; } { $$ = {"overwrite", true}; }
| LEARNT_IN EQUAL INT_NUMBER | LEARNT_IN EQUAL integer_or_date
{ $$ = {"learnt_in", $3}; } { $$ = {"learnt_in", $3}; }
| RELATIVE_TO_INITVAL | RELATIVE_TO_INITVAL
{ $$ = {"relative_to_initval", true}; } { $$ = {"relative_to_initval", true}; }
...@@ -1399,48 +1416,38 @@ mshock_list : mshock_list det_shock_elem ...@@ -1399,48 +1416,38 @@ mshock_list : mshock_list det_shock_elem
| det_shock_elem | det_shock_elem
; ;
period_list : period_list COMMA INT_NUMBER period_list : period_range
{ { $$ = { $1 }; }
$$ = $1; | period_list period_range
int p = stoi($3);
$$.emplace_back(p, p);
}
| period_list INT_NUMBER
{
$$ = $1;
int p = stoi($2);
$$.emplace_back(p, p);
}
| period_list COMMA INT_NUMBER ':' INT_NUMBER
{ {
$$ = $1; $$ = $1;
int p1 = stoi($3), p2 = stoi($5); $$.emplace_back($2);
if (p1 > p2)
driver.error("Can't have first period index greater than second index in range specification");
$$.emplace_back(p1, p2);
} }
| period_list INT_NUMBER ':' INT_NUMBER | period_list COMMA period_range
{ {
$$ = $1; $$ = $1;
int p1 = stoi($2), p2 = stoi($4); $$.emplace_back($3);
if (p1 > p2)
driver.error("Can't have first period index greater than second index in range specification");
$$.emplace_back(p1, p2);
}
| INT_NUMBER ':' INT_NUMBER
{
int p1 = stoi($1), p2 = stoi($3);
if (p1 > p2)
driver.error("Can't have first period index greater than second index in range specification");
$$ = {{p1, p2}};
}
| INT_NUMBER
{
int p = stoi($1);
$$ = {{p, p}};
} }
; ;
period_range : INT_NUMBER
{
int p = stoi($1);
$$.emplace<pair<int, int>>(p, p);
}
| INT_NUMBER ':' INT_NUMBER
{
int p1 = stoi($1), p2 = stoi($3);
if (p1 > p2)
driver.error("Can't have first period index greater than second index in range specification");
$$.emplace<pair<int, int>>(p1, p2);
}
| date_expr
{ $$.emplace<pair<string, string>>($1, $1); }
| date_expr ':' date_expr
{ $$.emplace<pair<string, string>>($1, $3); }
;
value_list : value_list COMMA '(' expression ')' value_list : value_list COMMA '(' expression ')'
{ {
$$ = $1; $$ = $1;
...@@ -1496,6 +1503,7 @@ steady_options : o_solve_algo ...@@ -1496,6 +1503,7 @@ steady_options : o_solve_algo
| o_steady_tolf | o_steady_tolf
| o_steady_tolx | o_steady_tolx
| o_fsolve_options | o_fsolve_options
| o_non_zero
; ;
check : CHECK ';' check : CHECK ';'
...@@ -1540,6 +1548,8 @@ perfect_foresight_setup_options_list : perfect_foresight_setup_options_list COMM ...@@ -1540,6 +1548,8 @@ perfect_foresight_setup_options_list : perfect_foresight_setup_options_list COMM
perfect_foresight_setup_options : o_periods perfect_foresight_setup_options : o_periods
| o_datafile | o_datafile
| o_endval_steady | o_endval_steady
| o_pf_first_simulation_period
| o_pf_last_simulation_period
; ;
perfect_foresight_solver : PERFECT_FORESIGHT_SOLVER ';' perfect_foresight_solver : PERFECT_FORESIGHT_SOLVER ';'
...@@ -1578,6 +1588,15 @@ perfect_foresight_solver_options : o_stack_solve_algo ...@@ -1578,6 +1588,15 @@ perfect_foresight_solver_options : o_stack_solve_algo
| o_homotopy_linearization_fallback | o_homotopy_linearization_fallback
| o_homotopy_marginal_linearization_fallback | o_homotopy_marginal_linearization_fallback
| o_homotopy_exclude_varexo | o_homotopy_exclude_varexo
| o_preconditioner
| o_iter_tol
| o_iter_maxit
| o_gmres_restart
| o_iterstack_maxlu
| o_iterstack_nperiods
| o_iterstack_nlu
| o_iterstack_relu
| o_check_jacobian_singularity
; ;
perfect_foresight_with_expectation_errors_setup : PERFECT_FORESIGHT_WITH_EXPECTATION_ERRORS_SETUP ';' perfect_foresight_with_expectation_errors_setup : PERFECT_FORESIGHT_WITH_EXPECTATION_ERRORS_SETUP ';'
...@@ -1592,6 +1611,8 @@ perfect_foresight_with_expectation_errors_setup_options_list : perfect_foresight ...@@ -1592,6 +1611,8 @@ perfect_foresight_with_expectation_errors_setup_options_list : perfect_foresight
perfect_foresight_with_expectation_errors_setup_options : o_periods perfect_foresight_with_expectation_errors_setup_options : o_periods
| o_datafile | o_datafile
| o_pf_first_simulation_period
| o_pf_last_simulation_period
; ;
perfect_foresight_with_expectation_errors_solver : PERFECT_FORESIGHT_WITH_EXPECTATION_ERRORS_SOLVER ';' perfect_foresight_with_expectation_errors_solver : PERFECT_FORESIGHT_WITH_EXPECTATION_ERRORS_SOLVER ';'
...@@ -1608,6 +1629,31 @@ perfect_foresight_with_expectation_errors_solver_options : o_pfwee_constant_simu ...@@ -1608,6 +1629,31 @@ perfect_foresight_with_expectation_errors_solver_options : o_pfwee_constant_simu
| perfect_foresight_solver_options | perfect_foresight_solver_options
; ;
perfect_foresight_controlled_paths : PERFECT_FORESIGHT_CONTROLLED_PATHS ';' perfect_foresight_controlled_paths_list END ';'
{ driver.perfect_foresight_controlled_paths($3, 1); }
| PERFECT_FORESIGHT_CONTROLLED_PATHS '(' LEARNT_IN EQUAL integer_or_date ')' ';' perfect_foresight_controlled_paths_list END ';'
{ driver.perfect_foresight_controlled_paths($8, $5); }
;
perfect_foresight_controlled_paths_list : perfect_foresight_controlled_paths_list perfect_foresight_controlled_paths_elem
{
$$ = $1;
$$.push_back($2);
}
| perfect_foresight_controlled_paths_elem
{ $$ = { $1 }; }
;
perfect_foresight_controlled_paths_elem : EXOGENIZE symbol ';' PERIODS period_list ';' VALUES value_list ';' ENDOGENIZE symbol ';'
{
driver.check_symbol_is_endogenous($2);
driver.check_symbol_is_exogenous($11, false);
if ($5.size() != $8.size())
driver.error("The number of periods is different from the number of values");
$$ = { $2, $5, $8, $11};
}
;
method_of_moments : METHOD_OF_MOMENTS ';' method_of_moments : METHOD_OF_MOMENTS ';'
{ driver.method_of_moments(); } { driver.method_of_moments(); }
| METHOD_OF_MOMENTS '(' method_of_moments_options_list ')' ';' | METHOD_OF_MOMENTS '(' method_of_moments_options_list ')' ';'
...@@ -2091,7 +2137,8 @@ prior_pdf : BETA_PDF ...@@ -2091,7 +2137,8 @@ prior_pdf : BETA_PDF
{ $$ = PriorDistributions::weibull; } { $$ = PriorDistributions::weibull; }
; ;
date_expr : DATES date_expr : DATE
{ $$ = "dates('" + $1 + "')"; }
| date_expr PLUS INT_NUMBER | date_expr PLUS INT_NUMBER
{ $$ = $1 + '+' + $3; } { $$ = $1 + '+' + $3; }
; ;
...@@ -3491,7 +3538,8 @@ extended_path_option : o_periods ...@@ -3491,7 +3538,8 @@ extended_path_option : o_periods
| o_solver_periods | o_solver_periods
| o_extended_path_order | o_extended_path_order
| o_hybrid | o_hybrid
| o_lmmcp | o_use_first_order_solution
| o_lmmcp
; ;
model_diagnostics : MODEL_DIAGNOSTICS ';' model_diagnostics : MODEL_DIAGNOSTICS ';'
...@@ -3619,7 +3667,15 @@ matched_irfs_elem : matched_irfs_elem_var_varexo ...@@ -3619,7 +3667,15 @@ matched_irfs_elem : matched_irfs_elem_var_varexo
vector<tuple<int, int, expr_t, expr_t>> v; vector<tuple<int, int, expr_t, expr_t>> v;
v.reserve($3.size()); v.reserve($3.size());
for (size_t i {0}; i < $3.size(); i++) for (size_t i {0}; i < $3.size(); i++)
v.emplace_back($3[i].first, $3[i].second, $5.first[i], $5.second[i]); try
{
auto [p1, p2] = get<pair<int, int>>($3[i]);
v.emplace_back(p1, p2, $5.first[i], $5.second[i]);
}
catch (bad_variant_access&)
{
driver.error("matched_irfs: dates are not allowed in the 'periods' keyword");
}
$$ = {$1, v}; $$ = {$1, v};
} }
; ;
...@@ -3718,6 +3774,7 @@ o_periods : PERIODS EQUAL INT_NUMBER { driver.option_num("periods", $3); }; ...@@ -3718,6 +3774,7 @@ o_periods : PERIODS EQUAL INT_NUMBER { driver.option_num("periods", $3); };
o_solver_periods : SOLVER_PERIODS EQUAL INT_NUMBER { driver.option_num("ep.periods", $3); }; o_solver_periods : SOLVER_PERIODS EQUAL INT_NUMBER { driver.option_num("ep.periods", $3); };
o_extended_path_order : ORDER EQUAL INT_NUMBER { driver.option_num("ep.stochastic.order", $3); }; o_extended_path_order : ORDER EQUAL INT_NUMBER { driver.option_num("ep.stochastic.order", $3); };
o_hybrid : HYBRID { driver.option_num("ep.stochastic.hybrid_order", "2"); }; o_hybrid : HYBRID { driver.option_num("ep.stochastic.hybrid_order", "2"); };
o_use_first_order_solution : USE_FIRST_ORDER_SOLUTION { driver.option_num("ep.use_first_order_solution_as_initial_guess", "true"); };
o_steady_maxit : MAXIT EQUAL INT_NUMBER { driver.option_num("steady.maxit", $3); }; o_steady_maxit : MAXIT EQUAL INT_NUMBER { driver.option_num("steady.maxit", $3); };
o_simul_maxit : MAXIT EQUAL INT_NUMBER { driver.option_num("simul.maxit", $3); }; o_simul_maxit : MAXIT EQUAL INT_NUMBER { driver.option_num("simul.maxit", $3); };
o_bandpass_filter : BANDPASS_FILTER { driver.option_num("bandpass.indicator", "true"); } o_bandpass_filter : BANDPASS_FILTER { driver.option_num("bandpass.indicator", "true"); }
...@@ -3793,6 +3850,8 @@ o_first_simulation_period : FIRST_SIMULATION_PERIOD EQUAL INT_NUMBER { driver.op ...@@ -3793,6 +3850,8 @@ o_first_simulation_period : FIRST_SIMULATION_PERIOD EQUAL INT_NUMBER { driver.op
o_last_simulation_period : LAST_SIMULATION_PERIOD EQUAL INT_NUMBER { driver.option_num("last_simulation_period", $3); } o_last_simulation_period : LAST_SIMULATION_PERIOD EQUAL INT_NUMBER { driver.option_num("last_simulation_period", $3); }
| LAST_SIMULATION_PERIOD EQUAL date_expr { driver.option_date("last_simulation_period", $3); } | LAST_SIMULATION_PERIOD EQUAL date_expr { driver.option_date("last_simulation_period", $3); }
; ;
o_pf_first_simulation_period : FIRST_SIMULATION_PERIOD EQUAL date_expr { driver.option_date("simul.first_simulation_period", $3); };
o_pf_last_simulation_period : LAST_SIMULATION_PERIOD EQUAL date_expr { driver.option_date("simul.last_simulation_period", $3); };
o_last_obs : LAST_OBS EQUAL INT_NUMBER { driver.option_num("last_obs", $3); }; o_last_obs : LAST_OBS EQUAL INT_NUMBER { driver.option_num("last_obs", $3); };
o_data_last_obs : LAST_OBS EQUAL date_expr { driver.option_date("last_obs", $3); } ; o_data_last_obs : LAST_OBS EQUAL date_expr { driver.option_date("last_obs", $3); } ;
o_keep_kalman_algo_if_singularity_is_detected : KEEP_KALMAN_ALGO_IF_SINGULARITY_IS_DETECTED { driver.option_num("kalman.keep_kalman_algo_if_singularity_is_detected", "true"); } ; o_keep_kalman_algo_if_singularity_is_detected : KEEP_KALMAN_ALGO_IF_SINGULARITY_IS_DETECTED { driver.option_num("kalman.keep_kalman_algo_if_singularity_is_detected", "true"); } ;
...@@ -4033,11 +4092,13 @@ o_resampling : RESAMPLING EQUAL SYSTEMATIC ...@@ -4033,11 +4092,13 @@ o_resampling : RESAMPLING EQUAL SYSTEMATIC
| RESAMPLING EQUAL NONE { driver.option_num("particle.resampling.status.systematic", "false"); driver.option_num("particle.resampling.status.none", "true"); } | RESAMPLING EQUAL NONE { driver.option_num("particle.resampling.status.systematic", "false"); driver.option_num("particle.resampling.status.none", "true"); }
| RESAMPLING EQUAL GENERIC { driver.option_num("particle.resampling.status.systematic", "false"); driver.option_num("particle.resampling.status.generic", "true"); }; | RESAMPLING EQUAL GENERIC { driver.option_num("particle.resampling.status.systematic", "false"); driver.option_num("particle.resampling.status.generic", "true"); };
o_resampling_threshold : RESAMPLING_THRESHOLD EQUAL non_negative_number { driver.option_num("particle.resampling.threshold", $3); }; o_resampling_threshold : RESAMPLING_THRESHOLD EQUAL non_negative_number { driver.option_num("particle.resampling.threshold", $3); };
o_resampling_method : RESAMPLING_METHOD EQUAL KITAGAWA { driver.option_num("particle.resampling.method.kitagawa", "true"); driver.option_num("particle.resampling.method.smooth", "false"); driver.option_num("particle.resampling.smethod.stratified", "false"); } o_resampling_method : RESAMPLING_METHOD EQUAL KITAGAWA { driver.option_num("particle.resampling.method.kitagawa", "true"); driver.option_num("particle.resampling.method.smooth", "false"); driver.option_num("particle.resampling.method.stratified", "false"); driver.option_num("particle.resampling.method.residual", "false"); driver.option_num("particle.resampling.method.multinomial", "false") ;}
| RESAMPLING_METHOD EQUAL SMOOTH { driver.option_num("particle.resampling.method.kitagawa", "false"); driver.option_num("particle.resampling.method.smooth", "true"); driver.option_num("particle.resampling.smethod.stratified", "false"); } | RESAMPLING_METHOD EQUAL SMOOTH { driver.option_num("particle.resampling.method.kitagawa", "false"); driver.option_num("particle.resampling.method.smooth", "true"); driver.option_num("particle.resampling.method.stratified", "false"); driver.option_num("particle.resampling.method.residual", "false"); driver.option_num("particle.resampling.method.multinomial", "false"); };
| RESAMPLING_METHOD EQUAL STRATIFIED { driver.option_num("particle.resampling.method.kitagawa", "false"); driver.option_num("particle.resampling.method.smooth", "false"); driver.option_num("particle.resampling.method.stratified", "true"); }; | RESAMPLING_METHOD EQUAL STRATIFIED { driver.option_num("particle.resampling.method.kitagawa", "false"); driver.option_num("particle.resampling.method.smooth", "false"); driver.option_num("particle.resampling.method.stratified", "true"); driver.option_num("particle.resampling.method.residual", "false"); driver.option_num("particle.resampling.method.multinomial", "false"); };
| RESAMPLING_METHOD EQUAL RESIDUAL { driver.option_num("particle.resampling.method.kitagawa", "false"); driver.option_num("particle.resampling.method.smooth", "false"); driver.option_num("particle.resampling.method.stratified", "false"); driver.option_num("particle.resampling.method.residual", "true"); driver.option_num("particle.resampling.method.multinomial", "false"); };
| RESAMPLING_METHOD EQUAL MULTINOMIAL { driver.option_num("particle.resampling.method.kitagawa", "false"); driver.option_num("particle.resampling.method.smooth", "false"); driver.option_num("particle.resampling.method.stratified", "false"); driver.option_num("particle.resampling.method.residual", "false"); driver.option_num("particle.resampling.method.multinomial", "true"); };
o_cpf_weights : CPF_WEIGHTS EQUAL AMISANOTRISTANI { driver.option_num("particle.cpf_weights_method.amisanotristani", "true"); driver.option_num("particle.cpf_weights_method.murrayjonesparslow", "false"); } o_cpf_weights : CPF_WEIGHTS EQUAL AMISANOTRISTANI { driver.option_num("particle.cpf_weights_method.amisanotristani", "true"); driver.option_num("particle.cpf_weights_method.murrayjonesparslow", "false"); }
| CPF_WEIGHTS EQUAL MURRAYJONESPARSLOW { driver.option_num("particle.cpf_weights_method.amisanotristani", "false"); driver.option_num("particle.cpf_weights_method.murrayjonesparslow", "true"); }; | CPF_WEIGHTS EQUAL MURRAYJONESPARSLOW { driver.option_num("particle.cpf_weights_method.amisanotristani", "false"); driver.option_num("particle.cpf_weights_method.murrayjonesparslow", "true"); };
o_filter_algorithm : FILTER_ALGORITHM EQUAL symbol { driver.option_str("particle.filter_algorithm", $3); }; o_filter_algorithm : FILTER_ALGORITHM EQUAL symbol { driver.option_str("particle.filter_algorithm", $3); };
o_nonlinear_filter_initialization : NONLINEAR_FILTER_INITIALIZATION EQUAL INT_NUMBER { driver.option_num("particle.initialization", $3); }; o_nonlinear_filter_initialization : NONLINEAR_FILTER_INITIALIZATION EQUAL INT_NUMBER { driver.option_num("particle.initialization", $3); };
o_proposal_approximation : PROPOSAL_APPROXIMATION EQUAL CUBATURE { driver.option_num("particle.proposal_approximation.cubature", "true"); driver.option_num("particle.proposal_approximation.unscented", "false"); driver.option_num("particle.proposal_approximation.montecarlo", "false"); } o_proposal_approximation : PROPOSAL_APPROXIMATION EQUAL CUBATURE { driver.option_num("particle.proposal_approximation.cubature", "true"); driver.option_num("particle.proposal_approximation.unscented", "false"); driver.option_num("particle.proposal_approximation.montecarlo", "false"); }
...@@ -4092,6 +4153,21 @@ o_max_dim_cova_group : MAX_DIM_COVA_GROUP EQUAL INT_NUMBER { driver.option_num(" ...@@ -4092,6 +4153,21 @@ o_max_dim_cova_group : MAX_DIM_COVA_GROUP EQUAL INT_NUMBER { driver.option_num("
o_homotopy_mode : HOMOTOPY_MODE EQUAL INT_NUMBER { driver.option_num("homotopy_mode", $3); }; o_homotopy_mode : HOMOTOPY_MODE EQUAL INT_NUMBER { driver.option_num("homotopy_mode", $3); };
o_homotopy_steps : HOMOTOPY_STEPS EQUAL INT_NUMBER { driver.option_num("homotopy_steps", $3); }; o_homotopy_steps : HOMOTOPY_STEPS EQUAL INT_NUMBER { driver.option_num("homotopy_steps", $3); };
o_homotopy_force_continue: HOMOTOPY_FORCE_CONTINUE EQUAL INT_NUMBER { driver.option_num("homotopy_force_continue", $3); }; o_homotopy_force_continue: HOMOTOPY_FORCE_CONTINUE EQUAL INT_NUMBER { driver.option_num("homotopy_force_continue", $3); };
o_preconditioner : PRECONDITIONER EQUAL UMFITER
{ driver.option_str("simul.preconditioner", "umfiter"); }
| PRECONDITIONER EQUAL ITERSTACK
{ driver.option_str("simul.preconditioner", "iterstack"); }
| PRECONDITIONER EQUAL ILU
{ driver.option_str("simul.preconditioner", "ilu"); };
;
o_iter_tol : ITER_TOL EQUAL non_negative_number { driver.option_num("simul.iter_tol", $3); };
o_iter_maxit : ITER_MAXIT EQUAL INT_NUMBER { driver.option_num("simul.iter_maxit", $3); };
o_gmres_restart : GMRES_RESTART EQUAL INT_NUMBER { driver.option_num("simul.gmres_restart", $3); };
o_iterstack_maxlu : ITERSTACK_MAXLU EQUAL INT_NUMBER { driver.option_num("simul.iterstack_maxlu", $3); };
o_iterstack_nperiods : ITERSTACK_NPERIODS EQUAL INT_NUMBER { driver.option_num("simul.iterstack_nperiods", $3); };
o_iterstack_nlu : ITERSTACK_NLU EQUAL INT_NUMBER { driver.option_num("simul.iterstack_nlu", $3); };
o_iterstack_relu : ITERSTACK_RELU EQUAL non_negative_number { driver.option_num("simul.iterstack_relu", $3); };
o_check_jacobian_singularity : CHECK_JACOBIAN_SINGULARITY { driver.option_num("simul.check_jacobian_singularity", "true"); };
o_nocheck : NOCHECK { driver.option_num("steadystate.nocheck", "true"); }; o_nocheck : NOCHECK { driver.option_num("steadystate.nocheck", "true"); };
o_controlled_varexo : CONTROLLED_VAREXO EQUAL '(' symbol_list ')' { driver.option_symbol_list("controlled_varexo", $4); }; o_controlled_varexo : CONTROLLED_VAREXO EQUAL '(' symbol_list ')' { driver.option_symbol_list("controlled_varexo", $4); };
...@@ -4306,10 +4382,11 @@ o_analytic_derivation_mode : ANALYTIC_DERIVATION_MODE EQUAL signed_number { driv ...@@ -4306,10 +4382,11 @@ o_analytic_derivation_mode : ANALYTIC_DERIVATION_MODE EQUAL signed_number { driv
o_endogenous_prior : ENDOGENOUS_PRIOR { driver.option_num("endogenous_prior", "true"); } o_endogenous_prior : ENDOGENOUS_PRIOR { driver.option_num("endogenous_prior", "true"); }
o_use_univariate_filters_if_singularity_is_detected : USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED EQUAL INT_NUMBER { driver.option_num("use_univariate_filters_if_singularity_is_detected", $3); } o_use_univariate_filters_if_singularity_is_detected : USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED EQUAL INT_NUMBER { driver.option_num("use_univariate_filters_if_singularity_is_detected", $3); }
o_mcmc_jumping_covariance : MCMC_JUMPING_COVARIANCE EQUAL HESSIAN o_mcmc_jumping_covariance : MCMC_JUMPING_COVARIANCE EQUAL HESSIAN
{ driver.option_str("MCMC_jumping_covariance", $3); } | MCMC_JUMPING_COVARIANCE EQUAL PRIOR_VARIANCE { driver.option_str("MCMC_jumping_covariance", "hessian"); }
{ driver.option_str("MCMC_jumping_covariance", $3); } | MCMC_JUMPING_COVARIANCE EQUAL PRIOR_VARIANCE
{ driver.option_str("MCMC_jumping_covariance", "prior_variance"); }
| MCMC_JUMPING_COVARIANCE EQUAL IDENTITY_MATRIX | MCMC_JUMPING_COVARIANCE EQUAL IDENTITY_MATRIX
{ driver.option_str("MCMC_jumping_covariance", $3); } { driver.option_str("MCMC_jumping_covariance", "identity_matrix"); }
| MCMC_JUMPING_COVARIANCE EQUAL filename | MCMC_JUMPING_COVARIANCE EQUAL filename
{ driver.option_str("MCMC_jumping_covariance", $3); } { driver.option_str("MCMC_jumping_covariance", $3); }
; ;
...@@ -4380,7 +4457,7 @@ o_emas_girf : EMAS_GIRF { driver.option_num("irf_opt.ergodic_mean_irf", "true"); ...@@ -4380,7 +4457,7 @@ o_emas_girf : EMAS_GIRF { driver.option_num("irf_opt.ergodic_mean_irf", "true");
o_emas_drop : EMAS_DROP EQUAL INT_NUMBER { driver.option_num("irf_opt.EM.drop", $3); }; o_emas_drop : EMAS_DROP EQUAL INT_NUMBER { driver.option_num("irf_opt.EM.drop", $3); };
o_emas_tolf : EMAS_TOLF EQUAL non_negative_number { driver.option_num("irf_opt.EM.tolf", $3); }; o_emas_tolf : EMAS_TOLF EQUAL non_negative_number { driver.option_num("irf_opt.EM.tolf", $3); };
o_emas_max_iter : EMAS_MAX_ITER EQUAL INT_NUMBER { driver.option_num("irf_opt.EM.iter", $3); }; o_emas_max_iter : EMAS_MAX_ITER EQUAL INT_NUMBER { driver.option_num("irf_opt.EM.iter", $3); };
o_non_zero : NON_ZERO { driver.option_num("non_zero", "true"); }; o_non_zero : NON_ZERO { driver.option_num("steady.non_zero", "true"); };
// Some options to "identification" // Some options to "identification"
o_no_identification_strength : NO_IDENTIFICATION_STRENGTH { driver.option_num("no_identification_strength", "true"); }; o_no_identification_strength : NO_IDENTIFICATION_STRENGTH { driver.option_num("no_identification_strength", "true"); };
...@@ -4470,9 +4547,8 @@ vec_int_number : INT_NUMBER ...@@ -4470,9 +4547,8 @@ vec_int_number : INT_NUMBER
vec_int_elem : vec_int_number vec_int_elem : vec_int_number
| INT_NUMBER ':' INT_NUMBER | INT_NUMBER ':' INT_NUMBER
{ {
$$ = {}; auto v = views::iota(stoi($1), stoi($3) + 1);
for (int i = stoi($1); i <= stoi($3); i++) $$ = {v.begin(), v.end()};
$$.push_back(i);
} }
; ;
...@@ -4600,6 +4676,7 @@ symbol : NAME ...@@ -4600,6 +4676,7 @@ symbol : NAME
| ADD | ADD
| MULTIPLY | MULTIPLY
| MFS | MFS
| RESIDUAL
; ;
%% %%
......
/* -*- C++ -*- */ /* -*- C++ -*- */
/* /*
* Copyright © 2003-2024 Dynare Team * Copyright © 2003-2025 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
%{ %{
#include <cstring>
#include "ParsingDriver.hh" #include "ParsingDriver.hh"
using namespace std; using namespace std;
...@@ -60,7 +59,6 @@ string eofbuff; ...@@ -60,7 +59,6 @@ string eofbuff;
%x VERBATIM_BLOCK %x VERBATIM_BLOCK
%x NATIVE %x NATIVE
%x NATIVE_COMMENT %x NATIVE_COMMENT
%x DATES_STATEMENT
%x LINE1 %x LINE1
%x LINE2 %x LINE2
%x LINE3 %x LINE3
...@@ -70,7 +68,9 @@ string eofbuff; ...@@ -70,7 +68,9 @@ string eofbuff;
#define YY_USER_ACTION location_increment(yylloc, yytext); #define YY_USER_ACTION location_increment(yylloc, yytext);
%} %}
DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) NAME [a-z_][a-z0-9_]*
FLOAT_NUMBER ((([0-9]*\.[0-9]+)|([0-9]+\.))([ed][-+]?[0-9]+)?)|([0-9]+[ed][-+]?[0-9]+)
DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]|[sh][12])
%% %%
/* Code put at the beginning of yylex() */ /* Code put at the beginning of yylex() */
...@@ -92,12 +92,12 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -92,12 +92,12 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
} }
/* spaces, tabs and carriage returns are ignored */ /* spaces, tabs and carriage returns are ignored */
<INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,COMMENT,DATES_STATEMENT,LINE1,LINE2,LINE3>[[:space:]]+ { yylloc->step(); } <INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,COMMENT,LINE1,LINE2,LINE3>[[:space:]]+ { yylloc->step(); }
/* Comments */ /* Comments */
<INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,DATES_STATEMENT>%.* <INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK>%.*
<INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,DATES_STATEMENT>"//".* <INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK>"//".*
<INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,DATES_STATEMENT>"/*" {comment_caller = YY_START; BEGIN COMMENT;} <INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK>"/*" {comment_caller = YY_START; BEGIN COMMENT;}
<COMMENT>"*/" {BEGIN comment_caller;} <COMMENT>"*/" {BEGIN comment_caller;}
<COMMENT>. <COMMENT>.
...@@ -236,6 +236,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -236,6 +236,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<INITIAL>pac_target_info {BEGIN DYNARE_BLOCK; return token::PAC_TARGET_INFO;} <INITIAL>pac_target_info {BEGIN DYNARE_BLOCK; return token::PAC_TARGET_INFO;}
<INITIAL>matched_irfs {BEGIN DYNARE_BLOCK; return token::MATCHED_IRFS;} <INITIAL>matched_irfs {BEGIN DYNARE_BLOCK; return token::MATCHED_IRFS;}
<INITIAL>matched_irfs_weights {BEGIN DYNARE_BLOCK; return token::MATCHED_IRFS_WEIGHTS;} <INITIAL>matched_irfs_weights {BEGIN DYNARE_BLOCK; return token::MATCHED_IRFS_WEIGHTS;}
<INITIAL>perfect_foresight_controlled_paths {BEGIN DYNARE_BLOCK; return token::PERFECT_FORESIGHT_CONTROLLED_PATHS;}
/* For the semicolon after an "end" keyword */ /* For the semicolon after an "end" keyword */
<INITIAL>; {return Dynare::parser::token_type (yytext[0]);} <INITIAL>; {return Dynare::parser::token_type (yytext[0]);}
...@@ -246,7 +247,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -246,7 +247,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>subsamples {return token::SUBSAMPLES;} <DYNARE_STATEMENT>subsamples {return token::SUBSAMPLES;}
<DYNARE_STATEMENT>options {return token::OPTIONS;} <DYNARE_STATEMENT>options {return token::OPTIONS;}
<DYNARE_STATEMENT>prior { <DYNARE_STATEMENT>prior {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::PRIOR; return token::PRIOR;
} }
<INITIAL>std {BEGIN DYNARE_STATEMENT; return token::STD;} <INITIAL>std {BEGIN DYNARE_STATEMENT; return token::STD;}
...@@ -256,27 +257,12 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -256,27 +257,12 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<INITIAL>prior_function {BEGIN DYNARE_STATEMENT; return token::PRIOR_FUNCTION;} <INITIAL>prior_function {BEGIN DYNARE_STATEMENT; return token::PRIOR_FUNCTION;}
<INITIAL>posterior_function {BEGIN DYNARE_STATEMENT; return token::POSTERIOR_FUNCTION;} <INITIAL>posterior_function {BEGIN DYNARE_STATEMENT; return token::POSTERIOR_FUNCTION;}
/* Inside of a Dynare statement */ <DYNARE_STATEMENT,DYNARE_BLOCK>{DATE} {
<DYNARE_STATEMENT>{DATE} { yylval->emplace<string>(yytext);
/* If a date is found within a statement, substitute it with a call to return token::DATE;
the dates() constructor in the input character stream. Then it will }
be handled by the rule that follows the present one. */
char* yycopy = strdup(yytext); /* Inside a Dynare statement */
char* uput = yycopy + yyleng;
unput(')');
unput('\'');
while (uput > yycopy)
unput(*--uput);
unput('\'');
unput('(');
unput('s');
unput('e');
unput('t');
unput('a');
unput('d');
free( yycopy );
}
<DYNARE_STATEMENT>dates {dates_parens_nb=0; BEGIN DATES_STATEMENT; yylval->build<string>("dates");}
<DYNARE_STATEMENT>file {return token::FILE;} <DYNARE_STATEMENT>file {return token::FILE;}
<DYNARE_STATEMENT>datafile {return token::DATAFILE;} <DYNARE_STATEMENT>datafile {return token::DATAFILE;}
<DYNARE_STATEMENT>dirname {return token::DIRNAME;} <DYNARE_STATEMENT>dirname {return token::DIRNAME;}
...@@ -309,10 +295,10 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -309,10 +295,10 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>posterior_nograph {return token::POSTERIOR_NOGRAPH;} <DYNARE_STATEMENT>posterior_nograph {return token::POSTERIOR_NOGRAPH;}
<DYNARE_STATEMENT>nodisplay {return token::NODISPLAY;} <DYNARE_STATEMENT>nodisplay {return token::NODISPLAY;}
<DYNARE_STATEMENT>graph_format {return token::GRAPH_FORMAT;} <DYNARE_STATEMENT>graph_format {return token::GRAPH_FORMAT;}
<DYNARE_STATEMENT>eps {yylval->build<string>(yytext); return token::EPS;} <DYNARE_STATEMENT>eps {yylval->emplace<string>(yytext); return token::EPS;}
<DYNARE_STATEMENT>pdf {yylval->build<string>(yytext); return token::PDF;} <DYNARE_STATEMENT>pdf {yylval->emplace<string>(yytext); return token::PDF;}
<DYNARE_STATEMENT>fig {yylval->build<string>(yytext); return token::FIG;} <DYNARE_STATEMENT>fig {yylval->emplace<string>(yytext); return token::FIG;}
<DYNARE_STATEMENT>none {yylval->build<string>(yytext); return token::NONE;} <DYNARE_STATEMENT>none {yylval->emplace<string>(yytext); return token::NONE;}
<DYNARE_STATEMENT>print {return token::PRINT;} <DYNARE_STATEMENT>print {return token::PRINT;}
<DYNARE_STATEMENT>noprint {return token::NOPRINT;} <DYNARE_STATEMENT>noprint {return token::NOPRINT;}
<DYNARE_STATEMENT>conf_sig {return token::CONF_SIG;} <DYNARE_STATEMENT>conf_sig {return token::CONF_SIG;}
...@@ -420,6 +406,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -420,6 +406,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>logarithmic_reduction {return token::LOGARITHMIC_REDUCTION;} <DYNARE_STATEMENT>logarithmic_reduction {return token::LOGARITHMIC_REDUCTION;}
<DYNARE_STATEMENT>use_univariate_filters_if_singularity_is_detected {return token::USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED;} <DYNARE_STATEMENT>use_univariate_filters_if_singularity_is_detected {return token::USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED;}
<DYNARE_STATEMENT>hybrid {return token::HYBRID;} <DYNARE_STATEMENT>hybrid {return token::HYBRID;}
<DYNARE_STATEMENT>use_first_order_solution {return token::USE_FIRST_ORDER_SOLUTION;}
<DYNARE_STATEMENT>default {return token::DEFAULT;} <DYNARE_STATEMENT>default {return token::DEFAULT;}
<DYNARE_STATEMENT>init2shocks {return token::INIT2SHOCKS;} <DYNARE_STATEMENT>init2shocks {return token::INIT2SHOCKS;}
...@@ -432,6 +419,11 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -432,6 +419,11 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>kitagawa {return token::KITAGAWA;} <DYNARE_STATEMENT>kitagawa {return token::KITAGAWA;}
<DYNARE_STATEMENT>smooth {return token::SMOOTH;} <DYNARE_STATEMENT>smooth {return token::SMOOTH;}
<DYNARE_STATEMENT>stratified {return token::STRATIFIED;} <DYNARE_STATEMENT>stratified {return token::STRATIFIED;}
<DYNARE_STATEMENT>residual {
yylval->emplace<string>(yytext);
return token::RESIDUAL;
}
<DYNARE_STATEMENT>multinomial {return token::MULTINOMIAL;}
<DYNARE_STATEMENT>cpf_weights {return token::CPF_WEIGHTS;} <DYNARE_STATEMENT>cpf_weights {return token::CPF_WEIGHTS;}
<DYNARE_STATEMENT>amisanotristani {return token::AMISANOTRISTANI;} <DYNARE_STATEMENT>amisanotristani {return token::AMISANOTRISTANI;}
<DYNARE_STATEMENT>murrayjonesparslow {return token::MURRAYJONESPARSLOW;} <DYNARE_STATEMENT>murrayjonesparslow {return token::MURRAYJONESPARSLOW;}
...@@ -453,43 +445,40 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -453,43 +445,40 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>fsolve_options {return token::FSOLVE_OPTIONS;} <DYNARE_STATEMENT>fsolve_options {return token::FSOLVE_OPTIONS;}
<DYNARE_STATEMENT>alpha { <DYNARE_STATEMENT>alpha {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::ALPHA; return token::ALPHA;
} }
<DYNARE_STATEMENT>beta { <DYNARE_STATEMENT>beta {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::BETA; return token::BETA;
} }
<DYNARE_STATEMENT>gamma { <DYNARE_STATEMENT>gamma {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::GAMMA; return token::GAMMA;
} }
<DYNARE_STATEMENT>inv_gamma { <DYNARE_STATEMENT>inv_gamma {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::INV_GAMMA; return token::INV_GAMMA;
} }
<DYNARE_STATEMENT>inv_gamma1 { <DYNARE_STATEMENT>inv_gamma1 {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::INV_GAMMA1; return token::INV_GAMMA1;
} }
<DYNARE_STATEMENT>inv_gamma2 { <DYNARE_STATEMENT>inv_gamma2 {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::INV_GAMMA2; return token::INV_GAMMA2;
} }
<DYNARE_STATEMENT>dirichlet { <DYNARE_STATEMENT>dirichlet {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::DIRICHLET; return token::DIRICHLET;
} }
<DYNARE_STATEMENT>weibull { <DYNARE_STATEMENT>weibull {return token::WEIBULL;}
yylval->build<string>(yytext);
return token::WEIBULL;
}
<DYNARE_STATEMENT>normal { <DYNARE_STATEMENT>normal {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::NORMAL; return token::NORMAL;
} }
<DYNARE_STATEMENT>uniform { <DYNARE_STATEMENT>uniform {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::UNIFORM; return token::UNIFORM;
} }
<DYNARE_STATEMENT>gsig2_lmdm {return token::GSIG2_LMDM;} <DYNARE_STATEMENT>gsig2_lmdm {return token::GSIG2_LMDM;}
...@@ -500,13 +489,13 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -500,13 +489,13 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>ncsk {return token::NCSK;} <DYNARE_STATEMENT>ncsk {return token::NCSK;}
<DYNARE_STATEMENT>nstd {return token::NSTD;} <DYNARE_STATEMENT>nstd {return token::NSTD;}
<DYNARE_STATEMENT>ninv { <DYNARE_STATEMENT>ninv {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::NINV; return token::NINV;
} }
<DYNARE_STATEMENT>indxparr {return token::INDXPARR;} <DYNARE_STATEMENT>indxparr {return token::INDXPARR;}
<DYNARE_STATEMENT>indxovr {return token::INDXOVR;} <DYNARE_STATEMENT>indxovr {return token::INDXOVR;}
<DYNARE_STATEMENT>aband { <DYNARE_STATEMENT>aband {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::ABAND; return token::ABAND;
} }
<DYNARE_STATEMENT>write_equation_tags {return token::WRITE_EQUATION_TAGS;} <DYNARE_STATEMENT>write_equation_tags {return token::WRITE_EQUATION_TAGS;}
...@@ -523,18 +512,18 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -523,18 +512,18 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>indxgdls {return token::INDXGDLS;} <DYNARE_STATEMENT>indxgdls {return token::INDXGDLS;}
<DYNARE_STATEMENT>eq_ms {return token::EQ_MS;} <DYNARE_STATEMENT>eq_ms {return token::EQ_MS;}
<DYNARE_STATEMENT>cms { <DYNARE_STATEMENT>cms {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::CMS; return token::CMS;
} }
<DYNARE_STATEMENT>ncms { <DYNARE_STATEMENT>ncms {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::NCMS; return token::NCMS;
} }
<DYNARE_STATEMENT>eq_cms {return token::EQ_CMS;} <DYNARE_STATEMENT>eq_cms {return token::EQ_CMS;}
<DYNARE_STATEMENT>tlindx {return token::TLINDX;} <DYNARE_STATEMENT>tlindx {return token::TLINDX;}
<DYNARE_STATEMENT>tlnumber {return token::TLNUMBER;} <DYNARE_STATEMENT>tlnumber {return token::TLNUMBER;}
<DYNARE_STATEMENT>cnum { <DYNARE_STATEMENT>cnum {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::CNUM; return token::CNUM;
} }
<DYNARE_STATEMENT>nodecomposition {return token::NODECOMPOSITION;}; <DYNARE_STATEMENT>nodecomposition {return token::NODECOMPOSITION;};
...@@ -616,18 +605,9 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -616,18 +605,9 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>substitute_libs {return token::SUBSTITUTE_LIBS;} <DYNARE_STATEMENT>substitute_libs {return token::SUBSTITUTE_LIBS;}
<DYNARE_STATEMENT>compiler {return token::COMPILER;} <DYNARE_STATEMENT>compiler {return token::COMPILER;}
<DYNARE_STATEMENT>instruments {return token::INSTRUMENTS;} <DYNARE_STATEMENT>instruments {return token::INSTRUMENTS;}
<DYNARE_STATEMENT>hessian { <DYNARE_STATEMENT>hessian {return token::HESSIAN;}
yylval->build<string>(yytext); <DYNARE_STATEMENT>prior_variance {return token::PRIOR_VARIANCE;}
return token::HESSIAN; <DYNARE_STATEMENT>identity_matrix {return token::IDENTITY_MATRIX;}
}
<DYNARE_STATEMENT>prior_variance {
yylval->build<string>(yytext);
return token::PRIOR_VARIANCE;
}
<DYNARE_STATEMENT>identity_matrix {
yylval->build<string>(yytext);
return token::IDENTITY_MATRIX;
}
<DYNARE_STATEMENT>mcmc_jumping_covariance {return token::MCMC_JUMPING_COVARIANCE;} <DYNARE_STATEMENT>mcmc_jumping_covariance {return token::MCMC_JUMPING_COVARIANCE;}
/* These four (var, varexo, varexo_det, parameters) are for change_type */ /* These four (var, varexo, varexo_det, parameters) are for change_type */
...@@ -727,14 +707,6 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -727,14 +707,6 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>lmmcp {return token::LMMCP;} <DYNARE_STATEMENT>lmmcp {return token::LMMCP;}
<DYNARE_STATEMENT>additional_optimizer_steps {return token::ADDITIONAL_OPTIMIZER_STEPS;} <DYNARE_STATEMENT>additional_optimizer_steps {return token::ADDITIONAL_OPTIMIZER_STEPS;}
<DYNARE_STATEMENT>bartlett_kernel_lag {return token::BARTLETT_KERNEL_LAG; } <DYNARE_STATEMENT>bartlett_kernel_lag {return token::BARTLETT_KERNEL_LAG; }
<DYNARE_STATEMENT>optimal {
yylval->build<string>(yytext);
return token::OPTIMAL;
}
<DYNARE_STATEMENT>diagonal {
yylval->build<string>(yytext);
return token::DIAGONAL;
}
<DYNARE_STATEMENT>gmm {return token::GMM;} <DYNARE_STATEMENT>gmm {return token::GMM;}
<DYNARE_STATEMENT>smm {return token::SMM;} <DYNARE_STATEMENT>smm {return token::SMM;}
<DYNARE_STATEMENT>irf_matching {return token::IRF_MATCHING;} <DYNARE_STATEMENT>irf_matching {return token::IRF_MATCHING;}
...@@ -778,10 +750,21 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -778,10 +750,21 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>with_epilogue {return token::WITH_EPILOGUE;} <DYNARE_STATEMENT>with_epilogue {return token::WITH_EPILOGUE;}
<DYNARE_STATEMENT>heteroskedastic_filter {return token::HETEROSKEDASTIC_FILTER;} <DYNARE_STATEMENT>heteroskedastic_filter {return token::HETEROSKEDASTIC_FILTER;}
<DYNARE_STATEMENT>non_zero {return token::NON_ZERO;} <DYNARE_STATEMENT>non_zero {return token::NON_ZERO;}
<DYNARE_STATEMENT>preconditioner {return token::PRECONDITIONER;}
<DYNARE_STATEMENT>umfiter {return token::UMFITER;}
<DYNARE_STATEMENT>iterstack {return token::ITERSTACK;}
<DYNARE_STATEMENT>ilu {return token::ILU;}
<DYNARE_STATEMENT>iter_tol {return token::ITER_TOL;}
<DYNARE_STATEMENT>iter_maxit {return token::ITER_MAXIT;}
<DYNARE_STATEMENT>gmres_restart {return token::GMRES_RESTART;}
<DYNARE_STATEMENT>iterstack_maxlu {return token::ITERSTACK_MAXLU;}
<DYNARE_STATEMENT>iterstack_nperiods {return token::ITERSTACK_NPERIODS;}
<DYNARE_STATEMENT>iterstack_nlu {return token::ITERSTACK_NLU;}
<DYNARE_STATEMENT>iterstack_relu {return token::ITERSTACK_RELU;}
<DYNARE_STATEMENT>check_jacobian_singularity {return token::CHECK_JACOBIAN_SINGULARITY;}
<DYNARE_STATEMENT>\$[^$]*\$ { <DYNARE_STATEMENT>\$[^$]*\$ {
strtok(yytext + 1, "$"); yylval->emplace<string>(yytext + 1).pop_back();
yylval->build<string>(yytext + 1);
return token::TEX_NAME; return token::TEX_NAME;
} }
...@@ -794,16 +777,16 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -794,16 +777,16 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_BLOCK>periods {return token::PERIODS;} <DYNARE_BLOCK>periods {return token::PERIODS;}
<DYNARE_BLOCK>scales {return token::SCALES;} <DYNARE_BLOCK>scales {return token::SCALES;}
<DYNARE_BLOCK>add { <DYNARE_BLOCK>add {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::ADD; return token::ADD;
} }
<DYNARE_BLOCK>multiply { <DYNARE_BLOCK>multiply {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::MULTIPLY; return token::MULTIPLY;
} }
<DYNARE_STATEMENT,DYNARE_BLOCK>cutoff {return token::CUTOFF;} <DYNARE_STATEMENT,DYNARE_BLOCK>cutoff {return token::CUTOFF;}
<DYNARE_STATEMENT,DYNARE_BLOCK>mfs { <DYNARE_STATEMENT,DYNARE_BLOCK>mfs {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::MFS; return token::MFS;
} }
<DYNARE_STATEMENT,DYNARE_BLOCK>static_mfs {return token::STATIC_MFS;} <DYNARE_STATEMENT,DYNARE_BLOCK>static_mfs {return token::STATIC_MFS;}
...@@ -820,19 +803,19 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -820,19 +803,19 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_BLOCK>dsge_prior_weight {return token::DSGE_PRIOR_WEIGHT;} <DYNARE_BLOCK>dsge_prior_weight {return token::DSGE_PRIOR_WEIGHT;}
<DYNARE_BLOCK>surprise {return token::SURPRISE;} <DYNARE_BLOCK>surprise {return token::SURPRISE;}
<DYNARE_BLOCK>bind { <DYNARE_BLOCK>bind {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::BIND; return token::BIND;
} }
<DYNARE_BLOCK>relax { <DYNARE_BLOCK>relax {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::RELAX; return token::RELAX;
} }
<DYNARE_BLOCK>error_bind { <DYNARE_BLOCK>error_bind {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::ERROR_BIND; return token::ERROR_BIND;
} }
<DYNARE_BLOCK>error_relax { <DYNARE_BLOCK>error_relax {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::ERROR_RELAX; return token::ERROR_RELAX;
} }
<DYNARE_BLOCK>relative_to_initval {return token::RELATIVE_TO_INITVAL;} <DYNARE_BLOCK>relative_to_initval {return token::RELATIVE_TO_INITVAL;}
...@@ -846,22 +829,24 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -846,22 +829,24 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_BLOCK,DYNARE_STATEMENT>auxname {return token::AUXNAME;} <DYNARE_BLOCK,DYNARE_STATEMENT>auxname {return token::AUXNAME;}
<DYNARE_BLOCK>auxname_target_nonstationary {return token::AUXNAME_TARGET_NONSTATIONARY;} <DYNARE_BLOCK>auxname_target_nonstationary {return token::AUXNAME_TARGET_NONSTATIONARY;}
<DYNARE_BLOCK,DYNARE_STATEMENT>kind { <DYNARE_BLOCK,DYNARE_STATEMENT>kind {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::KIND; return token::KIND;
} }
<DYNARE_BLOCK,DYNARE_STATEMENT>ll { <DYNARE_BLOCK,DYNARE_STATEMENT>ll {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::LL; return token::LL;
} }
<DYNARE_BLOCK,DYNARE_STATEMENT>dl { <DYNARE_BLOCK,DYNARE_STATEMENT>dl {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::DL; return token::DL;
} }
<DYNARE_BLOCK,DYNARE_STATEMENT>dd { <DYNARE_BLOCK,DYNARE_STATEMENT>dd {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::DD; return token::DD;
} }
<DYNARE_BLOCK>weights {return token::WEIGHTS;} <DYNARE_BLOCK>weights {return token::WEIGHTS;}
<DYNARE_BLOCK>exogenize {return token::EXOGENIZE;}
<DYNARE_BLOCK>endogenize {return token::ENDOGENIZE;}
/* Inside Dynare statement */ /* Inside Dynare statement */
<DYNARE_STATEMENT>solve_algo {return token::SOLVE_ALGO;} <DYNARE_STATEMENT>solve_algo {return token::SOLVE_ALGO;}
...@@ -873,7 +858,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -873,7 +858,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>order {return token::ORDER;} <DYNARE_STATEMENT>order {return token::ORDER;}
<DYNARE_STATEMENT>lyapunov {return token::LYAPUNOV;} <DYNARE_STATEMENT>lyapunov {return token::LYAPUNOV;}
<DYNARE_STATEMENT>dr { <DYNARE_STATEMENT>dr {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::DR; return token::DR;
} }
<DYNARE_STATEMENT>lyapunov_complex_threshold {return token::LYAPUNOV_COMPLEX_THRESHOLD;} <DYNARE_STATEMENT>lyapunov_complex_threshold {return token::LYAPUNOV_COMPLEX_THRESHOLD;}
...@@ -937,11 +922,11 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -937,11 +922,11 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>time_shift {return token::TIME_SHIFT;} <DYNARE_STATEMENT>time_shift {return token::TIME_SHIFT;}
<DYNARE_STATEMENT>structural {return token::STRUCTURAL;} <DYNARE_STATEMENT>structural {return token::STRUCTURAL;}
<DYNARE_STATEMENT>true { <DYNARE_STATEMENT>true {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::TRUE; return token::TRUE;
} }
<DYNARE_STATEMENT>false { <DYNARE_STATEMENT>false {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::FALSE; return token::FALSE;
} }
...@@ -1065,38 +1050,27 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -1065,38 +1050,27 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<DYNARE_STATEMENT>use_shock_groups {return token::USE_SHOCK_GROUPS;} <DYNARE_STATEMENT>use_shock_groups {return token::USE_SHOCK_GROUPS;}
<DYNARE_STATEMENT>colormap {return token::COLORMAP;} <DYNARE_STATEMENT>colormap {return token::COLORMAP;}
<DYNARE_STATEMENT,DYNARE_BLOCK>[a-z_][a-z0-9_]* { <DYNARE_STATEMENT,DYNARE_BLOCK>{NAME} {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::NAME; return token::NAME;
} }
<DYNARE_STATEMENT,DYNARE_BLOCK>((([0-9]*\.[0-9]+)|([0-9]+\.))([ed][-+]?[0-9]+)?)|([0-9]+[ed][-+]?[0-9]+) { <DYNARE_STATEMENT,DYNARE_BLOCK>{FLOAT_NUMBER} {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::FLOAT_NUMBER; return token::FLOAT_NUMBER;
} }
<DYNARE_STATEMENT,DYNARE_BLOCK>[0-9]+ { <DYNARE_STATEMENT,DYNARE_BLOCK>[0-9]+ {
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::INT_NUMBER; return token::INT_NUMBER;
} }
<DATES_STATEMENT>\( { yylval->as<string>().append(yytext); dates_parens_nb++; }
<DATES_STATEMENT>\) {
yylval->as<string>().append(yytext);
if (--dates_parens_nb == 0)
{
BEGIN DYNARE_STATEMENT;
return token::DATES;
}
}
<DATES_STATEMENT>. { yylval->as<string>().append(yytext); }
<DYNARE_BLOCK>\|e { return token::PIPE_E; } <DYNARE_BLOCK>\|e { return token::PIPE_E; }
<DYNARE_BLOCK>\|x { return token::PIPE_X; } <DYNARE_BLOCK>\|x { return token::PIPE_X; }
<DYNARE_BLOCK>\|p { return token::PIPE_P; } <DYNARE_BLOCK>\|p { return token::PIPE_P; }
<DYNARE_STATEMENT,DYNARE_BLOCK>\'[^\']*\' { <DYNARE_STATEMENT,DYNARE_BLOCK>\'[^\']*\' {
yylval->build<string>(yytext + 1).pop_back(); yylval->emplace<string>(yytext + 1).pop_back();
return token::QUOTED_STRING; return token::QUOTED_STRING;
} }
...@@ -1128,11 +1102,11 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -1128,11 +1102,11 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
element in initval (in which case Dynare recognizes the matrix name as an external element in initval (in which case Dynare recognizes the matrix name as an external
function symbol), and may want to modify the matrix later with Matlab statements. function symbol), and may want to modify the matrix later with Matlab statements.
*/ */
<INITIAL>[a-z_][a-z0-9_]* { <INITIAL>{NAME} {
if (driver.symbol_exists_and_is_not_modfile_local_or_external_function(yytext)) if (driver.symbol_exists_and_is_not_modfile_local_or_external_function(yytext))
{ {
BEGIN DYNARE_STATEMENT; BEGIN DYNARE_STATEMENT;
yylval->build<string>(yytext); yylval->emplace<string>(yytext);
return token::NAME; return token::NAME;
} }
else else
...@@ -1153,7 +1127,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -1153,7 +1127,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
be able to back out of the statement if we realize it's a native statement be able to back out of the statement if we realize it's a native statement
and move to the NATIVE context and move to the NATIVE context
*/ */
<INITIAL>\[([[:space:]]*[a-z_][a-z0-9_]*[[:space:]]*,{1}[[:space:]]*)*([[:space:]]*[a-z_][a-z0-9_]*[[:space:]]*){1}\] { <INITIAL>\[([[:space:]]*{NAME}[[:space:]]*,{1}[[:space:]]*)*([[:space:]]*{NAME}[[:space:]]*){1}\] {
string yytextcpy{yytext}; string yytextcpy{yytext};
yytextcpy.erase(remove(yytextcpy.begin(), yytextcpy.end(), '['), yytextcpy.end()); yytextcpy.erase(remove(yytextcpy.begin(), yytextcpy.end(), '['), yytextcpy.end());
yytextcpy.erase(remove(yytextcpy.begin(), yytextcpy.end(), ']'), yytextcpy.end()); yytextcpy.erase(remove(yytextcpy.begin(), yytextcpy.end(), ']'), yytextcpy.end());
...@@ -1177,7 +1151,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -1177,7 +1151,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
if (dynare_statement) if (dynare_statement)
{ {
BEGIN DYNARE_STATEMENT; BEGIN DYNARE_STATEMENT;
yylval->build<vector<string>>(val); yylval->emplace<vector<string>>(val);
return token::SYMBOL_VEC; return token::SYMBOL_VEC;
} }
} }
...@@ -1222,7 +1196,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]) ...@@ -1222,7 +1196,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
<NATIVE_COMMENT>"*/"[[:space:]]*\n { BEGIN NATIVE; } <NATIVE_COMMENT>"*/"[[:space:]]*\n { BEGIN NATIVE; }
<NATIVE_COMMENT>. <NATIVE_COMMENT>.
<INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,COMMENT,DATES_STATEMENT,LINE1,LINE2,LINE3,NATIVE_COMMENT><<EOF>> { yyterminate(); } <INITIAL,DYNARE_STATEMENT,DYNARE_BLOCK,COMMENT,LINE1,LINE2,LINE3,NATIVE_COMMENT><<EOF>> { yyterminate(); }
<*>. { driver.error(*yylloc, "character unrecognized by lexer"); } <*>. { driver.error(*yylloc, "character unrecognized by lexer"); }
%% %%
......
...@@ -56,7 +56,7 @@ usage() ...@@ -56,7 +56,7 @@ usage()
"[conffile=path_to_config_file] [parallel_follower_open_mode] " "[conffile=path_to_config_file] [parallel_follower_open_mode] "
"[parallel_test] [parallel_use_psexec=true|false]" "[parallel_test] [parallel_use_psexec=true|false]"
<< " [-D<variable>[=<value>]] [-I/path] [nostrict] [stochastic] [fast] [minimal_workspace] " << " [-D<variable>[=<value>]] [-I/path] [nostrict] [stochastic] [fast] [minimal_workspace] "
"[compute_xrefs] [output=second|third] [language=matlab|julia]" "[compute_xrefs] [output=first|second|third] [language=matlab|julia]"
<< " [params_derivs_order=0|1|2] [transform_unary_ops] " << " [params_derivs_order=0|1|2] [transform_unary_ops] "
"[exclude_eqs=<equation_tag_list_or_file>] [include_eqs=<equation_tag_list_or_file>]" "[exclude_eqs=<equation_tag_list_or_file>] [include_eqs=<equation_tag_list_or_file>]"
<< " [json=parse|check|transform|compute] [jsonstdout] [onlyjson] [jsonderivsimple] " << " [json=parse|check|transform|compute] [jsonstdout] [onlyjson] [jsonderivsimple] "
...@@ -320,7 +320,9 @@ main(int argc, char** argv) ...@@ -320,7 +320,9 @@ main(int argc, char** argv)
s.erase(0, 7); s.erase(0, 7);
if (s == "second") if (s == "first")
output_mode = OutputType::first;
else if (s == "second")
output_mode = OutputType::second; output_mode = OutputType::second;
else if (s == "third") else if (s == "third")
output_mode = OutputType::third; output_mode = OutputType::third;
......
/* /*
* Copyright © 2020-2023 Dynare Team * Copyright © 2020-2025 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -74,13 +74,12 @@ EquationTags::erase(const set<int>& eqns, const map<int, int>& old_eqn_num_2_new ...@@ -74,13 +74,12 @@ EquationTags::erase(const set<int>& eqns, const map<int, int>& old_eqn_num_2_new
eqn_tags.erase(eqn); eqn_tags.erase(eqn);
for (const auto& [oldeqn, neweqn] : old_eqn_num_2_new) for (const auto& [oldeqn, neweqn] : old_eqn_num_2_new)
for (auto& [eqn, tags] : eqn_tags) if (eqn_tags.contains(oldeqn))
if (eqn == oldeqn) {
{ auto tmp = eqn_tags.extract(oldeqn);
auto tmp = eqn_tags.extract(eqn); tmp.key() = neweqn;
tmp.key() = neweqn; eqn_tags.insert(move(tmp));
eqn_tags.insert(move(tmp)); }
}
} }
void void
......
/* /*
* Copyright © 2007-2024 Dynare Team * Copyright © 2007-2025 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -429,7 +429,7 @@ ExprNode::fillErrorCorrectionRow(int eqn, const vector<int>& nontarget_lhs, ...@@ -429,7 +429,7 @@ ExprNode::fillErrorCorrectionRow(int eqn, const vector<int>& nontarget_lhs,
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
int colidx = static_cast<int>( int colidx = static_cast<int>(
distance(nontarget_lhs.begin(), ranges::find(nontarget_lhs, orig_vid))); ranges::distance(nontarget_lhs.begin(), ranges::find(nontarget_lhs, orig_vid)));
if (A0.contains({eqn, colidx})) if (A0.contains({eqn, colidx}))
{ {
cerr << "ExprNode::fillErrorCorrection: Error filling A0 matrix: " cerr << "ExprNode::fillErrorCorrection: Error filling A0 matrix: "
...@@ -442,7 +442,7 @@ ExprNode::fillErrorCorrectionRow(int eqn, const vector<int>& nontarget_lhs, ...@@ -442,7 +442,7 @@ ExprNode::fillErrorCorrectionRow(int eqn, const vector<int>& nontarget_lhs,
{ {
// This is a target, so fill A0star // This is a target, so fill A0star
int colidx = static_cast<int>( int colidx = static_cast<int>(
distance(target_lhs.begin(), ranges::find(target_lhs, orig_vid))); ranges::distance(target_lhs.begin(), ranges::find(target_lhs, orig_vid)));
expr_t e = datatree.AddTimes(datatree.AddVariable(speed_of_adjustment_param), expr_t e = datatree.AddTimes(datatree.AddVariable(speed_of_adjustment_param),
datatree.AddPossiblyNegativeConstant(-constant)); datatree.AddPossiblyNegativeConstant(-constant));
if (param_id) if (param_id)
...@@ -908,6 +908,7 @@ VariableNode::prepareForDerivation() ...@@ -908,6 +908,7 @@ VariableNode::prepareForDerivation()
case SymbolType::endogenous: case SymbolType::endogenous:
case SymbolType::parameter: case SymbolType::parameter:
case SymbolType::heterogeneousEndogenous: case SymbolType::heterogeneousEndogenous:
case SymbolType::heterogeneousExogenous:
non_null_derivatives.insert(getDerivID()); non_null_derivatives.insert(getDerivID());
break; break;
case SymbolType::modelLocalVariable: case SymbolType::modelLocalVariable:
...@@ -915,7 +916,6 @@ VariableNode::prepareForDerivation() ...@@ -915,7 +916,6 @@ VariableNode::prepareForDerivation()
// Non null derivatives are those of the value of the local parameter // Non null derivatives are those of the value of the local parameter
non_null_derivatives = datatree.getLocalVariable(symb_id, lag)->non_null_derivatives; non_null_derivatives = datatree.getLocalVariable(symb_id, lag)->non_null_derivatives;
break; break;
case SymbolType::heterogeneousExogenous:
case SymbolType::heterogeneousParameter: case SymbolType::heterogeneousParameter:
case SymbolType::modFileLocalVariable: case SymbolType::modFileLocalVariable:
case SymbolType::statementDeclaredVariable: case SymbolType::statementDeclaredVariable:
...@@ -1004,11 +1004,11 @@ VariableNode::computeDerivative(int deriv_id) ...@@ -1004,11 +1004,11 @@ VariableNode::computeDerivative(int deriv_id)
case SymbolType::endogenous: case SymbolType::endogenous:
case SymbolType::parameter: case SymbolType::parameter:
case SymbolType::heterogeneousEndogenous: case SymbolType::heterogeneousEndogenous:
case SymbolType::heterogeneousExogenous:
if (deriv_id == getDerivID()) if (deriv_id == getDerivID())
return datatree.One; return datatree.One;
else else
return datatree.Zero; return datatree.Zero;
case SymbolType::heterogeneousExogenous:
case SymbolType::heterogeneousParameter: case SymbolType::heterogeneousParameter:
return datatree.Zero; return datatree.Zero;
case SymbolType::modelLocalVariable: case SymbolType::modelLocalVariable:
...@@ -2978,10 +2978,8 @@ UnaryOpNode::writeJsonOutput(ostream& output, const temporary_terms_t& temporary ...@@ -2978,10 +2978,8 @@ UnaryOpNode::writeJsonOutput(ostream& output, const temporary_terms_t& temporary
output << "])"; output << "])";
return; return;
case UnaryOpcode::steadyState: case UnaryOpcode::steadyState:
output << "("; output << "STEADY_STATE";
arg->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic); break;
output << ")";
return;
case UnaryOpcode::steadyStateParamDeriv: case UnaryOpcode::steadyStateParamDeriv:
{ {
auto varg = dynamic_cast<VariableNode*>(arg); auto varg = dynamic_cast<VariableNode*>(arg);
...@@ -6458,9 +6456,9 @@ TrinaryOpNode::eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v ...@@ -6458,9 +6456,9 @@ TrinaryOpNode::eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v
switch (op_code) switch (op_code)
{ {
case TrinaryOpcode::normcdf: case TrinaryOpcode::normcdf:
return (0.5 * (1 + erf((v1 - v2) / v3 / numbers::sqrt2))); return 0.5 * (1 + erf((v1 - v2) / v3 / numbers::sqrt2));
case TrinaryOpcode::normpdf: case TrinaryOpcode::normpdf:
return (1 / (v3 * sqrt(2 * numbers::pi) * exp(pow((v1 - v2) / v3, 2) / 2))); return 1 / (v3 * sqrt(2 * numbers::pi) * exp(pow((v1 - v2) / v3, 2) / 2));
} }
__builtin_unreachable(); // Silence GCC warning __builtin_unreachable(); // Silence GCC warning
} }
...@@ -6989,9 +6987,9 @@ TrinaryOpNode::isVariableNodeEqualTo([[maybe_unused]] SymbolType type_arg, ...@@ -6989,9 +6987,9 @@ TrinaryOpNode::isVariableNodeEqualTo([[maybe_unused]] SymbolType type_arg,
bool bool
TrinaryOpNode::containsPacExpectation(const string& pac_model_name) const TrinaryOpNode::containsPacExpectation(const string& pac_model_name) const
{ {
return (arg1->containsPacExpectation(pac_model_name) return arg1->containsPacExpectation(pac_model_name)
|| arg2->containsPacExpectation(pac_model_name) || arg2->containsPacExpectation(pac_model_name)
|| arg3->containsPacExpectation(pac_model_name)); || arg3->containsPacExpectation(pac_model_name);
} }
bool bool
...@@ -7907,7 +7905,7 @@ ExternalFunctionNode::sameTefTermPredicate() const ...@@ -7907,7 +7905,7 @@ ExternalFunctionNode::sameTefTermPredicate() const
{ {
return [this](expr_t e) { return [this](expr_t e) {
auto e2 = dynamic_cast<ExternalFunctionNode*>(e); auto e2 = dynamic_cast<ExternalFunctionNode*>(e);
return (e2 != nullptr && e2->symb_id == symb_id && e2->arguments == arguments); return e2 != nullptr && e2->symb_id == symb_id && e2->arguments == arguments;
}; };
} }
...@@ -8245,12 +8243,12 @@ FirstDerivExternalFunctionNode::sameTefTermPredicate() const ...@@ -8245,12 +8243,12 @@ FirstDerivExternalFunctionNode::sameTefTermPredicate() const
if (first_deriv_symb_id == symb_id) if (first_deriv_symb_id == symb_id)
return [this](expr_t e) { return [this](expr_t e) {
auto e2 = dynamic_cast<ExternalFunctionNode*>(e); auto e2 = dynamic_cast<ExternalFunctionNode*>(e);
return (e2 && e2->symb_id == symb_id && e2->arguments == arguments); return e2 && e2->symb_id == symb_id && e2->arguments == arguments;
}; };
else else
return [this](expr_t e) { return [this](expr_t e) {
auto e2 = dynamic_cast<FirstDerivExternalFunctionNode*>(e); auto e2 = dynamic_cast<FirstDerivExternalFunctionNode*>(e);
return (e2 && e2->symb_id == symb_id && e2->arguments == arguments); return e2 && e2->symb_id == symb_id && e2->arguments == arguments;
}; };
} }
...@@ -8600,12 +8598,12 @@ SecondDerivExternalFunctionNode::sameTefTermPredicate() const ...@@ -8600,12 +8598,12 @@ SecondDerivExternalFunctionNode::sameTefTermPredicate() const
if (second_deriv_symb_id == symb_id) if (second_deriv_symb_id == symb_id)
return [this](expr_t e) { return [this](expr_t e) {
auto e2 = dynamic_cast<ExternalFunctionNode*>(e); auto e2 = dynamic_cast<ExternalFunctionNode*>(e);
return (e2 && e2->symb_id == symb_id && e2->arguments == arguments); return e2 && e2->symb_id == symb_id && e2->arguments == arguments;
}; };
else else
return [this](expr_t e) { return [this](expr_t e) {
auto e2 = dynamic_cast<SecondDerivExternalFunctionNode*>(e); auto e2 = dynamic_cast<SecondDerivExternalFunctionNode*>(e);
return (e2 && e2->symb_id == symb_id && e2->arguments == arguments); return e2 && e2->symb_id == symb_id && e2->arguments == arguments;
}; };
} }
...@@ -9491,9 +9489,9 @@ ExprNode::matchParamTimesTargetMinusVariable(int symb_id) const ...@@ -9491,9 +9489,9 @@ ExprNode::matchParamTimesTargetMinusVariable(int symb_id) const
auto& avi = datatree.symbol_table.getAuxVarInfo(target->symb_id); auto& avi = datatree.symbol_table.getAuxVarInfo(target->symb_id);
if (avi.type == AuxVarType::pacTargetNonstationary && target->lag == -1) if (avi.type == AuxVarType::pacTargetNonstationary && target->lag == -1)
return true; return true;
return (avi.type == AuxVarType::unaryOp && avi.unary_op == "log" && avi.orig_symb_id return avi.type == AuxVarType::unaryOp && avi.unary_op == "log" && avi.orig_symb_id
&& !datatree.symbol_table.isAuxiliaryVariable(*avi.orig_symb_id) && !datatree.symbol_table.isAuxiliaryVariable(*avi.orig_symb_id)
&& target->lag + avi.orig_lead_lag.value() == -1); && target->lag + avi.orig_lead_lag.value() == -1;
} }
else else
return target->lag == -1; return target->lag == -1;
...@@ -9572,13 +9570,14 @@ ExprNode::toString() const ...@@ -9572,13 +9570,14 @@ ExprNode::toString() const
} }
tuple<int, expr_t, expr_t> tuple<int, expr_t, expr_t>
ExprNode::matchComplementarityCondition() const ExprNode::matchComplementarityCondition(
[[maybe_unused]] const optional<int>& heterogeneity_dimension) const
{ {
throw MatchFailureException {"This expression is not an inequality"}; throw MatchFailureException {"This expression is not an inequality"};
} }
tuple<int, expr_t, expr_t> tuple<int, expr_t, expr_t>
BinaryOpNode::matchComplementarityCondition() const BinaryOpNode::matchComplementarityCondition(const optional<int>& heterogeneity_dimension) const
{ {
bool is_greater {[&] { bool is_greater {[&] {
switch (op_code) switch (op_code)
...@@ -9596,7 +9595,13 @@ BinaryOpNode::matchComplementarityCondition() const ...@@ -9596,7 +9595,13 @@ BinaryOpNode::matchComplementarityCondition() const
auto match_contemporaneous_endogenous = [&](expr_t e) -> optional<int> { auto match_contemporaneous_endogenous = [&](expr_t e) -> optional<int> {
auto* ve = dynamic_cast<VariableNode*>(e); auto* ve = dynamic_cast<VariableNode*>(e);
if (ve && ve->lag == 0 && datatree.symbol_table.getType(ve->symb_id) == SymbolType::endogenous) if (ve && ve->lag == 0
&& ((!heterogeneity_dimension
&& datatree.symbol_table.getType(ve->symb_id) == SymbolType::endogenous)
|| (heterogeneity_dimension
&& datatree.symbol_table.getType(ve->symb_id) == SymbolType::heterogeneousEndogenous
&& datatree.symbol_table.getHeterogeneityDimension(ve->symb_id)
== *heterogeneity_dimension)))
return ve->symb_id; return ve->symb_id;
else else
return nullopt; return nullopt;
...@@ -9633,11 +9638,11 @@ BinaryOpNode::matchComplementarityCondition() const ...@@ -9633,11 +9638,11 @@ BinaryOpNode::matchComplementarityCondition() const
|| (!is_greater || (!is_greater
&& (barg1->op_code == BinaryOpcode::less && (barg1->op_code == BinaryOpcode::less
|| barg1->op_code == BinaryOpcode::lessEqual))))) || barg1->op_code == BinaryOpcode::lessEqual)))))
throw MatchFailureException {"Complementarity condition does not have the right form"}; throw MatchFailureException {};
auto id = match_contemporaneous_endogenous(barg1->arg2); auto id = match_contemporaneous_endogenous(barg1->arg2);
if (!id) if (!id)
throw MatchFailureException {"Complementarity condition does not have the right form"}; throw MatchFailureException {};
check_bound_constant(barg1->arg1); check_bound_constant(barg1->arg1);
check_bound_constant(arg2); check_bound_constant(arg2);
......
/* /*
* Copyright © 2007-2024 Dynare Team * Copyright © 2007-2025 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -283,7 +283,7 @@ protected: ...@@ -283,7 +283,7 @@ protected:
min_cost(bool is_matlab) min_cost(bool is_matlab)
{ {
return is_matlab ? min_cost_matlab : min_cost_c; return is_matlab ? min_cost_matlab : min_cost_c;
}; }
//! Initializes data member non_null_derivatives //! Initializes data member non_null_derivatives
virtual void prepareForDerivation() = 0; virtual void prepareForDerivation() = 0;
...@@ -943,7 +943,8 @@ public: ...@@ -943,7 +943,8 @@ public:
/* Matches an expression that constitutes a complementarity condition. /* Matches an expression that constitutes a complementarity condition.
If successful, returns a triplet (endo_symb_id, lower_bound, upper_bound). If successful, returns a triplet (endo_symb_id, lower_bound, upper_bound).
Otherwise, throws a MatchFailureException. */ Otherwise, throws a MatchFailureException. */
[[nodiscard]] virtual tuple<int, expr_t, expr_t> matchComplementarityCondition() const; [[nodiscard]] virtual tuple<int, expr_t, expr_t>
matchComplementarityCondition(const optional<int>& heterogeneity_dimension = nullopt) const;
/* Replaces aggregation operators (e.g. SUM()) by new auxiliary variables. /* Replaces aggregation operators (e.g. SUM()) by new auxiliary variables.
Also declares those aggregation operators in the HeterogeneityTable, so as to Also declares those aggregation operators in the HeterogeneityTable, so as to
...@@ -1519,7 +1520,9 @@ public: ...@@ -1519,7 +1520,9 @@ public:
[[nodiscard]] expr_t substituteLogTransform(int orig_symb_id, int aux_symb_id) const override; [[nodiscard]] expr_t substituteLogTransform(int orig_symb_id, int aux_symb_id) const override;
[[nodiscard]] expr_t substituteAggregationOperators(subst_table_t& subst_table, [[nodiscard]] expr_t substituteAggregationOperators(subst_table_t& subst_table,
vector<BinaryOpNode*>& neweqs) const override; vector<BinaryOpNode*>& neweqs) const override;
[[nodiscard]] tuple<int, expr_t, expr_t> matchComplementarityCondition() const override; [[nodiscard]] tuple<int, expr_t, expr_t>
matchComplementarityCondition(const optional<int>& heterogeneity_dimension
= nullopt) const override;
}; };
//! Trinary operator node //! Trinary operator node
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
enum class OutputType enum class OutputType
{ {
standard, // Default value, infer the derivation order from .mod file only standard, // Default value, infer the derivation order from .mod file only
first, // Output only 1st dynamic derivatives with no other computations
second, // Output at least 2nd dynamic derivatives second, // Output at least 2nd dynamic derivatives
third, // Output at least 3rd dynamic derivatives third, // Output at least 3rd dynamic derivatives
}; };
......
...@@ -90,7 +90,7 @@ public: ...@@ -90,7 +90,7 @@ public:
}; };
void addSummedHeterogeneousEndogenous(int symb_id); void addSummedHeterogeneousEndogenous(int symb_id);
int getSummedHeterogenousEndogenousIndex(int symb_id) const; [[nodiscard]] int getSummedHeterogenousEndogenousIndex(int symb_id) const;
[[nodiscard]] int aggregateEndoSize() const; [[nodiscard]] int aggregateEndoSize() const;
void writeOutput(ostream& output) const; void writeOutput(ostream& output) const;
......
/* /*
* Copyright © 2024 Dynare Team * Copyright © 2024-2025 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -33,14 +33,6 @@ HeterogeneousModel::HeterogeneousModel(SymbolTable& symbol_table_arg, ...@@ -33,14 +33,6 @@ HeterogeneousModel::HeterogeneousModel(SymbolTable& symbol_table_arg,
{ {
} }
HeterogeneousModel::HeterogeneousModel(const HeterogeneousModel& m) :
ModelTree {m},
heterogeneity_dimension {m.heterogeneity_dimension},
deriv_id_table {m.deriv_id_table},
inv_deriv_id_table {m.inv_deriv_id_table}
{
}
HeterogeneousModel& HeterogeneousModel&
HeterogeneousModel::operator=(const HeterogeneousModel& m) HeterogeneousModel::operator=(const HeterogeneousModel& m)
{ {
...@@ -123,14 +115,7 @@ HeterogeneousModel::computingPass(int derivsOrder, bool no_tmp_terms, bool use_d ...@@ -123,14 +115,7 @@ HeterogeneousModel::computingPass(int derivsOrder, bool no_tmp_terms, bool use_d
computeTemporaryTerms(!use_dll, no_tmp_terms); computeTemporaryTerms(!use_dll, no_tmp_terms);
if (ranges::any_of(complementarity_conditions, [](const auto& x) { return x.has_value(); })) computeMCPEquationsReordering(heterogeneity_dimension);
{
// Implementing it requires modifications in ModelTree::computeMCPEquationsReordering()
cerr << "ERROR: Complementarity conditions are not yet implemented in "
"model(heterogeneity=...) blocks"
<< endl;
exit(EXIT_FAILURE);
}
} }
void void
...@@ -138,6 +123,7 @@ HeterogeneousModel::writeModelFiles(const string& basename, bool julia) const ...@@ -138,6 +123,7 @@ HeterogeneousModel::writeModelFiles(const string& basename, bool julia) const
{ {
assert(!julia); // Not yet implemented assert(!julia); // Not yet implemented
writeSparseModelMFiles<true>(basename, heterogeneity_dimension); writeSparseModelMFiles<true>(basename, heterogeneity_dimension);
writeComplementarityConditionsFile<true>(basename, heterogeneity_dimension);
} }
int int
...@@ -245,4 +231,9 @@ HeterogeneousModel::writeDriverOutput(ostream& output) const ...@@ -245,4 +231,9 @@ HeterogeneousModel::writeDriverOutput(ostream& output) const
output << "];" << endl; output << "];" << endl;
writeDriverSparseIndicesHelper( writeDriverSparseIndicesHelper(
"heterogeneity("s + to_string(heterogeneity_dimension + 1) + ").dynamic", output); "heterogeneity("s + to_string(heterogeneity_dimension + 1) + ").dynamic", output);
output << "M_.heterogeneity(" << heterogeneity_dimension + 1
<< ").dynamic_mcp_equations_reordering = [";
for (auto i : mcp_equations_reordering)
output << i + 1 << "; ";
output << "];" << endl;
} }
...@@ -35,7 +35,7 @@ public: ...@@ -35,7 +35,7 @@ public:
ExternalFunctionsTable& external_functions_table_arg, ExternalFunctionsTable& external_functions_table_arg,
HeterogeneityTable& heterogeneity_table_arg, int heterogeneity_dimension_arg); HeterogeneityTable& heterogeneity_table_arg, int heterogeneity_dimension_arg);
HeterogeneousModel(const HeterogeneousModel& m); HeterogeneousModel(const HeterogeneousModel& m) = default;
HeterogeneousModel& operator=(const HeterogeneousModel& m); HeterogeneousModel& operator=(const HeterogeneousModel& m);
void computingPass(int derivsOrder, bool no_tmp_terms, bool use_dll); void computingPass(int derivsOrder, bool no_tmp_terms, bool use_dll);
......
/* /*
* Copyright © 2006-2024 Dynare Team * Copyright © 2006-2025 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
...@@ -960,8 +960,22 @@ ModFile::computingPass(bool no_tmp_terms, OutputType output, int params_derivs_o ...@@ -960,8 +960,22 @@ ModFile::computingPass(bool no_tmp_terms, OutputType output, int params_derivs_o
no_tmp_terms, block, use_dll); no_tmp_terms, block, use_dll);
} }
} }
else // No computing task requested, compute derivatives up to 2nd order by default else // No computing task requested, compute derivatives up to 2nd order by default unless
dynamic_model.computingPass(2, 0, global_eval_context, no_tmp_terms, block, use_dll); // output=first (preprocessor#100) or third (preprocessor#121) is requested
{
switch (output)
{
case OutputType::first:
dynamic_model.computingPass(1, 0, global_eval_context, no_tmp_terms, block, use_dll);
break;
case OutputType::third:
dynamic_model.computingPass(3, 0, global_eval_context, no_tmp_terms, block, use_dll);
break;
default:
dynamic_model.computingPass(2, 0, global_eval_context, no_tmp_terms, block, use_dll);
break;
}
}
if (linear) if (linear)
{ {
...@@ -1137,7 +1151,8 @@ ModFile::writeMOutput(const string& basename, bool clear_all, bool clear_global, ...@@ -1137,7 +1151,8 @@ ModFile::writeMOutput(const string& basename, bool clear_all, bool clear_global,
<< "M_.heteroskedastic_shocks.Qvalue_orig = [];" << endl << "M_.heteroskedastic_shocks.Qvalue_orig = [];" << endl
<< "M_.heteroskedastic_shocks.Qscale_orig = [];" << endl << "M_.heteroskedastic_shocks.Qscale_orig = [];" << endl
<< "M_.matched_irfs = {};" << endl << "M_.matched_irfs = {};" << endl
<< "M_.matched_irfs_weights = {};" << endl; << "M_.matched_irfs_weights = {};" << endl
<< "M_.perfect_foresight_controlled_paths = [];" << endl;
// NB: options_.{ramsey,discretionary}_policy should rather be fields of M_ // NB: options_.{ramsey,discretionary}_policy should rather be fields of M_
mOutputFile << boolalpha << "options_.linear = " << linear << ";" << endl mOutputFile << boolalpha << "options_.linear = " << linear << ";" << endl
...@@ -1311,8 +1326,8 @@ ModFile::writeMOutput(const string& basename, bool clear_all, bool clear_global, ...@@ -1311,8 +1326,8 @@ ModFile::writeMOutput(const string& basename, bool clear_all, bool clear_global,
if (!no_warn) if (!no_warn)
{ {
if (warnings.countWarnings() > 0) if (int num_warnings {warnings.numWarnings()}; num_warnings > 0)
mOutputFile << "disp('Note: " << warnings.countWarnings() mOutputFile << "disp('Note: " << num_warnings
<< " warning(s) encountered in the preprocessor')" << endl; << " warning(s) encountered in the preprocessor')" << endl;
mOutputFile << "if ~isempty(lastwarn)" << endl mOutputFile << "if ~isempty(lastwarn)" << endl
......