v4 parser:
* added pre-computing of numerical constants (i.e. 1+1 is replaced by 2) * removed appending of ".0" for integer constants * refactoring of NumericalConstants git-svn-id: https://www.dynare.org/svn/dynare/dynare_v4@1255 ac1d8469-bf42-47a9-8791-bf33cf982152time-shift
parent
3f6a51bfd4
commit
8fb8b0ff99
|
@ -8,8 +8,8 @@ DataTree::DataTree(SymbolTable &symbol_table_arg, NumericalConstants &num_consta
|
||||||
node_counter(0),
|
node_counter(0),
|
||||||
variable_table(symbol_table_arg)
|
variable_table(symbol_table_arg)
|
||||||
{
|
{
|
||||||
Zero = AddNumConstant("0.0");
|
Zero = AddNumConstant("0");
|
||||||
One = AddNumConstant("1.0");
|
One = AddNumConstant("1");
|
||||||
|
|
||||||
MinusOne = AddUMinus(One);
|
MinusOne = AddUMinus(One);
|
||||||
}
|
}
|
||||||
|
|
|
@ -799,7 +799,7 @@ namespace yy
|
||||||
|
|
||||||
case 141:
|
case 141:
|
||||||
#line 383 "DynareBison.yy"
|
#line 383 "DynareBison.yy"
|
||||||
{(yysemantic_stack_[(1) - (1)].string_val)->append(".0"); (yyval.node_val) = driver.add_constant((yysemantic_stack_[(1) - (1)].string_val));;}
|
{(yyval.node_val) = driver.add_constant((yysemantic_stack_[(1) - (1)].string_val));;}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 142:
|
case 142:
|
||||||
|
|
|
@ -380,7 +380,7 @@ cutoff
|
||||||
| FLOAT_NUMBER
|
| FLOAT_NUMBER
|
||||||
{$$ = driver.add_constant($1);}
|
{$$ = driver.add_constant($1);}
|
||||||
| INT_NUMBER
|
| INT_NUMBER
|
||||||
{$1->append(".0"); $$ = driver.add_constant($1);}
|
{$$ = driver.add_constant($1);}
|
||||||
| hand_side PLUS hand_side
|
| hand_side PLUS hand_side
|
||||||
{$$ = driver.add_plus($1, $3);}
|
{$$ = driver.add_plus($1, $3);}
|
||||||
| hand_side MINUS hand_side
|
| hand_side MINUS hand_side
|
||||||
|
|
|
@ -123,7 +123,7 @@ NumConstNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
||||||
double
|
double
|
||||||
NumConstNode::eval(const eval_context_type &eval_context) const throw (EvalException)
|
NumConstNode::eval(const eval_context_type &eval_context) const throw (EvalException)
|
||||||
{
|
{
|
||||||
return(atof(datatree.num_constants.get(id).c_str()));
|
return(datatree.num_constants.getDouble(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -666,10 +666,8 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
double
|
||||||
UnaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalException)
|
UnaryOpNode::eval_opcode(UnaryOpcode op_code, double v) throw (EvalException)
|
||||||
{
|
{
|
||||||
double v = arg->eval(eval_context);
|
|
||||||
|
|
||||||
switch(op_code)
|
switch(op_code)
|
||||||
{
|
{
|
||||||
case oUminus:
|
case oUminus:
|
||||||
|
@ -711,6 +709,14 @@ UnaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalExcept
|
||||||
throw EvalException();
|
throw EvalException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
UnaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalException)
|
||||||
|
{
|
||||||
|
double v = arg->eval(eval_context);
|
||||||
|
|
||||||
|
return eval_opcode(op_code, v);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
UnaryOpNode::collectEndogenous(NodeID &Id)
|
UnaryOpNode::collectEndogenous(NodeID &Id)
|
||||||
{
|
{
|
||||||
|
@ -914,11 +920,8 @@ BinaryOpNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
double
|
||||||
BinaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalException)
|
BinaryOpNode::eval_opcode(double v1, BinaryOpcode op_code, double v2) throw (EvalException)
|
||||||
{
|
{
|
||||||
double v1 = arg1->eval(eval_context);
|
|
||||||
double v2 = arg2->eval(eval_context);
|
|
||||||
|
|
||||||
switch(op_code)
|
switch(op_code)
|
||||||
{
|
{
|
||||||
case oPlus:
|
case oPlus:
|
||||||
|
@ -937,6 +940,15 @@ BinaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalExcep
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
BinaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalException)
|
||||||
|
{
|
||||||
|
double v1 = arg1->eval(eval_context);
|
||||||
|
double v2 = arg2->eval(eval_context);
|
||||||
|
|
||||||
|
return eval_opcode(v1, op_code, v2);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
||||||
const temporary_terms_type &temporary_terms) const
|
const temporary_terms_type &temporary_terms) const
|
||||||
|
|
|
@ -1,51 +1,47 @@
|
||||||
/*! \file
|
|
||||||
\version 1.0
|
|
||||||
\date 04/09/2004
|
|
||||||
\par This file implements the NumericalConstants class methodes.
|
|
||||||
*/
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
using namespace std;
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
#include "NumericalConstants.hh"
|
#include "NumericalConstants.hh"
|
||||||
|
|
||||||
NumericalConstants::NumericalConstants()
|
NumericalConstants::NumericalConstants()
|
||||||
{
|
{
|
||||||
AddConstant("0.0");
|
AddConstant("0");
|
||||||
AddConstant("1.0");
|
AddConstant("1");
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
int
|
||||||
NumericalConstants::~NumericalConstants()
|
NumericalConstants::AddConstant(const string &iConst)
|
||||||
{
|
{
|
||||||
// Empty
|
map<string, int>::iterator iter = numConstantsIndex.find(iConst);
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
int NumericalConstants::AddConstant(string iConst)
|
|
||||||
{
|
|
||||||
map<string, int, less<string> >::iterator iter = numConstantsIndex.find(iConst);
|
|
||||||
|
|
||||||
if (iter != numConstantsIndex.end())
|
if (iter != numConstantsIndex.end())
|
||||||
return iter->second;
|
return iter->second;
|
||||||
|
|
||||||
|
if (atof(iConst.c_str()) < 0)
|
||||||
|
{
|
||||||
|
cerr << "Can't handle a negative constant..!" << endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
int id = (int) mNumericalConstants.size();
|
int id = (int) mNumericalConstants.size();
|
||||||
mNumericalConstants.push_back(iConst);
|
mNumericalConstants.push_back(iConst);
|
||||||
numConstantsIndex[iConst] = id;
|
numConstantsIndex[iConst] = id;
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
string
|
||||||
string NumericalConstants::get(int ID) const
|
NumericalConstants::get(int ID) const
|
||||||
{
|
{
|
||||||
if (ID < (int)mNumericalConstants.size())
|
if (ID < (int) mNumericalConstants.size())
|
||||||
{
|
return mNumericalConstants[ID];
|
||||||
return mNumericalConstants[ID];
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return "";
|
cerr << "Unknown constant" << endl;
|
||||||
|
exit(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
double
|
||||||
|
NumericalConstants::getDouble(int iID) const
|
||||||
|
{
|
||||||
|
return(atof(get(iID).c_str()));
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ using namespace std;
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "SymbolTable.hh"
|
#include "SymbolTable.hh"
|
||||||
#include "NumericalConstants.hh"
|
#include "NumericalConstants.hh"
|
||||||
|
@ -44,6 +45,7 @@ protected:
|
||||||
typedef map<pair<pair<NodeID, NodeID>, int>, NodeID> binary_op_node_map_type;
|
typedef map<pair<pair<NodeID, NodeID>, int>, NodeID> binary_op_node_map_type;
|
||||||
binary_op_node_map_type binary_op_node_map;
|
binary_op_node_map_type binary_op_node_map;
|
||||||
|
|
||||||
|
inline NodeID AddPossiblyNegativeConstant(double val);
|
||||||
inline NodeID AddUnaryOp(UnaryOpcode op_code, NodeID arg);
|
inline NodeID AddUnaryOp(UnaryOpcode op_code, NodeID arg);
|
||||||
inline NodeID AddBinaryOp(NodeID arg1, BinaryOpcode op_code, NodeID arg2);
|
inline NodeID AddBinaryOp(NodeID arg1, BinaryOpcode op_code, NodeID arg2);
|
||||||
public:
|
public:
|
||||||
|
@ -115,14 +117,51 @@ public:
|
||||||
NodeID AddUnknownFunction(const string &function_name, const vector<NodeID> &arguments);
|
NodeID AddUnknownFunction(const string &function_name, const vector<NodeID> &arguments);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline NodeID
|
||||||
|
DataTree::AddPossiblyNegativeConstant(double v)
|
||||||
|
{
|
||||||
|
bool neg = false;
|
||||||
|
if (v < 0)
|
||||||
|
{
|
||||||
|
v = -v;
|
||||||
|
neg = true;
|
||||||
|
}
|
||||||
|
ostringstream ost;
|
||||||
|
ost << v;
|
||||||
|
|
||||||
|
NodeID cnode = AddNumConstant(ost.str());
|
||||||
|
|
||||||
|
if (neg)
|
||||||
|
return AddUMinus(cnode);
|
||||||
|
else
|
||||||
|
return cnode;
|
||||||
|
}
|
||||||
|
|
||||||
inline NodeID
|
inline NodeID
|
||||||
DataTree::AddUnaryOp(UnaryOpcode op_code, NodeID arg)
|
DataTree::AddUnaryOp(UnaryOpcode op_code, NodeID arg)
|
||||||
{
|
{
|
||||||
|
// If the node already exists in tree, share it
|
||||||
unary_op_node_map_type::iterator it = unary_op_node_map.find(make_pair(arg, op_code));
|
unary_op_node_map_type::iterator it = unary_op_node_map.find(make_pair(arg, op_code));
|
||||||
if (it != unary_op_node_map.end())
|
if (it != unary_op_node_map.end())
|
||||||
return it->second;
|
return it->second;
|
||||||
else
|
|
||||||
return new UnaryOpNode(*this, op_code, arg);
|
// Try to reduce to a constant
|
||||||
|
// Case where arg is a constant and op_code == oUminus (i.e. we're adding a negative constant) is skipped
|
||||||
|
NumConstNode *carg = dynamic_cast<NumConstNode *>(arg);
|
||||||
|
if (op_code != oUminus || carg == NULL)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
double argval = arg->eval(eval_context_type());
|
||||||
|
double val = UnaryOpNode::eval_opcode(op_code, argval);
|
||||||
|
return AddPossiblyNegativeConstant(val);
|
||||||
|
}
|
||||||
|
catch(ExprNode::EvalException &e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UnaryOpNode(*this, op_code, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline NodeID
|
inline NodeID
|
||||||
|
@ -131,8 +170,20 @@ DataTree::AddBinaryOp(NodeID arg1, BinaryOpcode op_code, NodeID arg2)
|
||||||
binary_op_node_map_type::iterator it = binary_op_node_map.find(make_pair(make_pair(arg1, arg2), op_code));
|
binary_op_node_map_type::iterator it = binary_op_node_map.find(make_pair(make_pair(arg1, arg2), op_code));
|
||||||
if (it != binary_op_node_map.end())
|
if (it != binary_op_node_map.end())
|
||||||
return it->second;
|
return it->second;
|
||||||
else
|
|
||||||
return new BinaryOpNode(*this, arg1, op_code, arg2);
|
// Try to reduce to a constant
|
||||||
|
try
|
||||||
|
{
|
||||||
|
double argval1 = arg1->eval(eval_context_type());
|
||||||
|
double argval2 = arg2->eval(eval_context_type());
|
||||||
|
double val = BinaryOpNode::eval_opcode(argval1, op_code, argval2);
|
||||||
|
return AddPossiblyNegativeConstant(val);
|
||||||
|
}
|
||||||
|
catch(ExprNode::EvalException &e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BinaryOpNode(*this, arg1, op_code, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -141,6 +141,7 @@ struct ExprNodeLess
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Numerical constant node
|
//! Numerical constant node
|
||||||
|
/*! The constant is necessarily non-negative (this is enforced at the NumericalConstants class level) */
|
||||||
class NumConstNode : public ExprNode
|
class NumConstNode : public ExprNode
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -213,6 +214,7 @@ public:
|
||||||
int Curr_block,
|
int Curr_block,
|
||||||
Model_Block *ModelBlock) const;
|
Model_Block *ModelBlock) const;
|
||||||
virtual void collectEndogenous(NodeID &Id);
|
virtual void collectEndogenous(NodeID &Id);
|
||||||
|
static double eval_opcode(UnaryOpcode op_code, double v) throw (EvalException);
|
||||||
virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
|
virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -247,6 +249,7 @@ public:
|
||||||
int Curr_block,
|
int Curr_block,
|
||||||
Model_Block *ModelBlock) const;
|
Model_Block *ModelBlock) const;
|
||||||
virtual void collectEndogenous(NodeID &Id);
|
virtual void collectEndogenous(NodeID &Id);
|
||||||
|
static double eval_opcode(double v1, BinaryOpcode op_code, double v2) throw (EvalException);
|
||||||
virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
|
virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,36 +1,28 @@
|
||||||
#ifndef _NUMERICALCONSTANTS_HH
|
#ifndef _NUMERICALCONSTANTS_HH
|
||||||
#define _NUMERICALCONSTANTS_HH
|
#define _NUMERICALCONSTANTS_HH
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/** \file
|
using namespace std;
|
||||||
* \version 1.0
|
|
||||||
* \date 12/01/2003
|
|
||||||
* \par This file defines NumericalConstants class.
|
|
||||||
*/
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/*!
|
//! Handles numerical constants
|
||||||
\class NumericalConstants
|
|
||||||
\brief Handles numerical constants
|
|
||||||
*/
|
|
||||||
class NumericalConstants
|
class NumericalConstants
|
||||||
{
|
{
|
||||||
private :
|
private:
|
||||||
/*! Vector of numerical constants */
|
//! Vector of numerical constants
|
||||||
std::vector<std::string> mNumericalConstants;
|
vector<string> mNumericalConstants;
|
||||||
//! Map matching constants to their id
|
//! Map matching constants to their id
|
||||||
std::map<std::string, int, std::less<std::string> > numConstantsIndex;
|
map<string, int> numConstantsIndex;
|
||||||
public :
|
public:
|
||||||
/*! Construcor */
|
|
||||||
NumericalConstants();
|
NumericalConstants();
|
||||||
/*! Destructor */
|
//! Adds a constant and returns its ID
|
||||||
~NumericalConstants();
|
int AddConstant(const string &iConst);
|
||||||
/*! Adds a constant to mNumericalConstants */
|
//! Get a constant in string form
|
||||||
int AddConstant(std::string iConst);
|
string get(int iID) const;
|
||||||
/*! Gets a constant form mNumericalConstants */
|
//! Get a constant in double form
|
||||||
std::string get(int iID) const;
|
double getDouble(int iID) const;
|
||||||
};
|
};
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue