Refactor parsing of equation tags in a more functional way
Incidentally, makes tag names case-insensitive in “model_replace” and “model_remove”, which is consistent with tag declarations.master
parent
ac35ef6101
commit
1ad7dd9672
|
@ -3425,12 +3425,12 @@ DynamicModel::fillEvalContext(eval_context_t &eval_context) const
|
|||
}
|
||||
|
||||
void
|
||||
DynamicModel::addStaticOnlyEquation(expr_t eq, optional<int> lineno, const map<string, string> &eq_tags)
|
||||
DynamicModel::addStaticOnlyEquation(expr_t eq, optional<int> lineno, map<string, string> eq_tags)
|
||||
{
|
||||
auto beq = dynamic_cast<BinaryOpNode *>(eq);
|
||||
assert(beq && beq->op_code == BinaryOpcode::equal);
|
||||
|
||||
static_only_equations_equation_tags.add(static_only_equations.size(), eq_tags);
|
||||
static_only_equations_equation_tags.add(static_only_equations.size(), move(eq_tags));
|
||||
static_only_equations.push_back(beq);
|
||||
static_only_equations_lineno.push_back(move(lineno));
|
||||
}
|
||||
|
@ -3448,7 +3448,7 @@ DynamicModel::dynamicOnlyEquationsNbr() const
|
|||
}
|
||||
|
||||
void
|
||||
DynamicModel::addOccbinEquation(expr_t eq, optional<int> lineno, const map<string, string> &eq_tags, const vector<string> ®imes_bind, const vector<string> ®imes_relax)
|
||||
DynamicModel::addOccbinEquation(expr_t eq, optional<int> lineno, map<string, string> eq_tags, const vector<string> ®imes_bind, const vector<string> ®imes_relax)
|
||||
{
|
||||
auto beq = dynamic_cast<BinaryOpNode *>(eq);
|
||||
assert(beq && beq->op_code == BinaryOpcode::equal);
|
||||
|
@ -3501,9 +3501,8 @@ DynamicModel::addOccbinEquation(expr_t eq, optional<int> lineno, const map<strin
|
|||
}
|
||||
else
|
||||
{
|
||||
auto eq_tags_static = eq_tags;
|
||||
eq_tags_static["static"] = "";
|
||||
addStaticOnlyEquation(AddEqual(basic_term, Zero), lineno, eq_tags_static);
|
||||
eq_tags["static"] = "";
|
||||
addStaticOnlyEquation(AddEqual(basic_term, Zero), lineno, move(eq_tags));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -417,7 +417,7 @@ public:
|
|||
void replaceMyEquations(DynamicModel &dynamic_model) const;
|
||||
|
||||
//! Adds an equation marked as [static]
|
||||
void addStaticOnlyEquation(expr_t eq, optional<int> lineno, const map<string, string> &eq_tags);
|
||||
void addStaticOnlyEquation(expr_t eq, optional<int> lineno, map<string, string> eq_tags);
|
||||
|
||||
//! Returns number of static only equations
|
||||
size_t staticOnlyEquationsNbr() const;
|
||||
|
@ -430,7 +430,7 @@ public:
|
|||
auxiliary parameters have already been added to the symbol table.
|
||||
It also assumes that the “bind” and “relax” tags have been cleared from
|
||||
eq_tags. */
|
||||
void addOccbinEquation(expr_t eq, optional<int> lineno, const map<string, string> &eq_tags, const vector<string> ®imes_bind, const vector<string> ®imes_relax);
|
||||
void addOccbinEquation(expr_t eq, optional<int> lineno, map<string, string> eq_tags, const vector<string> ®imes_bind, const vector<string> ®imes_relax);
|
||||
|
||||
//! Writes LaTeX file with the equations of the dynamic model
|
||||
void writeLatexFile(const string &basename, bool write_equation_tags) const;
|
||||
|
|
|
@ -78,6 +78,16 @@ class ParsingDriver;
|
|||
* current lexer object of the driver context. */
|
||||
#undef yylex
|
||||
#define yylex driver.lexer->lex
|
||||
|
||||
#include <cctype>
|
||||
|
||||
string
|
||||
str_tolower(string s)
|
||||
{
|
||||
// Converting to unsigned char is needed, see https://en.cppreference.com/w/cpp/string/byte/tolower
|
||||
transform(s.begin(), s.end(), s.begin(), [](unsigned char c){ return std::tolower(c); });
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
%token AIM_SOLVER ANALYTIC_DERIVATION ANALYTIC_DERIVATION_MODE AR POSTERIOR_SAMPLING_METHOD
|
||||
|
@ -224,8 +234,9 @@ class ParsingDriver;
|
|||
%type <vector<int>> vec_int_elem vec_int_1 vec_int vec_int_number
|
||||
%type <PriorDistributions> prior_pdf prior_distribution
|
||||
%type <pair<expr_t,expr_t>> calibration_range
|
||||
%type <pair<string,string>> partition_elem subsamples_eq_opt integer_range_w_inf
|
||||
%type <pair<string,string>> partition_elem subsamples_eq_opt integer_range_w_inf tag_pair
|
||||
%type <vector<pair<string,string>>> partition partition_1 tag_pair_list_for_selection symbol_list_with_tex
|
||||
%type <map<string, string>> tag_pair_list
|
||||
%type <tuple<string,string,string,string>> prior_eq_opt options_eq_opt
|
||||
%type <vector<pair<int, int>>> period_list
|
||||
%type <vector<expr_t>> matched_moments_list value_list
|
||||
|
@ -982,23 +993,30 @@ equation_list : equation_list equation
|
|||
;
|
||||
|
||||
equation : hand_side EQUAL hand_side ';'
|
||||
{ $$ = driver.add_model_equal($1, $3); }
|
||||
{ $$ = driver.add_model_equal($1, $3, {}); }
|
||||
| hand_side ';'
|
||||
{ $$ = driver.add_model_equal_with_zero_rhs($1); }
|
||||
| '[' tags_list ']' hand_side EQUAL hand_side ';'
|
||||
{ $$ = driver.add_model_equal($4, $6); }
|
||||
| '[' tags_list ']' hand_side ';'
|
||||
{ $$ = driver.add_model_equal_with_zero_rhs($4); }
|
||||
{ $$ = driver.add_model_equal_with_zero_rhs($1, {}); }
|
||||
| '[' tag_pair_list ']' hand_side EQUAL hand_side ';'
|
||||
{ $$ = driver.add_model_equal($4, $6, $2); }
|
||||
| '[' tag_pair_list ']' hand_side ';'
|
||||
{ $$ = driver.add_model_equal_with_zero_rhs($4, $2); }
|
||||
;
|
||||
|
||||
tags_list : tags_list COMMA tag_pair
|
||||
| tag_pair
|
||||
;
|
||||
tag_pair_list : tag_pair_list COMMA tag_pair
|
||||
{
|
||||
$$ = $1;
|
||||
auto [it, success] = $$.emplace($3);
|
||||
if (!success)
|
||||
driver.error("Tag '" + $3.first + "' cannot be used twice for the same equation");
|
||||
}
|
||||
| tag_pair
|
||||
{ $$ = { $1 }; }
|
||||
;
|
||||
|
||||
tag_pair : symbol EQUAL QUOTED_STRING
|
||||
{ driver.add_equation_tags($1, $3); }
|
||||
{ $$ = { str_tolower($1), $3 }; }
|
||||
| symbol
|
||||
{ driver.add_equation_tags($1, ""); }
|
||||
{ $$ = { str_tolower($1), "" }; }
|
||||
;
|
||||
|
||||
hand_side : '(' hand_side ')'
|
||||
|
@ -1138,17 +1156,17 @@ model_options : MODEL_OPTIONS '(' model_options_list ')' ';'
|
|||
|
||||
tag_pair_list_for_selection : QUOTED_STRING
|
||||
{ $$ = { { "name", $1 } }; }
|
||||
| symbol EQUAL QUOTED_STRING
|
||||
{ $$ = { { $1, $3 } }; }
|
||||
| tag_pair
|
||||
{ $$ = { $1 }; }
|
||||
| tag_pair_list_for_selection COMMA QUOTED_STRING
|
||||
{
|
||||
$$ = $1;
|
||||
$$.emplace_back("name", $3);
|
||||
}
|
||||
| tag_pair_list_for_selection COMMA symbol EQUAL QUOTED_STRING
|
||||
| tag_pair_list_for_selection COMMA tag_pair
|
||||
{
|
||||
$$ = $1;
|
||||
$$.emplace_back($3, $5);
|
||||
$$.push_back($3);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -1397,9 +1397,9 @@ ModelTree::findConstantEquationsWithoutMcpTag(map<VariableNode *, NumConstNode *
|
|||
}
|
||||
|
||||
void
|
||||
ModelTree::addEquation(expr_t eq, optional<int> lineno, const map<string, string> &eq_tags)
|
||||
ModelTree::addEquation(expr_t eq, optional<int> lineno, map<string, string> eq_tags)
|
||||
{
|
||||
equation_tags.add(equations.size(), eq_tags);
|
||||
equation_tags.add(equations.size(), move(eq_tags));
|
||||
addEquation(eq, move(lineno));
|
||||
}
|
||||
|
||||
|
|
|
@ -622,7 +622,7 @@ public:
|
|||
//! Declare a node as an equation of the model; also give its line number
|
||||
void addEquation(expr_t eq, optional<int> lineno);
|
||||
//! Declare a node as an equation of the model, also giving its tags
|
||||
void addEquation(expr_t eq, optional<int> lineno, const map<string, string> &eq_tags);
|
||||
void addEquation(expr_t eq, optional<int> lineno, map<string, string> eq_tags);
|
||||
//! Declare a node as an auxiliary equation of the model, adding it at the end of the list of auxiliary equations
|
||||
void addAuxEquation(expr_t eq);
|
||||
//! Returns the number of equations in the model
|
||||
|
|
|
@ -307,19 +307,6 @@ ParsingDriver::predetermined_variables(const vector<string> &symbol_list)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ParsingDriver::add_equation_tags(string key, string value)
|
||||
{
|
||||
if (eq_tags.contains(key))
|
||||
error("Tag '" + key + "' cannot be declared twice for the same equation");
|
||||
|
||||
eq_tags[key] = value;
|
||||
|
||||
transform(key.begin(), key.end(), key.begin(), ::tolower);
|
||||
if (key == "endogenous")
|
||||
declare_or_change_type(SymbolType::endogenous, value);
|
||||
}
|
||||
|
||||
expr_t
|
||||
ParsingDriver::add_non_negative_constant(const string &constant)
|
||||
{
|
||||
|
@ -2585,10 +2572,14 @@ ParsingDriver::extended_path()
|
|||
}
|
||||
|
||||
expr_t
|
||||
ParsingDriver::add_model_equal(expr_t arg1, expr_t arg2)
|
||||
ParsingDriver::add_model_equal(expr_t arg1, expr_t arg2, map<string, string> eq_tags)
|
||||
{
|
||||
expr_t id = model_tree->AddEqual(arg1, arg2);
|
||||
|
||||
for (const auto &[key, value] : eq_tags)
|
||||
if (key == "endogenous")
|
||||
declare_or_change_type(SymbolType::endogenous, value);
|
||||
|
||||
if (eq_tags.contains("static"))
|
||||
{
|
||||
// If the equation is tagged [static]
|
||||
|
@ -2625,19 +2616,18 @@ ParsingDriver::add_model_equal(expr_t arg1, expr_t arg2)
|
|||
}
|
||||
eq_tags.erase("bind");
|
||||
eq_tags.erase("relax");
|
||||
dynamic_model->addOccbinEquation(id, location.begin.line, eq_tags, regimes_bind, regimes_relax);
|
||||
dynamic_model->addOccbinEquation(id, location.begin.line, move(eq_tags), regimes_bind, regimes_relax);
|
||||
}
|
||||
else // General case
|
||||
model_tree->addEquation(id, location.begin.line, eq_tags);
|
||||
model_tree->addEquation(id, location.begin.line, move(eq_tags));
|
||||
|
||||
eq_tags.clear();
|
||||
return id;
|
||||
}
|
||||
|
||||
expr_t
|
||||
ParsingDriver::add_model_equal_with_zero_rhs(expr_t arg)
|
||||
ParsingDriver::add_model_equal_with_zero_rhs(expr_t arg, map<string, string> eq_tags)
|
||||
{
|
||||
return add_model_equal(arg, model_tree->Zero);
|
||||
return add_model_equal(arg, model_tree->Zero, move(eq_tags));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -239,8 +239,6 @@ private:
|
|||
expr_t add_model_variable(int symb_id, int lag);
|
||||
//! For parsing the graph_format option
|
||||
vector<string> graph_formats;
|
||||
//! Temporary storage for equation tags
|
||||
map<string, string> eq_tags;
|
||||
// Temporary storages for pac_target_info
|
||||
string pac_target_info_name;
|
||||
PacModelTable::target_component_t pac_target_info_component;
|
||||
|
@ -390,8 +388,6 @@ public:
|
|||
void declare_and_init_model_local_variable(const string &name, expr_t rhs);
|
||||
//! Changes type of a symbol
|
||||
void change_type(SymbolType new_type, const vector<string> &symbol_list);
|
||||
//! Adds a list of tags for the current equation
|
||||
void add_equation_tags(string key, string value);
|
||||
//! Adds a non-negative constant to DataTree
|
||||
expr_t add_non_negative_constant(const string &constant);
|
||||
//! Adds a NaN constant to DataTree
|
||||
|
@ -725,9 +721,9 @@ public:
|
|||
//! Extended path
|
||||
void extended_path();
|
||||
//! Writes token "arg1=arg2" to model tree
|
||||
expr_t add_model_equal(expr_t arg1, expr_t arg2);
|
||||
expr_t add_model_equal(expr_t arg1, expr_t arg2, map<string, string> eq_tags);
|
||||
//! Writes token "arg=0" to model tree
|
||||
expr_t add_model_equal_with_zero_rhs(expr_t arg);
|
||||
expr_t add_model_equal_with_zero_rhs(expr_t arg, map<string, string> eq_tags);
|
||||
//! Writes token "arg1+arg2" to model tree
|
||||
expr_t add_plus(expr_t arg1, expr_t arg2);
|
||||
//! Writes token "arg1-arg2" to model tree
|
||||
|
|
Loading…
Reference in New Issue