preprocessor: write JSON output. #1387

time-shift
Houtan Bastani 2017-02-02 15:09:43 +01:00
parent e88739a5ea
commit d05dd34d30
18 changed files with 662 additions and 13 deletions

View File

@ -16,7 +16,7 @@ function dynare(fname, varargin)
% SPECIAL REQUIREMENTS
% none
% Copyright (C) 2001-2015 Dynare Team
% Copyright (C) 2001-2017 Dynare Team
%
% This file is part of Dynare.
%
@ -195,6 +195,11 @@ if ismember('onlymacro', varargin)
return;
end
if ismember('language=json', varargin)
disp('Preprocesser stopped after preprocessing step because of ''language=json'' option.');
return;
end
% post-dynare-prerocessor-hook
if exist(fname(1:end-4),'dir') && exist([fname(1:end-4) filesep 'hooks'],'dir') && exist([fname(1:end-4) filesep 'hooks/postprocessing.m'],'file')
run([fname(1:end-4) filesep 'hooks/postprocessing'])

View File

@ -5336,3 +5336,10 @@ DynamicModel::writeCCOutput(ostream &output, const string &basename, bool block_
output << "NNZDerivatives.push_back(-1);" << endl
<< "NNZDerivatives.push_back(-1);" << endl;
}
void
DynamicModel::writeJsonOutput(ostream &output) const
{
writeJsonModelEquations(output);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2016 Dynare Team
* Copyright (C) 2003-2017 Dynare Team
*
* This file is part of Dynare.
*
@ -217,6 +217,9 @@ public:
//! Writes model initialization and lead/lag incidence matrix to output
void writeOutput(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll, int order, bool estimation_present, bool compute_xrefs, bool julia) const;
//! Write JSON Output
void writeJsonOutput(ostream &output) const;
//! Return true if the hessian is equal to zero
inline bool checkHessianZero() const;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2016 Dynare Team
* Copyright (C) 2003-2017 Dynare Team
*
* This file is part of Dynare.
*
@ -45,6 +45,7 @@ void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool
#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__)
, bool cygwin, bool msvc, bool mingw
#endif
, bool json, JsonFileOutputType json_output_mode
);
void main1(char *modfile, string &basename, bool debug, bool save_macro, string &save_macro_file,
@ -61,6 +62,7 @@ usage()
#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__)
<< " [cygwin] [msvc] [mingw]"
#endif
<< "[json] [jsonstdout]"
<< endl;
exit(EXIT_FAILURE);
}
@ -113,6 +115,8 @@ main(int argc, char **argv)
map<string, string> defines;
vector<string> path;
FileOutputType output_mode = none;
bool json = false;
JsonFileOutputType json_output_mode = file;
LanguageOutputType language = matlab;
// Parse options
@ -291,6 +295,10 @@ main(int argc, char **argv)
}
}
}
else if (!strcmp(argv[arg], "jsonstdout"))
json_output_mode = standardout;
else if (!strcmp(argv[arg], "json"))
json = true;
else
{
cerr << "Unknown option: " << argv[arg] << endl;
@ -337,6 +345,7 @@ main(int argc, char **argv)
#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__)
, cygwin, msvc, mingw
#endif
, json, json_output_mode
);
return EXIT_SUCCESS;

View File

