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),
|
||||
variable_table(symbol_table_arg)
|
||||
{
|
||||
Zero = AddNumConstant("0.0");
|
||||
One = AddNumConstant("1.0");
|
||||
Zero = AddNumConstant("0");
|
||||
One = AddNumConstant("1");
|
||||
|
||||
MinusOne = AddUMinus(One);
|
||||
}
|
||||
|
|
|
@ -799,7 +799,7 @@ namespace yy
|
|||
|
||||
case 141:
|
||||
#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;
|
||||
|
||||
case 142:
|
||||
|
|
|
@ -380,7 +380,7 @@ cutoff
|
|||
| FLOAT_NUMBER
|
||||
{$$ = driver.add_constant($1);}
|
||||
| INT_NUMBER
|
||||
{$1->append(".0"); $$ = driver.add_constant($1);}
|
||||
{$$ = driver.add_constant($1);}
|
||||
| hand_side PLUS hand_side
|
||||
{$$ = driver.add_plus($1, $3);}
|
||||
| hand_side MINUS hand_side
|
||||
|
|
|
@ -123,7 +123,7 @@ NumConstNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
double
|
||||
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
|
||||
|
@ -666,10 +666,8 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
case oUminus:
|
||||
|
@ -711,6 +709,14 @@ UnaryOpNode::eval(const eval_context_type &eval_context) const throw (EvalExcept
|
|||
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
|
||||
UnaryOpNode::collectEndogenous(NodeID &Id)
|
||||
{
|
||||
|
@ -914,11 +920,8 @@ BinaryOpNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
||||
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>
|
||||
using namespace std;
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "NumericalConstants.hh"
|
||||
|
||||
NumericalConstants::NumericalConstants()
|
||||
{
|
||||
AddConstant("0.0");
|
||||
AddConstant("1.0");
|
||||
AddConstant("0");
|
||||
AddConstant("1");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
NumericalConstants::~NumericalConstants()
|
||||
int
|
||||
NumericalConstants::AddConstant(const string &iConst)
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int NumericalConstants::AddConstant(string iConst)
|
||||
{
|
||||
map<string, int, less<string> >::iterator iter = numConstantsIndex.find(iConst);
|
||||
map<string, int>::iterator iter = numConstantsIndex.find(iConst);
|
||||
|
||||
if (iter != numConstantsIndex.end())
|
||||
return iter->second;
|
||||
|
||||
if (atof(iConst.c_str()) < 0)
|
||||
{
|
||||
cerr << "Can't handle a negative constant..!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int id = (int) mNumericalConstants.size();
|
||||
mNumericalConstants.push_back(iConst);
|
||||
numConstantsIndex[iConst] = id;
|
||||
return id;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
string NumericalConstants::get(int ID) const
|
||||
string
|
||||
NumericalConstants::get(int ID) const
|
||||
{
|
||||
if (ID < (int) mNumericalConstants.size())
|
||||
{
|
||||
return mNumericalConstants[ID];
|
||||
}
|
||||
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 <map>
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
|
||||
#include "SymbolTable.hh"
|
||||
#include "NumericalConstants.hh"
|
||||
|
@ -44,6 +45,7 @@ protected:
|
|||
typedef map<pair<pair<NodeID, NodeID>, int>, NodeID> binary_op_node_map_type;
|
||||
binary_op_node_map_type binary_op_node_map;
|
||||
|
||||
inline NodeID AddPossiblyNegativeConstant(double val);
|
||||
inline NodeID AddUnaryOp(UnaryOpcode op_code, NodeID arg);
|
||||
inline NodeID AddBinaryOp(NodeID arg1, BinaryOpcode op_code, NodeID arg2);
|
||||
public:
|
||||
|
@ -115,13 +117,50 @@ public:
|
|||
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
|
||||
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));
|
||||
if (it != unary_op_node_map.end())
|
||||
return it->second;
|
||||
else
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@ -131,7 +170,19 @@ 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));
|
||||
if (it != binary_op_node_map.end())
|
||||
return it->second;
|
||||
else
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -141,6 +141,7 @@ struct ExprNodeLess
|
|||
};
|
||||
|
||||
//! Numerical constant node
|
||||
/*! The constant is necessarily non-negative (this is enforced at the NumericalConstants class level) */
|
||||
class NumConstNode : public ExprNode
|
||||
{
|
||||
private:
|
||||
|
@ -213,6 +214,7 @@ public:
|
|||
int Curr_block,
|
||||
Model_Block *ModelBlock) const;
|
||||
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);
|
||||
};
|
||||
|
||||
|
@ -247,6 +249,7 @@ public:
|
|||
int Curr_block,
|
||||
Model_Block *ModelBlock) const;
|
||||
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);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,36 +1,28 @@
|
|||
#ifndef _NUMERICALCONSTANTS_HH
|
||||
#define _NUMERICALCONSTANTS_HH
|
||||
//------------------------------------------------------------------------------
|
||||
/** \file
|
||||
* \version 1.0
|
||||
* \date 12/01/2003
|
||||
* \par This file defines NumericalConstants class.
|
||||
*/
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
//------------------------------------------------------------------------------
|
||||
/*!
|
||||
\class NumericalConstants
|
||||
\brief Handles numerical constants
|
||||
*/
|
||||
|
||||
//! Handles numerical constants
|
||||
class NumericalConstants
|
||||
{
|
||||
private:
|
||||
/*! Vector of numerical constants */
|
||||
std::vector<std::string> mNumericalConstants;
|
||||
//! Vector of numerical constants
|
||||
vector<string> mNumericalConstants;
|
||||
//! Map matching constants to their id
|
||||
std::map<std::string, int, std::less<std::string> > numConstantsIndex;
|
||||
map<string, int> numConstantsIndex;
|
||||
public:
|
||||
/*! Construcor */
|
||||
NumericalConstants();
|
||||
/*! Destructor */
|
||||
~NumericalConstants();
|
||||
/*! Adds a constant to mNumericalConstants */
|
||||
int AddConstant(std::string iConst);
|
||||
/*! Gets a constant form mNumericalConstants */
|
||||
std::string get(int iID) const;
|
||||
//! Adds a constant and returns its ID
|
||||
int AddConstant(const string &iConst);
|
||||
//! Get a constant in string form
|
||||
string get(int iID) const;
|
||||
//! Get a constant in double form
|
||||
double getDouble(int iID) const;
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue