v4 parser:

* refactored SymbolTable class
* added a uniform interface for emitting warnings


git-svn-id: https://www.dynare.org/svn/dynare/dynare_v4@1494 ac1d8469-bf42-47a9-8791-bf33cf982152
time-shift
sebastien 2007-12-19 15:16:43 +00:00
parent a3184c32de
commit 059bb76e7c
9 changed files with 233 additions and 287 deletions

View File

@ -35,12 +35,6 @@ DataTree::AddNumConstant(const string &value)
NodeID NodeID
DataTree::AddVariable(const string &name, int lag) DataTree::AddVariable(const string &name, int lag)
{ {
if (!symbol_table.Exist(name))
{
cerr << "Unknown symbol: " << name << endl;
exit(-1);
}
int symb_id = symbol_table.getID(name); int symb_id = symbol_table.getID(name);
Type type = symbol_table.getType(name); Type type = symbol_table.getType(name);
@ -382,12 +376,6 @@ 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
@ -401,12 +389,6 @@ 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)
{ {
if (!symbol_table.Exist(function_name))
{
cerr << "Unknown symbol: " << function_name << endl;
exit(-1);
}
if (symbol_table.getType(function_name) != eUnknownFunction) if (symbol_table.getType(function_name) != eUnknownFunction)
{ {
cerr << "Symbol " << function_name << " is not a function name!"; cerr << "Symbol " << function_name << " is not a function name!";

View File

@ -12,7 +12,7 @@ ParsingDriver::~ParsingDriver()
bool bool
ParsingDriver::symbol_exists_and_is_not_modfile_local_variable(const char *s) ParsingDriver::symbol_exists_and_is_not_modfile_local_variable(const char *s)
{ {
if (!mod_file->symbol_table.Exist(s)) if (!mod_file->symbol_table.exists(s))
return false; return false;
return(mod_file->symbol_table.getType(s) != eModFileLocalVariable); return(mod_file->symbol_table.getType(s) != eModFileLocalVariable);
@ -21,7 +21,7 @@ ParsingDriver::symbol_exists_and_is_not_modfile_local_variable(const char *s)
void void
ParsingDriver::check_symbol_existence(const string &name) ParsingDriver::check_symbol_existence(const string &name)
{ {
if (!mod_file->symbol_table.Exist(name)) if (!mod_file->symbol_table.exists(name))
error("Unknown symbol: " + name); error("Unknown symbol: " + name);
} }
@ -43,8 +43,6 @@ ParsingDriver::parse(const string &f)
{ {
mod_file = new ModFile(); mod_file = new ModFile();
mod_file->symbol_table.error = error;
tmp_symbol_table = new TmpSymbolTable(mod_file->symbol_table); tmp_symbol_table = new TmpSymbolTable(mod_file->symbol_table);
reset_data_tree(); reset_data_tree();
@ -64,7 +62,7 @@ ParsingDriver::parse(const string &f)
void void
ParsingDriver::error(const yy::parser::location_type &l, const string &m) ParsingDriver::error(const yy::parser::location_type &l, const string &m)
{ {
cerr << l << ": " << m << endl; cerr << "ERROR: " << l << ": " << m << endl;
exit(-1); exit(-1);
} }
@ -72,40 +70,58 @@ void
ParsingDriver::error(const string &m) ParsingDriver::error(const string &m)
{ {
extern int yylineno; extern int yylineno;
cerr << file << ":" << yylineno << ": " << m << endl; cerr << "ERROR: " << file << ":" << yylineno << ": " << m << endl;
exit(-1); exit(-1);
} }
void
ParsingDriver::warning(const string &m)
{
extern int yylineno;
cerr << "WARNING: " << file << ":" << yylineno << ": " << m << endl;
}
void
ParsingDriver::declare_symbol(string *name, Type type, string *tex_name)
{
try
{
mod_file->symbol_table.addSymbol(*name, type, *tex_name);
}
catch(SymbolTable::AlreadyDeclaredException &e)
{
if (e.same_type)
warning("Symbol " + *name + " declared twice.");
else
error("Symbol " + *name + " declared twice with different types!");
}
delete name;
delete tex_name;
}
void void
ParsingDriver::declare_endogenous(string *name, string *tex_name) ParsingDriver::declare_endogenous(string *name, string *tex_name)
{ {
mod_file->symbol_table.AddSymbolDeclar(*name, eEndogenous, *tex_name); declare_symbol(name, eEndogenous, tex_name);
delete name;
delete tex_name;
} }
void void
ParsingDriver::declare_exogenous(string *name, string *tex_name) ParsingDriver::declare_exogenous(string *name, string *tex_name)
{ {
mod_file->symbol_table.AddSymbolDeclar(*name, eExogenous, *tex_name); declare_symbol(name, eExogenous, tex_name);
delete name;
delete tex_name;
} }
void void
ParsingDriver::declare_exogenous_det(string *name, string *tex_name) ParsingDriver::declare_exogenous_det(string *name, string *tex_name)
{ {
mod_file->symbol_table.AddSymbolDeclar(*name, eExogenousDet, *tex_name); declare_symbol(name, eExogenousDet, tex_name);
delete name;
delete tex_name;
} }
void void
ParsingDriver::declare_parameter(string *name, string *tex_name) ParsingDriver::declare_parameter(string *name, string *tex_name)
{ {
mod_file->symbol_table.AddSymbolDeclar(*name, eParameter, *tex_name); declare_symbol(name, eParameter, tex_name);
delete name;
delete tex_name;
} }
NodeID NodeID
@ -149,10 +165,11 @@ ParsingDriver::add_model_variable(string *name, string *olag)
if ((type == eExogenous) && lag != 0) if ((type == eExogenous) && lag != 0)
{ {
cout << "Warning: exogenous variable " ostringstream ost;
<< *name ost << "Exogenous variable " << *name << " has lag " << lag;
<< " has lag " << lag << endl; warning(ost.str());
} }
NodeID id = model_tree->AddVariable(*name, lag); NodeID id = model_tree->AddVariable(*name, lag);
if ((type == eEndogenous) && (model_tree->mode == eSparseDLLMode || model_tree->mode == eSparseMode)) if ((type == eEndogenous) && (model_tree->mode == eSparseDLLMode || model_tree->mode == eSparseMode))
@ -167,8 +184,8 @@ NodeID
ParsingDriver::add_expression_variable(string *name) ParsingDriver::add_expression_variable(string *name)
{ {
// If symbol doesn't exist, then declare it as a mod file local variable // If symbol doesn't exist, then declare it as a mod file local variable
if (!mod_file->symbol_table.Exist(*name)) if (!mod_file->symbol_table.exists(*name))
mod_file->symbol_table.AddSymbolDeclar(*name, eModFileLocalVariable, *name); mod_file->symbol_table.addSymbol(*name, eModFileLocalVariable);
NodeID id = data_tree->AddVariable(*name); NodeID id = data_tree->AddVariable(*name);
@ -1047,15 +1064,16 @@ ParsingDriver::add_model_equal_with_zero_rhs(NodeID arg)
void void
ParsingDriver::declare_and_init_model_local_variable(string *name, NodeID rhs) ParsingDriver::declare_and_init_model_local_variable(string *name, NodeID rhs)
{ {
mod_file->symbol_table.AddSymbolDeclar(*name, eModelLocalVariable, *name);
try try
{ {
model_tree->AddLocalParameter(*name, rhs); mod_file->symbol_table.addSymbol(*name, eModelLocalVariable);
} }
catch(DataTree::LocalParameterException &e) catch(SymbolTable::AlreadyDeclaredException &e)
{ {
error("Local parameter " + e.name + " declared twice"); error("Local model variable " + *name + " declared twice.");
} }
model_tree->AddLocalParameter(*name, rhs);
delete name; delete name;
} }
@ -1254,13 +1272,13 @@ 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.exists(*function_name))
{ {
if (mod_file->symbol_table.getType(*function_name) != eUnknownFunction) if (mod_file->symbol_table.getType(*function_name) != eUnknownFunction)
error("Symbol " + *function_name + " is not a function name."); error("Symbol " + *function_name + " is not a function name.");
} }
else else
mod_file->symbol_table.AddSymbolDeclar(*function_name, eUnknownFunction, *function_name); mod_file->symbol_table.addSymbol(*function_name, eUnknownFunction);
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();

View File

@ -1,95 +1,58 @@
/*! \file
\version 1.0
\date 04/09/2004
\par This file implements the SymbolTable class methodes.
*/
#include <iostream>
#include <algorithm> #include <algorithm>
#include <sstream> #include <sstream>
#include "SymbolTable.hh" #include "SymbolTable.hh"
#include "Interface.hh" #include "Interface.hh"
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), unknown_function_nbr(0) recur_nbr(0), unknown_function_nbr(0)
{ {
name_table.resize(20);
tex_name_table.resize(20);
} }
int SymbolTable::AddSymbol(string name,Type type, string tex_name) void
SymbolTable::addSymbol(const string &name, Type type, const string &tex_name) throw (AlreadyDeclaredException)
{ {
symboltable[name].type = type; if (exists(name))
name_table[(int) type].push_back(name); if (symbol_table[name].first == type)
tex_name_table[(int) type].push_back(tex_name); throw AlreadyDeclaredException(name, true);
else
throw AlreadyDeclaredException(name, false);
int id;
switch (type) switch (type)
{ {
case eExogenous: case eExogenous:
symboltable[name].id = exo_nbr; id = exo_nbr++;
return exo_nbr++; break;
case eExogenousDet: case eExogenousDet:
symboltable[name].id = exo_det_nbr; id = exo_det_nbr++;
return exo_det_nbr++; break;
case eEndogenous: case eEndogenous:
symboltable[name].id = endo_nbr; id = endo_nbr++;
return endo_nbr++; break;
case eParameter: case eParameter:
symboltable[name].id = parameter_nbr; id = parameter_nbr++;
return parameter_nbr++; break;
case eRecursiveVariable: case eRecursiveVariable:
symboltable[name].id = recur_nbr; id = recur_nbr++;
return recur_nbr++; break;
case eModelLocalVariable: case eModelLocalVariable:
symboltable[name].id = model_local_variable_nbr; id = model_local_variable_nbr++;
return model_local_variable_nbr++; break;
case eModFileLocalVariable: case eModFileLocalVariable:
symboltable[name].id = modfile_local_variable_nbr; id = modfile_local_variable_nbr++;
return modfile_local_variable_nbr++; break;
case eUnknownFunction: case eUnknownFunction:
symboltable[name].id = unknown_function_nbr; id = unknown_function_nbr++;
return unknown_function_nbr++; break;
}
// should never happen
return -1;
} }
int SymbolTable::AddSymbolDeclar(string name,Type type, string tex_name) symbol_type symbol(type, id);
{ symbol_table[name] = symbol;
//Testing if the symbol exist in the map name_table[symbol] = name;
if ( !Exist(name) ) tex_name_table[symbol] = tex_name;
{
//The symbol dosn't exist, adding it
return AddSymbol(name,type, tex_name);
}
else
{
//The symbol exists, testing its type
if (symboltable[name].type == type)
{
cout << "Warning : symbol " << name << " declared more than once.\n";
return getID(name);
}
else
{
string msg = "symbol " + name + " declared more than once with different types.";
(* error) (msg.c_str());
return -1;
}
}
}
void SymbolTable::AddSymbolRange(string name,int nbr,Type type, string tex_name)
{
}
void SymbolTable::ResetType(string name,Type new_type)
{
symboltable[name].type = new_type;
} }
void void
@ -97,60 +60,60 @@ SymbolTable::writeOutput(ostream &output) const
{ {
if (exo_nbr > 0) if (exo_nbr > 0)
{ {
output << "M_.exo_names = '" << getNameByID(eExogenous, 0) << "';\n"; output << "M_.exo_names = '" << getNameByID(eExogenous, 0) << "';" << endl;
output << "M_.exo_names_tex = '" << getTexNameByID(eExogenous, 0) << "';\n"; output << "M_.exo_names_tex = '" << getTeXNameByID(eExogenous, 0) << "';" << endl;
for (int id = 1; id < exo_nbr; id++) for (int id = 1; id < exo_nbr; id++)
{ {
output << "M_.exo_names = " + interfaces::strvcat("M_.exo_names","'"+getNameByID(eExogenous, id)+"'") + ";\n"; output << "M_.exo_names = " << interfaces::strvcat("M_.exo_names","'"+getNameByID(eExogenous, id)+"'") << ";" << endl;
output << "M_.exo_names_tex = " + interfaces::strvcat("M_.exo_names_tex","'"+getTexNameByID(eExogenous, id)+"'") + ";\n"; output << "M_.exo_names_tex = " << interfaces::strvcat("M_.exo_names_tex","'"+getTeXNameByID(eExogenous, id)+"'") << ";" << endl;
} }
} }
if (exo_det_nbr > 0) if (exo_det_nbr > 0)
{ {
output << "lgxdet_ = '" << getNameByID(eExogenousDet, 0) << "';\n"; output << "lgxdet_ = '" << getNameByID(eExogenousDet, 0) << "';" << endl;
output << "lgxdet_tex_ = '" << getTexNameByID(eExogenousDet, 0) << "';\n"; output << "lgxdet_tex_ = '" << getTeXNameByID(eExogenousDet, 0) << "';" << endl;
for (int id = 1; id < exo_det_nbr; id++) for (int id = 1; id < exo_det_nbr; id++)
{ {
output << "lgxdet_ = " + interfaces::strvcat("lgxdet_","'"+getNameByID(eExogenousDet, id)+"'") + ";\n"; output << "lgxdet_ = " << interfaces::strvcat("lgxdet_","'"+getNameByID(eExogenousDet, id)+"'") << ";" << endl;
output << "lgxdet_tex_ = " + interfaces::strvcat("lgxdet_tex_","'"+getTexNameByID(eExogenousDet, id)+"'") + ";\n"; output << "lgxdet_tex_ = " << interfaces::strvcat("lgxdet_tex_","'"+getTeXNameByID(eExogenousDet, id)+"'") << ";" << endl;
} }
} }
if (endo_nbr > 0) if (endo_nbr > 0)
{ {
output << "M_.endo_names = '" << getNameByID(eEndogenous, 0) << "';\n"; output << "M_.endo_names = '" << getNameByID(eEndogenous, 0) << "';" << endl;
output << "M_.endo_names_tex = '" << getTexNameByID(eEndogenous, 0) << "';\n"; output << "M_.endo_names_tex = '" << getTeXNameByID(eEndogenous, 0) << "';" << endl;
for (int id = 1; id < endo_nbr; id++) for (int id = 1; id < endo_nbr; id++)
{ {
output << "M_.endo_names = " + interfaces::strvcat("M_.endo_names","'"+getNameByID(eEndogenous, id)+"'") + ";\n"; output << "M_.endo_names = " << interfaces::strvcat("M_.endo_names","'"+getNameByID(eEndogenous, id)+"'") << ";" << endl;
output << "M_.endo_names_tex = " + interfaces::strvcat("M_.endo_names_tex","'"+getTexNameByID(eEndogenous, id)+"'") + ";\n"; output << "M_.endo_names_tex = " << interfaces::strvcat("M_.endo_names_tex","'"+getTeXNameByID(eEndogenous, id)+"'") << ";" << endl;
} }
} }
if (recur_nbr > 0) if (recur_nbr > 0)
{ {
output << "M_.recur_names = '" << getNameByID(eRecursiveVariable, 0) << "';\n"; output << "M_.recur_names = '" << getNameByID(eRecursiveVariable, 0) << "';" << endl;
output << "M_.recur_names_tex = '" << getTexNameByID(eRecursiveVariable, 0) << "';\n"; output << "M_.recur_names_tex = '" << getTeXNameByID(eRecursiveVariable, 0) << "';" << endl;
for (int id = 1; id < recur_nbr; id++) for (int id = 1; id < recur_nbr; id++)
{ {
output << "M_.recur_names = " + interfaces::strvcat("M_.recur_names","'"+getNameByID(eRecursiveVariable, id)+"'") + ";\n"; output << "M_.recur_names = " << interfaces::strvcat("M_.recur_names","'"+getNameByID(eRecursiveVariable, id)+"'") << ";" << endl;
output << "M_.recur_names_tex = " + interfaces::strvcat("M_.recur_names_tex","'"+getTexNameByID(eRecursiveVariable, id)+"'") + ";\n"; output << "M_.recur_names_tex = " << interfaces::strvcat("M_.recur_names_tex","'"+getTeXNameByID(eRecursiveVariable, id)+"'") << ";" << endl;
} }
} }
if (parameter_nbr > 0) if (parameter_nbr > 0)
{ {
output << "M_.param_names = '" << getNameByID(eParameter, 0) << "';\n"; output << "M_.param_names = '" << getNameByID(eParameter, 0) << "';" << endl;
output << "M_.param_names_tex = '" << getTexNameByID(eParameter, 0) << "';\n"; output << "M_.param_names_tex = '" << getTeXNameByID(eParameter, 0) << "';" << endl;
for (int id = 1; id < parameter_nbr; id++) for (int id = 1; id < parameter_nbr; id++)
{ {
output << "M_.param_names = " + interfaces::strvcat("M_.param_names","'"+getNameByID(eParameter, id)+"'") + ";\n"; output << "M_.param_names = " << interfaces::strvcat("M_.param_names","'"+getNameByID(eParameter, id)+"'") << ";" << endl;
output << "M_.param_names_tex = " + interfaces::strvcat("M_.param_names_tex","'"+getTexNameByID(eParameter, id)+"'") + ";\n"; output << "M_.param_names_tex = " << interfaces::strvcat("M_.param_names_tex","'"+getTeXNameByID(eParameter, id)+"'") << ";" << endl;
} }
} }
output << "M_.exo_det_nbr = " << exo_det_nbr << ";\n"; output << "M_.exo_det_nbr = " << exo_det_nbr << ";" << endl
output << "M_.exo_nbr = " << exo_nbr << ";\n"; << "M_.exo_nbr = " << exo_nbr << ";" << endl
output << "M_.Sigma_e = zeros(" << exo_nbr << "M_.endo_nbr = " << endo_nbr << ";" << endl
<< ", " << exo_nbr << ");\n"; << "M_.recur_nbr = " << recur_nbr << ";" << endl
output << "M_.endo_nbr = " << endo_nbr << ";\n"; << "M_.param_nbr = " << parameter_nbr << ";" << endl;
output << "M_.recur_nbr = " << recur_nbr << ";\n";
output << "M_.param_nbr = " << parameter_nbr << ";\n"; output << "M_.Sigma_e = zeros(" << exo_nbr << ", " << exo_nbr << ");" << endl;
} }

View File

@ -17,12 +17,6 @@ VariableTable::VariableTable(const SymbolTable &symbol_table_arg) :
int int
VariableTable::AddVariable(const string &iName, int iLag) VariableTable::AddVariable(const string &iName, int iLag)
{ {
// Testing if symbol exists
if (!symbol_table.Exist(iName))
{
cerr << "Unknown symbol: " << iName << endl;
exit(-1);
}
// Testing if variable exists in VariableTable // Testing if variable exists in VariableTable
int lVariableID = getID(iName,iLag); int lVariableID = getID(iName,iLag);
if (lVariableID != -1) if (lVariableID != -1)

View File

@ -10,7 +10,7 @@ using namespace std;
#include <fstream> #include <fstream>
#include "SymbolTableTypes.hh" #include "SymbolTable.hh"
#include "CodeInterpreter.hh" #include "CodeInterpreter.hh"
class DataTree; class DataTree;

View File

@ -1,6 +1,5 @@
#ifndef MODELNORMALIZATION #ifndef MODELNORMALIZATION
#define MODELNORMALIZATION #define MODELNORMALIZATION
#include "SymbolTableTypes.hh"
#include "SymbolTable.hh" #include "SymbolTable.hh"
#include "CodeInterpreter.hh" #include "CodeInterpreter.hh"

View File

@ -42,6 +42,9 @@ private:
//! Checks that a given symbol exists, and stops with an error message if it doesn't //! Checks that a given symbol exists, and stops with an error message if it doesn't
void check_symbol_existence(const string &name); void check_symbol_existence(const string &name);
//! Helper to add a symbol declaration
void declare_symbol(string *name, Type type, string *tex_name);
//! Creates option "optim_opt" in OptionsList if it doesn't exist, else add a comma, and adds the option name //! Creates option "optim_opt" in OptionsList if it doesn't exist, else add a comma, and adds the option name
void optim_options_helper(const string &name); void optim_options_helper(const string &name);
@ -139,15 +142,8 @@ public:
void error(const yy::parser::location_type &l, const string &m); void error(const yy::parser::location_type &l, const string &m);
//! Error handler without location //! Error handler without location
void error(const string &m); void error(const string &m);
//! Warning handler
//! Static error handler void warning(const string &m);
/*! To be removed in the future. */
static void error(const char *m)
{
extern int yylineno;
cerr << "Error at line " << yylineno << ": " << m << endl;
exit(-1);
}
//! Check if a given symbol exists in the parsing context, and is not a mod file local variable //! Check if a given symbol exists in the parsing context, and is not a mod file local variable
bool symbol_exists_and_is_not_modfile_local_variable(const char *s); bool symbol_exists_and_is_not_modfile_local_variable(const char *s);
@ -161,13 +157,13 @@ public:
void init_compiler(int compiler_type); void init_compiler(int compiler_type);
//! Sets the FILENAME for the initial value in initval //! Sets the FILENAME for the initial value in initval
void init_val_filename(string *filename); void init_val_filename(string *filename);
//! Declares an endogenous variable by adding it to SymbolTable //! Declares an endogenous variable
void declare_endogenous(string *name, string *tex_name = new string); void declare_endogenous(string *name, string *tex_name = new string);
//! Declares an exogenous variable by adding it to SymbolTable //! Declares an exogenous variable
void declare_exogenous(string *name, string *tex_name = new string); void declare_exogenous(string *name, string *tex_name = new string);
//! Declares an exogenous deterministic variable by adding it to SymbolTable //! Declares an exogenous deterministic variable
void declare_exogenous_det(string *name, string *tex_name = new string); void declare_exogenous_det(string *name, string *tex_name = new string);
//! Declares a parameter by adding it to SymbolTable //! Declares a parameter
void declare_parameter(string *name, string *tex_name = new string); void declare_parameter(string *name, string *tex_name = new string);
//! Declares and initializes a local parameter //! Declares and initializes a local parameter
void declare_and_init_model_local_variable(string *name, NodeID rhs); void declare_and_init_model_local_variable(string *name, NodeID rhs);

View File

@ -1,12 +1,6 @@
#ifndef _SYMBOLTABLE_HH #ifndef _SYMBOLTABLE_HH
#define _SYMBOLTABLE_HH #define _SYMBOLTABLE_HH
//------------------------------------------------------------------------------
/*! \file
\version 1.0
\date 12/01/2003
\par This file defines the SymbolTable class .
*/
//------------------------------------------------------------------------------
using namespace std; using namespace std;
#include <map> #include <map>
@ -15,125 +9,154 @@ using namespace std;
#include <ostream> #include <ostream>
#include <iostream> #include <iostream>
#include "SymbolTableTypes.hh" //! Enumeration of possible symbol types
/*! Be careful not to change the order of the enumeration, it matters for VariableTable (at least up to eParameter) */
enum Type
{
eEndogenous = 0, //!< Endogenous
eExogenous = 1, //!< Exogenous
eExogenousDet = 2, //!< Exogenous deterministic
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)
eUnknownFunction = 12 //!< Function unknown to the preprocessor
};
//! Stores the symbol table
/*! /*!
\class SymbolTable A symbol is given by its name, and is internally represented by a pair (type, id).
\brief This class keeps track of symbols
There is a distinct sequence of ids for each type, so two symbol of different types can have the same id.
Also manages a TeX name for each symbol, which by default is an empty string.
*/ */
class SymbolTable class SymbolTable
{ {
private: private:
/*! Adds symbol into symbol table //! A symbol is represented by a pair (type, id)
\param name a string. typedef pair<Type, int> symbol_type;
\param type a Type struct.
\param tex_name a string for the TeX name. //! Type for map: symbol_name -> (type, id)
\par Description typedef map<string, symbol_type> symbol_table_type;
- warning if symbol is already set with same type //! Maps strings to pairs (type,id)
- error if symbol is already set with different type symbol_table_type symbol_table;
- set Name and Type
- increase corresponding counter in ModelParameters class //! Type for map: (type, id) -> symbol_name
*/ typedef map<symbol_type, string> inv_symbol_table_type;
int AddSymbol(std::string name, Type type, std::string tex_name);
/*! Symbol table map */ //! Maps pairs (type, id) to names
std::map<std::string, Symbol, std::less<std::string> > symboltable; inv_symbol_table_type name_table;
//! Typedef for const iterator on symboltable map //! Maps pairs (type, id) to TeX names
typedef std::map<std::string, Symbol, std::less<std::string> >::const_iterator symboltable_const_iterator; inv_symbol_table_type tex_name_table;
/*! Symbol name table indexed by type and ID */
std::vector< std::vector<std::string> > name_table;
std::vector< std::vector<std::string> > tex_name_table;
/*! Changes type of a symbol */
void ResetType(std::string name, Type new_type);
public: public:
/*! Constructor */
SymbolTable(); SymbolTable();
//! Thrown when trying to access an unknown symbol (by name)
class UnknownSymbolNameException
{
public:
//! Symbol name
string name;
UnknownSymbolNameException(const string &name_arg) : name(name_arg) {}
};
//! Thrown when trying to access an unknown symbol (by type+id pair)
class UnknownSymbolIDException
{
public:
//! Symbol type
Type type;
//! Symbol ID
int id;
UnknownSymbolIDException(Type type_arg, int id_arg) : type(type_arg), id(id_arg) {}
};
//! Thrown when trying to declare a symbol twice
class AlreadyDeclaredException
{
public:
//! Symbol name
string name;
//! Was the previous declaration done with the same symbol type ?
bool same_type;
AlreadyDeclaredException(const string &name_arg, bool same_type_arg) : name(name_arg), same_type(same_type_arg) {}
};
//! Number of declared endogenous variables //! Number of declared endogenous variables
int endo_nbr; int endo_nbr;
//! Number of declared exogenous variables //! Number of declared exogenous variables
int exo_nbr; int exo_nbr;
//! Number of declared deterministic exogenous variables //! Number of declared deterministic exogenous variables
int exo_det_nbr; int exo_det_nbr;
//! Number of declared parameters
int parameter_nbr;
//! Number of declared model local variables
int model_local_variable_nbr;
//! Number of declared modfile local variables
int modfile_local_variable_nbr;
//! Number of declared recursive variables //! Number of declared recursive variables
int recur_nbr; int recur_nbr;
//! Number of declared parameters
int parameter_nbr;
//! Number of model local variables
int model_local_variable_nbr;
//! Number of modfile local variables
int modfile_local_variable_nbr;
//! Number of unknown functions //! Number of unknown functions
int unknown_function_nbr; int unknown_function_nbr;
/*! Pointer to error function of parser class */ //! Add a symbol
void (* error) (const char* m); void addSymbol(const string &name, Type type, const string &tex_name = "") throw (AlreadyDeclaredException);
/*! Adds a symbol apearing in declaration //! Tests if symbol already exists
- warning if symbol is already set with same type inline bool exists(const string &name) const;
- error if symbol is already set with different type //! Get symbol name by type and ID
- set name, type inline string getNameByID(Type type, int id) const throw (UnknownSymbolIDException);
- increase corresponding counter in ModelParameters //! Get TeX name by type and ID
*/ inline string getTeXNameByID(Type type, int id) const throw (UnknownSymbolIDException);
int AddSymbolDeclar(std::string name, Type type, std::string tex_name); //! Get type by name
/*! Adds symbol range */ inline Type getType(const string &name) const throw (UnknownSymbolNameException);
void AddSymbolRange(std::string name, int nbr, Type type, std::string tex_name); //! Get ID by name
/*! Tests if symbol exists in symbol table inline int getID(const string &name) const throw (UnknownSymbolNameException);
\return true if exists, false outherwise
*/
inline bool Exist(const std::string &name) const;
/*! Gets name by type and ID */
inline std::string getNameByID(Type type, int id) const;
/*! Gets tex name by type and ID */
inline std::string getTexNameByID(Type type, int id) const;
/*! Gets type by name */
inline Type getType(const std::string &name) const;
/*! Gets ID by name */
inline int getID(const std::string &name) const;
//! Write output of this class //! Write output of this class
void writeOutput(std::ostream &output) const; void writeOutput(ostream &output) const;
}; };
inline bool SymbolTable::Exist(const std::string &name) const inline bool
SymbolTable::exists(const string &name) const
{ {
symboltable_const_iterator iter = symboltable.find(name); symbol_table_type::const_iterator iter = symbol_table.find(name);
return (iter != symboltable.end()); return (iter != symbol_table.end());
} }
//------------------------------------------------------------------------------ inline string
inline std::string SymbolTable::getNameByID(Type type,int id) const SymbolTable::getNameByID(Type type, int id) const throw (UnknownSymbolIDException)
{ {
if (id >= 0 && (int)name_table[type].size() > id) inv_symbol_table_type::const_iterator iter = name_table.find(make_pair(type, id));
return(name_table[type][id]); if (iter != name_table.end())
else return ""; return iter->second;
}
//------------------------------------------------------------------------------
inline std::string SymbolTable::getTexNameByID(Type type,int id) const
{
if (id >= 0 && (int)tex_name_table[type].size() > id)
return(tex_name_table[type][id]);
else return "";
}
//------------------------------------------------------------------------------
inline Type SymbolTable::getType(const std::string &name) const
{
symboltable_const_iterator iter = symboltable.find(name);
if (iter == symboltable.end())
{
cerr << "SymbolTable::getType: unknwon symbol: " << name << endl;
exit(-1);
}
else else
return iter->second.type; throw UnknownSymbolIDException(type, id);
} }
//------------------------------------------------------------------------------ inline string
inline int SymbolTable::getID(const std::string &name) const SymbolTable::getTeXNameByID(Type type, int id) const throw (UnknownSymbolIDException)
{ {
symboltable_const_iterator iter = symboltable.find(name); inv_symbol_table_type::const_iterator iter = tex_name_table.find(make_pair(type, id));
if (iter == symboltable.end()) if (iter != tex_name_table.end())
return -1; return iter->second;
else else
return(iter->second.id); throw UnknownSymbolIDException(type, id);
}
inline Type
SymbolTable::getType(const string &name) const throw (UnknownSymbolNameException)
{
symbol_table_type::const_iterator iter = symbol_table.find(name);
if (iter != symbol_table.end())
return iter->second.first;
else
throw UnknownSymbolNameException(name);
}
inline int
SymbolTable::getID(const string &name) const throw (UnknownSymbolNameException)
{
symbol_table_type::const_iterator iter = symbol_table.find(name);
if (iter != symbol_table.end())
return iter->second.second;
else
throw UnknownSymbolNameException(name);
} }
//------------------------------------------------------------------------------
#endif #endif

View File

@ -1,29 +0,0 @@
#ifndef _SYMBOLTABLETYPES_HH
#define _SYMBOLTABLETYPES_HH
//! Symbol type enum
enum Type
{
eEndogenous = 0, //!< Endogenous
eExogenous = 1, //!< Exogenous
eExogenousDet = 2, //!< Exogenous deterministic (new)
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)
eUnknownFunction = 12 //!< Function unknown to the preprocessor
};
struct Symbol
{
//! Symbol type
Type type;
//! Symbol ID : for each type
int id;
Symbol() : id(-1)
{
}
};
#endif