@ -34,12 +34,20 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear
#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__)
, bool cygwin, bool msvc, bool mingw
#endif
, bool json, JsonFileOutputType json_output_mode
)
{
ParsingDriver p(warnings, nostrict);
// Do parsing and construct internal representation of mod file
ModFile *mod_file = p.parse(in, debug);
if (json)
{
mod_file->symbol_table.freeze();
mod_file->writeJsonOutput(basename, json_output_mode);
mod_file->symbol_table.unfreeze();
cout << "JSON file written after Parsing step." << endl;
}
// Run checking pass
mod_file->checkPass(nostrict);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2016 Dynare Team
* Copyright (C) 2007-2017 Dynare Team
*
* This file is part of Dynare.
*
@ -322,6 +322,14 @@ NumConstNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
output << datatree.num_constants.get(id);
}
void
NumConstNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
output << datatree.num_constants.get(id);
}
bool
NumConstNode::containsExternalFunction() const
{
@ -615,6 +623,16 @@ VariableNode::containsExternalFunction() const
return false;
}
void
VariableNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
output << datatree.symbol_table.getName(symb_id);
if (lag != 0)
output << "(" << lag << ")";
}
void
VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
@ -1850,6 +1868,141 @@ UnaryOpNode::containsExternalFunction() const
return arg->containsExternalFunction();
}
void
UnaryOpNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
// Always put parenthesis around uminus nodes
if (op_code == oUminus)
output << LEFT_PAR(output_type);
switch (op_code)
{
case oUminus:
output << "-";
break;
case oExp:
output << "exp";
break;
case oLog:
output << "log";
break;
case oLog10:
output << "log10";
break;
case oCos:
output << "cos";
break;
case oSin:
output << "sin";
break;
case oTan:
output << "tan";
break;
case oAcos:
output << "acos";
break;
case oAsin:
output << "asin";
break;
case oAtan:
output << "atan";
break;
case oCosh:
output << "cosh";
break;
case oSinh:
output << "sinh";
break;
case oTanh:
output << "tanh";
break;
case oAcosh:
output << "acosh";
break;
case oAsinh:
output << "asinh";
break;
case oAtanh:
output << "atanh";
break;
case oSqrt:
output << "sqrt";
break;
case oAbs:
output << "abs";
break;
case oSign:
output << "sign";
break;
case oSteadyState:
output << "(";
arg->writeJsonOutput(output, output_type, temporary_terms, tef_terms);
output << ")";
return;
case oSteadyStateParamDeriv:
{
VariableNode *varg = dynamic_cast<VariableNode *>(arg);
assert(varg != NULL);
assert(datatree.symbol_table.getType(varg->symb_id) == eEndogenous);
assert(datatree.symbol_table.getType(param1_symb_id) == eParameter);
int tsid_endo = datatree.symbol_table.getTypeSpecificID(varg->symb_id);
int tsid_param = datatree.symbol_table.getTypeSpecificID(param1_symb_id);
assert(IS_MATLAB(output_type));
output << "ss_param_deriv(" << tsid_endo+1 << "," << tsid_param+1 << ")";
}
return;
case oSteadyStateParam2ndDeriv:
{
VariableNode *varg = dynamic_cast<VariableNode *>(arg);
assert(varg != NULL);
assert(datatree.symbol_table.getType(varg->symb_id) == eEndogenous);
assert(datatree.symbol_table.getType(param1_symb_id) == eParameter);
assert(datatree.symbol_table.getType(param2_symb_id) == eParameter);
int tsid_endo = datatree.symbol_table.getTypeSpecificID(varg->symb_id);
int tsid_param1 = datatree.symbol_table.getTypeSpecificID(param1_symb_id);
int tsid_param2 = datatree.symbol_table.getTypeSpecificID(param2_symb_id);
assert(IS_MATLAB(output_type));
output << "ss_param_2nd_deriv(" << tsid_endo+1 << "," << tsid_param1+1
<< "," << tsid_param2+1 << ")";
}
return;
case oExpectation:
output << "EXPECTATION(" << expectation_information_set << ")";
break;
case oErf:
output << "erf";
break;
}
bool close_parenthesis = false;
/* Enclose argument with parentheses if:
- current opcode is not uminus, or
- current opcode is uminus and argument has lowest precedence
*/
if (op_code != oUminus
|| (op_code == oUminus
&& arg->precedence(output_type, temporary_terms) < precedence(output_type, temporary_terms)))
{
output << LEFT_PAR(output_type);
if (op_code == oSign && (output_type == oCDynamicModel || output_type == oCStaticModel))
output << "1.0,";
close_parenthesis = true;
}
// Write argument
arg->writeJsonOutput(output, output_type, temporary_terms, tef_terms);
if (close_parenthesis)
output << RIGHT_PAR(output_type);
// Close parenthesis for uminus
if (op_code == oUminus)
output << RIGHT_PAR(output_type);
}
void
UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
@ -3072,6 +3225,119 @@ BinaryOpNode::containsExternalFunction() const
|| arg2->containsExternalFunction();
}
void
BinaryOpNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
if (op_code == oMax || op_code == oMin)
{
switch (op_code)
{
case oMax:
output << "max(";
break;
case oMin:
output << "min(";
break;
default:
;
}
arg1->writeJsonOutput(output, output_type, temporary_terms, tef_terms);
output << ",";
arg2->writeJsonOutput(output, output_type, temporary_terms, tef_terms);
output << ")";
return;
}
int prec = precedence(output_type, temporary_terms);
bool close_parenthesis = false;
// If left argument has a lower precedence, or if current and left argument are both power operators,
// add parenthesis around left argument
BinaryOpNode *barg1 = dynamic_cast<BinaryOpNode *>(arg1);
if (arg1->precedence(output_type, temporary_terms) < prec
|| (op_code == oPower && barg1 != NULL && barg1->op_code == oPower))
{
output << LEFT_PAR(output_type);
close_parenthesis = true;
}
// Write left argument
arg1->writeJsonOutput(output, output_type, temporary_terms, tef_terms);
if (close_parenthesis)
output << RIGHT_PAR(output_type);
// Write current operator symbol
switch (op_code)
{
case oPlus:
output << "+";
break;
case oMinus:
output << "-";
break;
case oTimes:
output << "*";
break;
case oDivide:
output << "/";
break;
case oPower:
output << "^";
break;
case oLess:
output << "<";
break;
case oGreater:
output << ">";
break;
case oLessEqual:
output << "<=";
break;
case oGreaterEqual:
output << ">=";
break;
case oEqualEqual:
output << "==";
break;
case oDifferent:
output << "!=";
break;
case oEqual:
output << "=";
break;
default:
;
}
close_parenthesis = false;
/* Add parenthesis around right argument if:
- its precedence is lower than those of the current node
- it is a power operator and current operator is also a power operator
- it is a minus operator with same precedence than current operator
- it is a divide operator with same precedence than current operator */
BinaryOpNode *barg2 = dynamic_cast<BinaryOpNode *>(arg2);
int arg2_prec = arg2->precedence(output_type, temporary_terms);
if (arg2_prec < prec
|| (op_code == oPower && barg2 != NULL && barg2->op_code == oPower && !IS_LATEX(output_type))
|| (op_code == oMinus && arg2_prec == prec)
|| (op_code == oDivide && arg2_prec == prec && !IS_LATEX(output_type)))
{
output << LEFT_PAR(output_type);
close_parenthesis = true;
}
// Write right argument
arg2->writeJsonOutput(output, output_type, temporary_terms, tef_terms);
if (close_parenthesis)
output << RIGHT_PAR(output_type);
}
void
BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
@ -4211,6 +4477,29 @@ TrinaryOpNode::containsExternalFunction() const
|| arg3->containsExternalFunction();
}
void
TrinaryOpNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
switch (op_code)
{
case oNormcdf:
output << "normcdf(";
break;
case oNormpdf:
output << "normpdf(";
break;
}
arg1->writeJsonOutput(output, output_type, temporary_terms, tef_terms);
output << ",";
arg2->writeJsonOutput(output, output_type, temporary_terms, tef_terms);
output << ",";
arg3->writeJsonOutput(output, output_type, temporary_terms, tef_terms);
output << ")";
}
void
TrinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
@ -4891,6 +5180,21 @@ AbstractExternalFunctionNode::writeExternalFunctionArguments(ostream &output, Ex
}
}
void
AbstractExternalFunctionNode::writeJsonExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
for (vector<expr_t>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
{
if (it != arguments.begin())
output << ",";
(*it)->writeJsonOutput(output, output_type, temporary_terms, tef_terms);
}
}
void
AbstractExternalFunctionNode::writePrhs(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
@ -5054,6 +5358,16 @@ ExternalFunctionNode::compileExternalFunctionOutput(ostream &CompileCode, unsign
}
}
void
ExternalFunctionNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
output << datatree.symbol_table.getName(symb_id) << "(";
writeJsonExternalFunctionArguments(output, output_type, temporary_terms, tef_terms);
output << ")";
}
void
ExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
@ -5244,6 +5558,13 @@ FirstDerivExternalFunctionNode::composeDerivatives(const vector<expr_t> &dargs)
return theDeriv;
}
void
FirstDerivExternalFunctionNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
}
void
FirstDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
@ -5556,6 +5877,13 @@ SecondDerivExternalFunctionNode::composeDerivatives(const vector<expr_t> &dargs)
exit(EXIT_FAILURE);
}
void
SecondDerivExternalFunctionNode::writeJsonOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const
{
}
void
SecondDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2016 Dynare Team
* Copyright (C) 2007-2017 Dynare Team
*
* This file is part of Dynare.
*
@ -221,6 +221,9 @@ public:
//! Writes output of node, using a Txxx notation for nodes in temporary_terms
void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const;
//! Writes output of node in JSON syntax
virtual void writeJsonOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const = 0;
//! Writes the output for an external function, ensuring that the external function is called as few times as possible using temporary terms
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
@ -478,6 +481,7 @@ public:
};
virtual void prepareForDerivation();
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual void writeJsonOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual bool containsExternalFunction() const;
virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const;
@ -527,6 +531,7 @@ public:
VariableNode(DataTree &datatree_arg, int symb_id_arg, int lag_arg);
virtual void prepareForDerivation();
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual void writeJsonOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual bool containsExternalFunction() const;
virtual void collectDynamicVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
virtual void computeTemporaryTerms(map<expr_t, int > &reference_count,
@ -602,6 +607,7 @@ public:
map<NodeTreeReference, temporary_terms_t> &temp_terms_map,
bool is_matlab, NodeTreeReference tr) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual void writeJsonOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual bool containsExternalFunction() const;
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
@ -689,6 +695,7 @@ public:
map<NodeTreeReference, temporary_terms_t> &temp_terms_map,
bool is_matlab, NodeTreeReference tr) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual void writeJsonOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual bool containsExternalFunction() const;
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
@ -794,6 +801,7 @@ public:
map<NodeTreeReference, temporary_terms_t> &temp_terms_map,
bool is_matlab, NodeTreeReference tr) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual void writeJsonOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual bool containsExternalFunction() const;
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
@ -864,6 +872,7 @@ protected:
int getIndxInTefTerms(int the_symb_id, deriv_node_temp_terms_t &tef_terms) const throw (UnknownFunctionNameAndArgs);
//! Helper function to write output arguments of any given external function
void writeExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
void writeJsonExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
public:
AbstractExternalFunctionNode(DataTree &datatree_arg, int symb_id_arg,
const vector<expr_t> &arguments_arg);
@ -872,6 +881,7 @@ public:
map<NodeTreeReference, temporary_terms_t> &temp_terms_map,
bool is_matlab, NodeTreeReference tr) const = 0;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const = 0;
virtual void writeJsonOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const = 0;
virtual bool containsExternalFunction() const;
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
@ -938,6 +948,7 @@ public:
map<NodeTreeReference, temporary_terms_t> &temp_terms_map,
bool is_matlab, NodeTreeReference tr) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual void writeJsonOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_t &temporary_terms,
deriv_node_temp_terms_t &tef_terms) const;
@ -978,6 +989,7 @@ public:
vector< vector<temporary_terms_t> > &v_temporary_terms,
int equation) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual void writeJsonOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual void compile(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,
@ -1017,6 +1029,7 @@ public:
vector< vector<temporary_terms_t> > &v_temporary_terms,
int equation) const;
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual void writeJsonOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const;
virtual void compile(ostream &CompileCode, unsigned int &instruction_number,
bool lhs_rhs, const temporary_terms_t &temporary_terms,
const map_idx_t &map_idx, bool dynamic, bool steady_dynamic,

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2015 Dynare Team
* Copyright (C) 2014-2017 Dynare Team
*
* This file is part of Dynare.
*
@ -38,4 +38,10 @@ enum LanguageOutputType
julia, // outputs files for Julia
python, // outputs files for Python (not yet implemented) (not yet implemented)
};
enum JsonFileOutputType
{
file, // output JSON files to file
standardout, // output JSON files to stdout
};
#endif

View File

@ -1246,3 +1246,72 @@ ModFile::writeExternalFilesJulia(const string &basename, FileOutputType output)
jlOutputFile.close();
cout << "done" << endl;
}
void
ModFile::writeJsonOutput(const string &basename, JsonFileOutputType json_output_mode) const
{
ostringstream output;
output << "{" << endl;
symbol_table.writeJsonOutput(output);
dynamic_model.writeJsonOutput(output);
if (!statements.empty())
{
output << ",\"statements\": [";
bool printed_statement = false;
for (vector<Statement *>::const_iterator it = statements.begin();
it != statements.end();)
{
(*it)->writeJsonOutput(output);
if (dynamic_cast<InitParamStatement *>(*it) != NULL ||
dynamic_cast<InitValStatement *>(*it) != NULL ||
dynamic_cast<EndValStatement *>(*it) != NULL ||
dynamic_cast<HistValStatement *>(*it) != NULL)
printed_statement = true;
if (++it == statements.end())
break;
// tests to see if the next statement will be one for which we support writing JSON files
// to be deleted once we support all statements
if (printed_statement &&
(dynamic_cast<InitParamStatement *>(*it) != NULL ||
dynamic_cast<InitValStatement *>(*it) != NULL ||
dynamic_cast<EndValStatement *>(*it) != NULL ||
dynamic_cast<HistValStatement *>(*it) != NULL))
output << "," << endl;
}
output << "]" << endl;
}
output << "}" << endl;
if (json_output_mode == standardout)
cout << output.str();
else
{
ofstream jsonOutputFile;
if (basename.size())
{
string fname(basename);
fname += ".json";
jsonOutputFile.open(fname.c_str(), ios::out | ios::binary);
if (!jsonOutputFile.is_open())
{
cerr << "ERROR: Can't open file " << fname << " for writing" << endl;
exit(EXIT_FAILURE);
}
}
else
{
cerr << "ERROR: Missing file name" << endl;
exit(EXIT_FAILURE);
}
jsonOutputFile << output.str();
jsonOutputFile.close();
}
}

View File

@ -167,6 +167,11 @@ public:
void writeModelCC(const string &basename) const;
void computeChecksum();
//! Write JSON representation of ModFile object
//! Initially created to enable Julia to work with .mod files
//! Potentially outputs ModFile after the various parts of processing (parsing, checkPass, transformPass, computingPass)
//! Allows user of other host language platforms (python, fortran, etc) to provide support for dynare .mod files
void writeJsonOutput(const string &basename, JsonFileOutputType json_output_mode) const;
};
#endif // ! MOD_FILE_HH

View File

@ -1919,3 +1919,38 @@ bool ModelTree::isNonstationary(int symb_id) const
!= nonstationary_symbols_map.end());
}
void
ModelTree::writeJsonModelEquations(ostream &output) const
{
deriv_node_temp_terms_t tef_terms;
vector<pair<string,string> > eqtags;
output << endl << ",\"model\":[" << endl;
for (int eq = 0; eq < (int) equations.size(); eq++)
{
output << "{ \"equation\": \"";
equations[eq]->writeJsonOutput(output, oMatlabDynamicModel, temporary_terms, tef_terms);
output << "\", \"line\": " << equations_lineno[eq];
for (vector<pair<int, pair<string, string> > >::const_iterator it = equation_tags.begin();
it != equation_tags.end(); it++)
if (it->first == eq)
eqtags.push_back(it->second);
if (!eqtags.empty())
{
output << ", \"tags\": {";
int i = 0;
for (vector<pair<string, string> >:: const_iterator it = eqtags.begin(); it != eqtags.end(); it++, i++)
{
if (i != 0)
output << ", ";
output << "\"" << it->first << "\": \"" << it->second << "\"";
}
output << "}";
eqtags.clear();
}
output << "}";
if (eq < (int) equations.size() - 1)
output << "," << endl;
}
output << endl << "]" << endl;
}

