Commit b4dfd32e authored by sebastien's avatar sebastien
Browse files

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-bf33cf982152
parent 4cf7dccd
...@@ -376,6 +376,12 @@ DataTree::AddEqual(NodeID iArg1, NodeID iArg2) ...@@ -376,6 +376,12 @@ DataTree::AddEqual(NodeID iArg1, NodeID iArg2)
void void
DataTree::AddLocalParameter(const string &name, NodeID value) throw (LocalParameterException) 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); int id = symbol_table.getID(name);
// Throw an exception if symbol already declared // Throw an exception if symbol already declared
...@@ -389,5 +395,19 @@ DataTree::AddLocalParameter(const string &name, NodeID value) throw (LocalParame ...@@ -389,5 +395,19 @@ DataTree::AddLocalParameter(const string &name, NodeID value) throw (LocalParame
NodeID NodeID
DataTree::AddUnknownFunction(const string &function_name, const vector<NodeID> &arguments) 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 ...@@ -195,6 +195,9 @@ VariableNode::VariableNode(DataTree &datatree_arg, int symb_id_arg, Type type_ar
case eModFileLocalVariable: case eModFileLocalVariable:
// Such a variable is never derived // Such a variable is never derived
break; 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) ...@@ -218,6 +221,9 @@ VariableNode::computeDerivative(int varID)
case eModFileLocalVariable: case eModFileLocalVariable:
cerr << "ModFileLocalVariable is not derivable" << endl; cerr << "ModFileLocalVariable is not derivable" << endl;
exit(-1); exit(-1);
case eUnknownFunction:
cerr << "Impossible case!" << endl;
exit(-1);
} }
cerr << "Impossible case!" << endl; cerr << "Impossible case!" << endl;
exit(-1); exit(-1);
...@@ -358,6 +364,9 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, ...@@ -358,6 +364,9 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
case eRecursiveVariable: case eRecursiveVariable:
cerr << "Recursive variable not implemented" << endl; cerr << "Recursive variable not implemented" << endl;
exit(-1); exit(-1);
case eUnknownFunction:
cerr << "Impossible case" << endl;
exit(-1);
} }
} }
...@@ -433,6 +442,9 @@ VariableNode::compile(ofstream &CompileCode, bool lhs_rhs, ExprNodeOutputType ou ...@@ -433,6 +442,9 @@ VariableNode::compile(ofstream &CompileCode, bool lhs_rhs, ExprNodeOutputType ou
case eModFileLocalVariable: case eModFileLocalVariable:
cerr << "VariableNode::compile: unhandled variable type" << endl; cerr << "VariableNode::compile: unhandled variable type" << endl;
exit(-1); exit(-1);
case eUnknownFunction:
cerr << "Impossible case" << endl;
exit(-1);
} }
} }
/*EndNew*/ /*EndNew*/
...@@ -1121,9 +1133,10 @@ BinaryOpNode::eval_opcode(double v1, BinaryOpcode op_code, double v2) throw (Eva ...@@ -1121,9 +1133,10 @@ BinaryOpNode::eval_opcode(double v1, BinaryOpcode op_code, double v2) throw (Eva
case oDifferent: case oDifferent:
return( v1!= v2 ? 1.0 : 0.0); return( v1!= v2 ? 1.0 : 0.0);
case oEqual: case oEqual:
default:
throw EvalException(); throw EvalException();
} }
cerr << "Impossible case!" << endl;
exit(-1);
} }
double double
...@@ -1289,10 +1302,10 @@ BinaryOpNode::collectEndogenous(NodeID &Id) ...@@ -1289,10 +1302,10 @@ BinaryOpNode::collectEndogenous(NodeID &Id)
} }
UnknownFunctionNode::UnknownFunctionNode(DataTree &datatree_arg, UnknownFunctionNode::UnknownFunctionNode(DataTree &datatree_arg,
const string &function_name_arg, int symb_id_arg,
const vector<NodeID> &arguments_arg) : const vector<NodeID> &arguments_arg) :
ExprNode(datatree_arg), ExprNode(datatree_arg),
function_name(function_name_arg), symb_id(symb_id_arg),
arguments(arguments_arg) arguments(arguments_arg)
{ {
} }
...@@ -1316,7 +1329,7 @@ UnknownFunctionNode::computeTemporaryTerms(map<NodeID, int> &reference_count, ...@@ -1316,7 +1329,7 @@ UnknownFunctionNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
void UnknownFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_type, void UnknownFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
const temporary_terms_type &temporary_terms) const 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(); for(vector<NodeID>::const_iterator it = arguments.begin();
it != arguments.end(); it++) it != arguments.end(); it++)
{ {
......
...@@ -1209,6 +1209,14 @@ ParsingDriver::add_unknown_function_arg(NodeID arg) ...@@ -1209,6 +1209,14 @@ ParsingDriver::add_unknown_function_arg(NodeID arg)
NodeID NodeID
ParsingDriver::add_unknown_function(string *function_name) 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); NodeID id = data_tree->AddUnknownFunction(*function_name, unknown_function_args);
unknown_function_args.clear(); unknown_function_args.clear();
return id; return id;
......
...@@ -14,7 +14,7 @@ using namespace std; ...@@ -14,7 +14,7 @@ using namespace std;
SymbolTable::SymbolTable() : endo_nbr(0), exo_nbr(0), exo_det_nbr(0), parameter_nbr(0), 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), model_local_variable_nbr(0), modfile_local_variable_nbr(0),
recur_nbr(0) recur_nbr(0), unknown_function_nbr(0)
{ {
name_table.resize(20); name_table.resize(20);
tex_name_table.resize(20); tex_name_table.resize(20);
...@@ -49,6 +49,9 @@ int SymbolTable::AddSymbol(string name,Type type, string tex_name) ...@@ -49,6 +49,9 @@ int SymbolTable::AddSymbol(string name,Type type, string tex_name)
case eModFileLocalVariable: case eModFileLocalVariable:
symboltable[name].id = modfile_local_variable_nbr; symboltable[name].id = modfile_local_variable_nbr;
return modfile_local_variable_nbr++; return modfile_local_variable_nbr++;
case eUnknownFunction:
symboltable[name].id = unknown_function_nbr;
return unknown_function_nbr++;
} }
// should never happen // should never happen
return -1; return -1;
......
...@@ -20,6 +20,7 @@ class DataTree ...@@ -20,6 +20,7 @@ class DataTree
friend class VariableNode; friend class VariableNode;
friend class UnaryOpNode; friend class UnaryOpNode;
friend class BinaryOpNode; friend class BinaryOpNode;
friend class UnknownFunctionNode;
protected: protected:
//! A reference to the symbol table //! A reference to the symbol table
SymbolTable &symbol_table; SymbolTable &symbol_table;
......
...@@ -285,14 +285,16 @@ public: ...@@ -285,14 +285,16 @@ public:
/*EndNew*/ /*EndNew*/
}; };
//! Unknown function node
class UnknownFunctionNode : public ExprNode class UnknownFunctionNode : public ExprNode
{ {
private: private:
const string function_name; //! Symbol ID (no need to store type: it is necessary eUnknownFunction)
const int symb_id;
const vector<NodeID> arguments; const vector<NodeID> arguments;
virtual NodeID computeDerivative(int varID); virtual NodeID computeDerivative(int varID);
public: public:
UnknownFunctionNode(DataTree &datatree_arg, const string &function_name_arg, UnknownFunctionNode(DataTree &datatree_arg, int symb_id_arg,
const vector<NodeID> &arguments_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 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; virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
......
...@@ -61,6 +61,8 @@ public : ...@@ -61,6 +61,8 @@ public :
int modfile_local_variable_nbr; int modfile_local_variable_nbr;
//! Number of declared recursive variables //! Number of declared recursive variables
int recur_nbr; int recur_nbr;
//! Number of unknown functions
int unknown_function_nbr;
/*! Pointer to error function of parser class */ /*! Pointer to error function of parser class */
void (* error) (const char* m); void (* error) (const char* m);
/*! Adds a symbol apearing in declaration /*! Adds a symbol apearing in declaration
......
...@@ -10,7 +10,8 @@ enum Type ...@@ -10,7 +10,8 @@ enum Type
eRecursiveVariable = 3, //!< Recursive variable (reserved for future use) eRecursiveVariable = 3, //!< Recursive variable (reserved for future use)
eParameter = 4, //!< Parameter eParameter = 4, //!< Parameter
eModelLocalVariable = 10, //!< Local variable whose scope is model (pound expression) 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 struct Symbol
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment