v4 parser: add unknown function names to the symbol table
git-svn-id: https://www.dynare.org/svn/dynare/dynare_v4@1430 ac1d8469-bf42-47a9-8791-bf33cf982152time-shift
parent
4cf7dccdac
commit
b4dfd32e59
|
@ -376,6 +376,12 @@ DataTree::AddEqual(NodeID iArg1, NodeID iArg2)
|
|||
void
|
||||
DataTree::AddLocalParameter(const string &name, NodeID value) throw (LocalParameterException)
|
||||
{
|
||||
if (!symbol_table.Exist(name))
|
||||
{
|
||||
cerr << "Unknown symbol: " << name << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int id = symbol_table.getID(name);
|
||||
|
||||
// Throw an exception if symbol already declared
|
||||
|
@ -389,5 +395,19 @@ DataTree::AddLocalParameter(const string &name, NodeID value) throw (LocalParame
|
|||
NodeID
|
||||
DataTree::AddUnknownFunction(const string &function_name, const vector<NodeID> &arguments)
|
||||
{
|
||||
return new UnknownFunctionNode(*this, function_name, arguments);
|
||||
if (!symbol_table.Exist(function_name))
|
||||
{
|
||||
cerr << "Unknown symbol: " << function_name << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (symbol_table.getType(function_name) != eUnknownFunction)
|
||||
{
|
||||
cerr << "Symbol " << function_name << " is not a function name!";
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int id = symbol_table.getID(function_name);
|
||||
|
||||
return new UnknownFunctionNode(*this, id, arguments);
|
||||
}
|
||||
|
|
|
@ -195,6 +195,9 @@ VariableNode::VariableNode(DataTree &datatree_arg, int symb_id_arg, Type type_ar
|
|||
case eModFileLocalVariable:
|
||||
// Such a variable is never derived
|
||||
break;
|
||||
case eUnknownFunction:
|
||||
cerr << "Attempt to construct a VariableNode with an unknown function name" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,6 +221,9 @@ VariableNode::computeDerivative(int varID)
|
|||
case eModFileLocalVariable:
|
||||
cerr << "ModFileLocalVariable is not derivable" << endl;
|
||||
exit(-1);
|
||||
case eUnknownFunction:
|
||||
cerr << "Impossible case!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
cerr << "Impossible case!" << endl;
|
||||
exit(-1);
|
||||
|
@ -358,6 +364,9 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
case eRecursiveVariable:
|
||||
cerr << "Recursive variable not implemented" << endl;
|
||||
exit(-1);
|
||||
case eUnknownFunction:
|
||||
cerr << "Impossible case" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -433,6 +442,9 @@ VariableNode::compile(ofstream &CompileCode, bool lhs_rhs, ExprNodeOutputType ou
|
|||
case eModFileLocalVariable:
|
||||
cerr << "VariableNode::compile: unhandled variable type" << endl;
|
||||
exit(-1);
|
||||
case eUnknownFunction:
|
||||
cerr << "Impossible case" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
/*EndNew*/
|
||||
|
@ -1121,9 +1133,10 @@ BinaryOpNode::eval_opcode(double v1, BinaryOpcode op_code, double v2) throw (Eva
|
|||
case oDifferent:
|
||||
return( v1!= v2 ? 1.0 : 0.0);
|
||||
case oEqual:
|
||||
default:
|
||||
throw EvalException();
|
||||
}
|
||||
cerr << "Impossible case!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
double
|
||||
|
@ -1289,10 +1302,10 @@ BinaryOpNode::collectEndogenous(NodeID &Id)
|
|||
}
|
||||
|
||||
UnknownFunctionNode::UnknownFunctionNode(DataTree &datatree_arg,
|
||||
const string &function_name_arg,
|
||||
int symb_id_arg,
|
||||
const vector<NodeID> &arguments_arg) :
|
||||
ExprNode(datatree_arg),
|
||||
function_name(function_name_arg),
|
||||
symb_id(symb_id_arg),
|
||||
arguments(arguments_arg)
|
||||
{
|
||||
}
|
||||
|
@ -1316,7 +1329,7 @@ UnknownFunctionNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
|
|||
void UnknownFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
||||
const temporary_terms_type &temporary_terms) const
|
||||
{
|
||||
output << function_name << "(";
|
||||
output << datatree.symbol_table.getNameByID(eUnknownFunction, symb_id) << "(";
|
||||
for(vector<NodeID>::const_iterator it = arguments.begin();
|
||||
it != arguments.end(); it++)
|
||||
{
|
||||
|
|
|
@ -1209,6 +1209,14 @@ ParsingDriver::add_unknown_function_arg(NodeID arg)
|
|||
NodeID
|
||||
ParsingDriver::add_unknown_function(string *function_name)
|
||||
{
|
||||
if (mod_file->symbol_table.Exist(*function_name))
|
||||
{
|
||||
if (mod_file->symbol_table.getType(*function_name) != eUnknownFunction)
|
||||
error("Symbol " + *function_name + " is not a function name.");
|
||||
}
|
||||
else
|
||||
mod_file->symbol_table.AddSymbolDeclar(*function_name, eUnknownFunction, *function_name);
|
||||
|
||||
NodeID id = data_tree->AddUnknownFunction(*function_name, unknown_function_args);
|
||||
unknown_function_args.clear();
|
||||
return id;
|
||||
|
|
|
@ -14,7 +14,7 @@ using namespace std;
|
|||
|
||||
SymbolTable::SymbolTable() : endo_nbr(0), exo_nbr(0), exo_det_nbr(0), parameter_nbr(0),
|
||||
model_local_variable_nbr(0), modfile_local_variable_nbr(0),
|
||||
recur_nbr(0)
|
||||
recur_nbr(0), unknown_function_nbr(0)
|
||||
{
|
||||
name_table.resize(20);
|
||||
tex_name_table.resize(20);
|
||||
|
@ -49,6 +49,9 @@ int SymbolTable::AddSymbol(string name,Type type, string tex_name)
|
|||
case eModFileLocalVariable:
|
||||
symboltable[name].id = modfile_local_variable_nbr;
|
||||
return modfile_local_variable_nbr++;
|
||||
case eUnknownFunction:
|
||||
symboltable[name].id = unknown_function_nbr;
|
||||
return unknown_function_nbr++;
|
||||
}
|
||||
// should never happen
|
||||
return -1;
|
||||
|
|
|
@ -20,6 +20,7 @@ class DataTree
|
|||
friend class VariableNode;
|
||||
friend class UnaryOpNode;
|
||||
friend class BinaryOpNode;
|
||||
friend class UnknownFunctionNode;
|
||||
protected:
|
||||
//! A reference to the symbol table
|
||||
SymbolTable &symbol_table;
|
||||
|
|
|
@ -285,14 +285,16 @@ public:
|
|||
/*EndNew*/
|
||||
};
|
||||
|
||||
//! Unknown function node
|
||||
class UnknownFunctionNode : public ExprNode
|
||||
{
|
||||
private:
|
||||
const string function_name;
|
||||
//! Symbol ID (no need to store type: it is necessary eUnknownFunction)
|
||||
const int symb_id;
|
||||
const vector<NodeID> arguments;
|
||||
virtual NodeID computeDerivative(int varID);
|
||||
public:
|
||||
UnknownFunctionNode(DataTree &datatree_arg, const string &function_name_arg,
|
||||
UnknownFunctionNode(DataTree &datatree_arg, int symb_id_arg,
|
||||
const vector<NodeID> &arguments_arg);
|
||||
virtual void computeTemporaryTerms(map<NodeID, int> &reference_count, temporary_terms_type &temporary_terms, bool is_matlab) const;
|
||||
virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
|
||||
|
|
|
@ -61,6 +61,8 @@ public :
|
|||
int modfile_local_variable_nbr;
|
||||
//! Number of declared recursive variables
|
||||
int recur_nbr;
|
||||
//! Number of unknown functions
|
||||
int unknown_function_nbr;
|
||||
/*! Pointer to error function of parser class */
|
||||
void (* error) (const char* m);
|
||||
/*! Adds a symbol apearing in declaration
|
||||
|
|
|
@ -10,7 +10,8 @@ enum Type
|
|||
eRecursiveVariable = 3, //!< Recursive variable (reserved for future use)
|
||||
eParameter = 4, //!< Parameter
|
||||
eModelLocalVariable = 10, //!< Local variable whose scope is model (pound expression)
|
||||
eModFileLocalVariable = 11 //!< Local variable whose scope is mod file (model excluded)
|
||||
eModFileLocalVariable = 11, //!< Local variable whose scope is mod file (model excluded)
|
||||
eUnknownFunction = 12 //!< Function unknown to the preprocessor
|
||||
};
|
||||
|
||||
struct Symbol
|
||||
|
|
Loading…
Reference in New Issue