View File

@ -199,6 +199,8 @@ protected:
void writeModelLocalVariables(ostream &output, ExprNodeOutputType output_type, deriv_node_temp_terms_t &tef_terms) const;
//! Writes model equations
void writeModelEquations(ostream &output, ExprNodeOutputType output_type) const;
//! Writes JSON model equations
void writeJsonModelEquations(ostream &output) const;
//! Compiles model equations
void compileModelEquations(ostream &code_file, unsigned int &instruction_number, const temporary_terms_t &tt, const map_idx_t &map_idx, bool dynamic, bool steady_dynamic) const;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2016 Dynare Team
* Copyright (C) 2003-2017 Dynare Team
*
* This file is part of Dynare.
*
@ -63,6 +63,14 @@ InitParamStatement::writeJuliaOutput(ostream &output, const string &basename)
// output << symbol_table.getName(symb_id) << " = model_.params[ " << id << " ]" << endl;
}
void
InitParamStatement::writeJsonOutput(ostream &output) const
{
output << "{\"statementName\": \"param_init\", \"name\": \"" << symbol_table.getName(symb_id) << "\", " << "\"value\": ";
param_value->writeOutput(output);
output << "}";
}
void
InitParamStatement::writeCOutput(ostream &output, const string &basename)
{
@ -165,6 +173,22 @@ InitOrEndValStatement::writeInitValues(ostream &output) const
}
}
void
InitOrEndValStatement::writeJsonInitValues(ostream &output) const
{
int i = 0;
deriv_node_temp_terms_t tef_terms;
for (init_values_t::const_iterator it = init_values.begin();
it != init_values.end(); it++, i++)
{
output << "{\"name\": \"" << symbol_table.getName(it->first) << "\", " << "\"value\": \"";
it->second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
output << "\"}";
if (i < init_values.size() - 1)
output << ", ";
}
}
InitValStatement::InitValStatement(const init_values_t &init_values_arg,
const SymbolTable &symbol_table_arg,
const bool &all_values_required_arg) :
@ -210,6 +234,14 @@ InitValStatement::writeOutput(ostream &output, const string &basename, bool mini
writeInitValues(output);
}
void
InitValStatement::writeJsonOutput(ostream &output) const
{
output << "{\"statementName\": \"init_val\", \"vals\": [";
writeJsonInitValues(output);
output << "]}";
}
void
InitValStatement::writeOutputPostInit(ostream &output) const
{
@ -267,6 +299,14 @@ EndValStatement::writeOutput(ostream &output, const string &basename, bool minim
writeInitValues(output);
}
void
EndValStatement::writeJsonOutput(ostream &output) const
{
output << "{\"statementName\": \"end_val\", \"vals\": [";
writeJsonInitValues(output);
output << "]}";
}
HistValStatement::HistValStatement(const hist_values_t &hist_values_arg,
const SymbolTable &symbol_table_arg,
const bool &all_values_required_arg) :
@ -375,6 +415,26 @@ HistValStatement::writeOutput(ostream &output, const string &basename, bool mini
}
}
void
HistValStatement::writeJsonOutput(ostream &output) const
{
int i = 0;
deriv_node_temp_terms_t tef_terms;
output << "{\"statementName\": \"hist_val\", \"vals\": [";
for (hist_values_t::const_iterator it = hist_values.begin();
it != hist_values.end(); it++)
{
output << "{ \"name\": \"" << symbol_table.getName(it->first.first) << "\""
<< ", \"lag\": " << it->first.second
<< ", \"value\": \"";
it->second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
output << "\"}";
if (i < hist_values.size() - 1)
output << ", ";
}
output << "]}";
}
InitvalFileStatement::InitvalFileStatement(const string &filename_arg) :
filename(filename_arg)
{

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2016 Dynare Team
* Copyright (C) 2003-2017 Dynare Team
*
* This file is part of Dynare.
*
@ -43,6 +43,7 @@ public:
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
virtual void writeJuliaOutput(ostream &output, const string &basename);
virtual void writeCOutput(ostream &output, const string &basename);
virtual void writeJsonOutput(ostream &output) const;
//! Fill eval context with parameter value
void fillEvalContext(eval_context_t &eval_context) const;
};
@ -69,6 +70,7 @@ public:
void fillEvalContext(eval_context_t &eval_context) const;
protected:
void writeInitValues(ostream &output) const;
void writeJsonInitValues(ostream &output) const;
};
class InitValStatement : public InitOrEndValStatement
@ -79,6 +81,7 @@ public:
const bool &all_values_required_arg);
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
virtual void writeJsonOutput(ostream &output) const;
//! Writes initializations for oo_.exo_simul and oo_.exo_det_simul
void writeOutputPostInit(ostream &output) const;
};
@ -92,6 +95,7 @@ public:
//! Workaround for trac ticket #35
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
virtual void writeJsonOutput(ostream &output) const;
};
class HistValStatement : public Statement
@ -114,6 +118,7 @@ public:
//! Workaround for trac ticket #157
virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
virtual void writeJsonOutput(ostream &output) const;
};
class InitvalFileStatement : public Statement

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2015 Dynare Team
* Copyright (C) 2006-2017 Dynare Team
*
* This file is part of Dynare.
*
@ -82,6 +82,10 @@ void Statement::writeJuliaOutput(ostream &output, const string &basename)
{
}
void Statement::writeJsonOutput(ostream &output) const
{
}
void
Statement::computingPass()
{

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2015 Dynare Team
* Copyright (C) 2006-2017 Dynare Team
*
* This file is part of Dynare.
*
@ -144,6 +144,7 @@ public:
virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const = 0;
virtual void writeCOutput(ostream &output, const string &basename);
virtual void writeJuliaOutput(ostream &output, const string &basename);
virtual void writeJsonOutput(ostream &output) const;
};
class NativeStatement : public Statement

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2016 Dynare Team
* Copyright (C) 2003-2017 Dynare Team
*
* This file is part of Dynare.
*
@ -21,6 +21,7 @@
#include <sstream>
#include <iostream>
#include <cassert>
#include <boost/algorithm/string/replace.hpp>
#include "SymbolTable.hh"
@ -138,6 +139,17 @@ SymbolTable::freeze() throw (FrozenException)
}
}
void
SymbolTable::unfreeze()
{
frozen = false;
endo_ids.clear();
exo_ids.clear();
exo_det_ids.clear();
param_ids.clear();
type_specific_ids.clear();
}
void
SymbolTable::changeType(int id, SymbolType newtype) throw (UnknownSymbolIDException, FrozenException)
{
@ -950,3 +962,74 @@ SymbolTable::writeJuliaOutput(ostream &output) const throw (NotYetFrozenExceptio
output << " ]" << endl;
}
}
void
SymbolTable::writeJsonOutput(ostream &output) const
{/*
vector<int> endos, exos, exo_dets, params;
for (int i = 0; i < size; i++)
{
switch (getType(i))
{
case eEndogenous:
endos.push_back(i);
break;
case eExogenous:
exos.push_back(i);
break;
case eExogenousDet:
exo_dets.push_back(i);
break;
case eParameter:
params.push_back(i);
break;
default:
break;
}
}
*/
if (!endo_ids.empty())
{
output << "\"endogenous\":";
writeJsonVarVector(output, endo_ids);
output << endl;
}
if (!exo_ids.empty())
{
output << ",\"exogenous\":";
writeJsonVarVector(output, exo_ids);
output << endl;
}
if (!exo_det_ids.empty())
{
output << ",\"exogenous_deterministic\":";
writeJsonVarVector(output, exo_det_ids);
output << endl;
}
if (!param_ids.empty())
{
output << ",\"parameters\":";
writeJsonVarVector(output, param_ids);
cout << endl;
}
}
void
SymbolTable::writeJsonVarVector(ostream &output, const vector<int> &varvec) const
{
output << "[";
for (int i = 0; i < varvec.size(); i++)
{
output << endl << "{"
<< "\"name\":\" " << getName(varvec[i]) << "\", "
<< "\"texName\":\" " << boost::replace_all_copy(getTeXName(varvec[i]), "\\", "\\\\") << "\", "
<< "\"longName\":\" " << boost::replace_all_copy(getLongName(varvec[i]), "\\", "\\\\") << "\"}";
if (i < varvec.size() - 1)
output << ", ";
}
output << endl << "]";
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2016 Dynare Team
* Copyright (C) 2003-2017 Dynare Team
*
* This file is part of Dynare.
*
@ -192,7 +192,8 @@ private:
int addLagAuxiliaryVarInternal(bool endo, int orig_symb_id, int orig_lead_lag, expr_t arg) throw (FrozenException);
//! Factorized code for adding aux lead variables
int addLeadAuxiliaryVarInternal(bool endo, int index, expr_t arg) throw (FrozenException);
//! Factorized code for Json writing
void writeJsonVarVector(ostream &output, const vector<int> &varvec) const;
public:
//! Add a symbol
/*! Returns the symbol ID */
@ -274,6 +275,9 @@ public:
int getID(SymbolType type, int tsid) const throw (UnknownTypeSpecificIDException, NotYetFrozenException);
//! Freeze symbol table
void freeze() throw (FrozenException);
//! unreeze symbol table
//! Used after having written JSON files
void unfreeze();
//! Change the type of a symbol
void changeType(int id, SymbolType newtype) throw (UnknownSymbolIDException, FrozenException);
//! Get type specific ID (by symbol ID)
@ -294,6 +298,8 @@ public:
inline int orig_endo_nbr() const throw (NotYetFrozenException);
//! Write output of this class
void writeOutput(ostream &output) const throw (NotYetFrozenException);
//! Write JSON Output
void writeJsonOutput(ostream &output) const;
//! Write Julia output of this class
void writeJuliaOutput(ostream &output) const throw (NotYetFrozenException);
//! Write C output of this class