Commit 573227a0 authored by sebastien's avatar sebastien
Browse files

v4 parser:

* removed Expression class; the "ExprNode" class is therefore now used everywhere
* removed interprete class, and replaced it by a method in ExprNode and an global evaluation context in ModFile
* fixed breakage of SparseDLL / Block decomposition code introduced in previous revision


git-svn-id: https://www.dynare.org/svn/dynare/dynare_v4@1204 ac1d8469-bf42-47a9-8791-bf33cf982152
parent 30c70a35
......@@ -60,8 +60,10 @@ SimulStatement::writeOutput(ostream &output, const string &basename) const
output << "simul(oo_.dr);\n";
}
SimulSparseStatement::SimulSparseStatement(const OptionsList &options_list_arg) :
options_list(options_list_arg)
SimulSparseStatement::SimulSparseStatement(const OptionsList &options_list_arg,
int compiler_arg) :
options_list(options_list_arg),
compiler(compiler_arg)
{
}
......@@ -81,10 +83,10 @@ SimulSparseStatement::writeOutput(ostream &output, const string &basename) const
output << "end\n";
output << "disp('compiling...');\n";
if (compiler == 0)
output << "mex " << filename << "_dynamic.c;\n";
output << "mex " << basename << "_dynamic.c;\n";
else
output << "mex " << filename << "_dynamic.cc;\n";
output << "oo_.endo_simul=" << filename << "_dynamic;\n";
output << "mex " << basename << "_dynamic.cc;\n";
output << "oo_.endo_simul=" << basename << "_dynamic;\n";
}
StochSimulStatement::StochSimulStatement(const TmpSymbolTable &tmp_symbol_table_arg,
......@@ -452,7 +454,9 @@ ObservationTrendsStatement::writeOutput(ostream &output, const string &basename)
if (type == eEndogenous)
{
output << "tmp1 = strmatch('" << it->first << "',options_.varobs,'exact');\n";
output << "options_.trend_coeffs{tmp1} = '" << it->second << "';\n";
output << "options_.trend_coeffs{tmp1} = '";
it->second->writeOutput(output);
output << "';" << endl;
}
else
cout << "Error : Non-variable symbol used in TREND_COEFF: " << it->first << endl;
......@@ -490,20 +494,24 @@ CalibVarStatement::writeOutput(ostream &output, const string &basename) const
{
const string &name = it->first;
const string &weight = it->second.first;
const string &expression = it->second.second;
const NodeID expression = it->second.second;
int id = symbol_table.getID(name) + 1;
if (symbol_table.getType(name) == eEndogenous)
{
output << "calib_var_index{1} = [calib_var_index{1};" << id << "," << id << "];\n";
output << "calib_weights{1} = [calib_weights{1}; " << weight << "];\n";
output << "calib_targets{1} =[calib_targets{1}; " << expression << "];\n";
output << "calib_targets{1} =[calib_targets{1}; ";
expression->writeOutput(output);
output << "];\n";
}
else if (symbol_table.getType(name) == eExogenous)
{
output << "calib_var_index{3} = [calib_var_index{3};" << id << "," << id << "];\n";
output << "calib_weights{3} = [calib_weights{3}; " << weight << "];\n";
output << "calib_targets{3} =[calib_targets{3}; " << expression << "];\n";
output << "calib_targets{3} =[calib_targets{3}; ";
expression->writeOutput(output);
output << "];\n";
}
}
......@@ -514,7 +522,7 @@ CalibVarStatement::writeOutput(ostream &output, const string &basename) const
const string &name1 = it->first.first;
const string &name2 = it->first.second;
const string &weight = it->second.first;
const string &expression = it->second.second;
const NodeID expression = it->second.second;
int id1 = symbol_table.getID(name1) + 1;
int id2 = symbol_table.getID(name2) + 1;
......@@ -522,13 +530,17 @@ CalibVarStatement::writeOutput(ostream &output, const string &basename) const
{
output << "calib_var_index{1} = [calib_var_index{1};" << id1 << "," << id2 << "];\n";
output << "calib_weights{1} = [calib_weights{1}; " << weight << "];\n";
output << "calib_targets{1} =[calib_targets{1}; " << expression << "];\n";
output << "calib_targets{1} =[calib_targets{1}; ";
expression->writeOutput(output);
output << "];\n";
}
else if (symbol_table.getType(name1) == eExogenous)
{
output << "calib_var_index{3} = [calib_var_index{3};" << id1 << "," << id2 << "];\n";
output << "calib_weights{3} = [calib_weights{3}; " << weight << "];\n";
output << "calib_targets{3} =[calib_targets{3}; " << expression << "];\n";
output << "calib_targets{3} =[calib_targets{3}; ";
expression->writeOutput(output);
output << "];\n";
}
}
......@@ -541,7 +553,7 @@ CalibVarStatement::writeOutput(ostream &output, const string &basename) const
const string &name = it->first.first;
int iar = it->first.second + 3;
const string &weight = it->second.first;
const string &expression = it->second.second;
const NodeID expression = it->second.second;
int id = symbol_table.getID(name) + 1;
......@@ -559,7 +571,9 @@ CalibVarStatement::writeOutput(ostream &output, const string &basename) const
output << "calib_var_index{" << iar << "} = [calib_var_index{" << iar << "};" << id << "];\n";
output << "calib_weights{" << iar << "} = [calib_weights{" << iar << "}; " << weight << "];\n";
output << "calib_targets{" << iar << "} =[calib_targets{" << iar << "}; " << expression << "];\n";
output << "calib_targets{" << iar << "} =[calib_targets{" << iar << "}; ";
expression->writeOutput(output);
output << "];\n";
}
}
......@@ -671,9 +685,11 @@ OptimWeightsStatement::writeOutput(ostream &output, const string &basename) cons
it != var_weights.end(); it++)
{
const string &name = it->first;
const string &value = it->second;
const NodeID value = it->second;
int id = symbol_table.getID(name) + 1;
output << "optim_weights_(" << id << "," << id << ") = " << value << ";\n";
output << "optim_weights_(" << id << "," << id << ") = ";
value->writeOutput(output);
output << ";" << endl;
output << "obj_var_ = [obj_var_; " << id << "];\n";
}
......@@ -682,10 +698,12 @@ OptimWeightsStatement::writeOutput(ostream &output, const string &basename) cons
{
const string &name1 = it->first.first;
const string &name2 = it->first.second;
const string &value = it->second;
const NodeID value = it->second;
int id1 = symbol_table.getID(name1) + 1;
int id2 = symbol_table.getID(name2) + 1;
output << "optim_weights_(" << id1 << "," << id2 << ") = " << value << ";\n";
output << "optim_weights_(" << id1 << "," << id2 << ") = ";
value->writeOutput(output);
output << ";" << endl;
output << "obj_var_ = [obj_var_; " << id1 << " " << id2 << "];\n";
}
}
......@@ -770,7 +788,7 @@ void
PlannerObjectiveStatement::computingPass()
{
model_tree->computeStaticHessian = true;
model_tree->computingPass();
model_tree->computingPass(eval_context_type());
}
void
......
......@@ -43,21 +43,14 @@ DataTree::AddVariable(const string &name, int lag)
symbol_table.SetReferenced(name);
int symb_id = symbol_table.getID(name);
Type type = symbol_table.getType(name);
int id;
if (type == eEndogenous
|| type == eExogenousDet
|| type == eExogenous
|| type == eRecursiveVariable)
id = variable_table.AddVariable(name, lag);
else
id = symbol_table.getID(name);
variable_node_map_type::iterator it = variable_node_map.find(make_pair(id, type));
variable_node_map_type::iterator it = variable_node_map.find(make_pair(make_pair(symb_id, type), lag));
if (it != variable_node_map.end())
return it->second;
else
return new VariableNode(*this, id, type);
return new VariableNode(*this, symb_id, type, lag);
}
NodeID
......@@ -346,3 +339,9 @@ DataTree::AddLocalParameter(const string &name, NodeID value) throw (LocalParame
local_parameters_table[id] = value;
}
NodeID
DataTree::AddUnknownFunction(const string &function_name, const vector<NodeID> &arguments)
{
return new UnknownFunctionNode(*this, function_name, arguments);
}
This diff is collapsed.
......@@ -7,11 +7,7 @@ using namespace std;
class ParsingDriver;
#include "SymbolTableTypes.hh"
#include "ExprNode.hh"
//! Type for semantic value of non-derivable expressions
typedef pair<int, Type> ExpObj;
%}
%parse-param { ParsingDriver &driver }
......@@ -30,8 +26,7 @@ typedef pair<int, Type> ExpObj;
%union
{
string *string_val;
ExpObj *exp_val;
NodeID model_val;
NodeID node_val;
};
%{
......@@ -75,8 +70,8 @@ typedef pair<int, Type> ExpObj;
%nonassoc POWER
%token EXP LOG LOG10 SIN COS TAN ASIN ACOS ATAN SINH COSH TANH ASINH ACOSH ATANH SQRT
%type <exp_val> expression comma_expression
%type <model_val> equation hand_side model_var
%type <node_val> expression
%type <node_val> equation hand_side model_var
%type <string_val> signed_float signed_integer prior
%type <string_val> value filename filename_elem vec_int_elem vec_int_1 vec_int
%type <string_val> calib_arg2 range
......@@ -255,54 +250,52 @@ cutoff
| NAME
{$$ = driver.add_expression_variable($1);}
| FLOAT_NUMBER
{$$ = driver.add_expression_constant($1);}
{$$ = driver.add_constant($1);}
| INT_NUMBER
{$$ = driver.add_expression_constant($1);}
{$$ = driver.add_constant($1);}
| expression PLUS expression
{$$ = driver.add_expression_token($1, $3, token::PLUS);}
{$$ = driver.add_plus($1, $3);}
| expression MINUS expression
{$$ = driver.add_expression_token($1, $3, token::MINUS);}
{$$ = driver.add_minus($1, $3);}
| expression DIVIDE expression
{$$ = driver.add_expression_token($1, $3, token::DIVIDE);}
{$$ = driver.add_divide($1, $3);}
| expression TIMES expression
{$$ = driver.add_expression_token($1, $3, token::TIMES);}
{$$ = driver.add_times($1, $3);}
| expression POWER expression
{$$ = driver.add_expression_token($1, $3, token::POWER);}
{$$ = driver.add_power($1, $3);}
| MINUS expression %prec UMINUS
{$$ = driver.add_expression_token($2, token::UMINUS);}
{$$ = driver.add_uminus($2);}
| PLUS expression
{$$ = $2;}
| EXP '(' expression ')'
{$$ = driver.add_expression_token($3, token::EXP);}
{$$ = driver.add_exp($3);}
| LOG '(' expression ')'
{$$ = driver.add_expression_token($3, token::LOG);}
{$$ = driver.add_log($3);}
| LOG10 '(' expression ')'
{$$ = driver.add_expression_token($3, token::LOG10);}
{$$ = driver.add_log10($3);}
| SIN '(' expression ')'
{$$ = driver.add_expression_token($3, token::SIN);}
{$$ = driver.add_sin($3);}
| COS '(' expression ')'
{$$ = driver.add_expression_token($3, token::COS);}
{$$ = driver.add_cos($3);}
| TAN '(' expression ')'
{$$ = driver.add_expression_token($3, token::TAN);}
{$$ = driver.add_tan($3);}
| ASIN '(' expression ')'
{$$ = driver.add_expression_token($3, token::ASIN);}
{$$ = driver.add_asin($3);}
| ACOS '(' expression ')'
{$$ = driver.add_expression_token($3, token::ACOS);}
{$$ = driver.add_acos($3);}
| ATAN '(' expression ')'
{$$ = driver.add_expression_token($3, token::ATAN);}
{$$ = driver.add_atan($3);}
| SQRT '(' expression ')'
{$$ = driver.add_expression_token($3, token::SQRT);}
| NAME '(' expression ')'
{$$ = driver.add_expression_token($3, $1);}
{$$ = driver.add_sqrt($3);}
| NAME '(' comma_expression ')'
{$$ = driver.add_expression_token($3, $1);}
{$$ = driver.add_unknown_function($1);}
;
comma_expression :
expression COMMA expression
{$$ = driver.add_expression_token($1, $3, token::COMMA);}
expression
{ driver.add_unknown_function_arg($1); }
| comma_expression COMMA expression
{$$ = driver.add_expression_token($1, $3, token::COMMA);}
{ driver.add_unknown_function_arg($3); }
initval
: INITVAL ';' initval_list END
......@@ -356,15 +349,15 @@ cutoff
;
model
: MODEL ';' { driver.begin_model(); } equation_list END
: MODEL ';' { driver.begin_model(); } equation_list END { driver.reset_data_tree(); }
| MODEL '(' o_linear ')' ';' { driver.begin_model(); }
equation_list END
equation_list END { driver.reset_data_tree(); }
| MODEL '(' USE_DLL ')' ';' { driver.begin_model(); driver.use_dll(); }
equation_list END
| MODEL '(' SPARSE_DLL COMMA model_sparse_options_list ')' { driver.sparse_dll(); driver.begin_model(); } ';'
equation_list END
| MODEL '(' SPARSE_DLL ')' { driver.sparse_dll(); driver.begin_model(); } ';'
equation_list END
equation_list END { driver.reset_data_tree(); }
| MODEL '(' SPARSE_DLL COMMA model_sparse_options_list ')' { driver.begin_model(); driver.sparse_dll(); } ';'
equation_list END { driver.reset_data_tree(); }
| MODEL '(' SPARSE_DLL ')' { driver.begin_model(); driver.sparse_dll(); } ';'
equation_list END { driver.reset_data_tree(); }
;
equation_list
......@@ -385,43 +378,43 @@ cutoff
: '(' hand_side ')' {$$ = $2;}
| model_var
| FLOAT_NUMBER
{$$ = driver.add_model_constant($1);}
{$$ = driver.add_constant($1);}
| INT_NUMBER
{$1->append(".0"); $$ = driver.add_model_constant($1);}
{$1->append(".0"); $$ = driver.add_constant($1);}
| hand_side PLUS hand_side
{$$ = driver.add_model_plus($1, $3);}
{$$ = driver.add_plus($1, $3);}
| hand_side MINUS hand_side
{$$ = driver.add_model_minus($1, $3);}
{$$ = driver.add_minus($1, $3);}
| hand_side DIVIDE hand_side
{$$ = driver.add_model_divide($1, $3);}
{$$ = driver.add_divide($1, $3);}
| hand_side TIMES hand_side
{$$ = driver.add_model_times($1, $3);}
{$$ = driver.add_times($1, $3);}
| hand_side POWER hand_side
{$$ = driver.add_model_power($1, $3);}
{$$ = driver.add_power($1, $3);}
| MINUS hand_side %prec UMINUS
{ $$ = driver.add_model_uminus($2);}
{ $$ = driver.add_uminus($2);}
| PLUS hand_side
{$$ = $2;}
| EXP '(' hand_side ')'
{$$ = driver.add_model_exp($3);}
{$$ = driver.add_exp($3);}
| LOG '(' hand_side ')'
{$$ = driver.add_model_log($3);}
{$$ = driver.add_log($3);}
| LOG10 '(' hand_side ')'
{$$ = driver.add_model_log10($3);}
{$$ = driver.add_log10($3);}
| SIN '(' hand_side ')'
{$$ = driver.add_model_sin($3);}
{$$ = driver.add_sin($3);}
| COS '(' hand_side ')'
{$$ = driver.add_model_cos($3);}
{$$ = driver.add_cos($3);}
| TAN '(' hand_side ')'
{$$ = driver.add_model_tan($3);}
{$$ = driver.add_tan($3);}
| ASIN '(' hand_side ')'
{$$ = driver.add_model_asin($3);}
{$$ = driver.add_asin($3);}
| ACOS '(' hand_side ')'
{$$ = driver.add_model_acos($3);}
{$$ = driver.add_acos($3);}
| ATAN '(' hand_side ')'
{$$ = driver.add_model_atan($3);}
{$$ = driver.add_atan($3);}
| SQRT '(' hand_side ')'
{$$ = driver.add_model_sqrt($3);}
{$$ = driver.add_sqrt($3);}
;
pound_expression: '#' NAME EQUAL hand_side ';'
......@@ -478,17 +471,17 @@ cutoff
value_list
: value_list signed_float
{driver.add_value($2);}
{driver.add_value_const($2);}
| value_list signed_integer
{driver.add_value($2);}
{driver.add_value_const($2);}
| value_list NAME
{driver.add_value($2);}
{driver.add_value_var($2);}
| signed_float
{driver.add_value($1);}
{driver.add_value_const($1);}
| signed_integer
{driver.add_value($1);}
{driver.add_value_const($1);}
| NAME
{driver.add_value($1);}
{driver.add_value_var($1);}
| value_list '(' expression ')'
{driver.add_value($3);}
| '(' expression ')'
......@@ -511,21 +504,21 @@ cutoff
: triangular_row COMMA '(' expression ')'
{driver.add_to_row($4);}
| triangular_row COMMA FLOAT_NUMBER
{driver.add_to_row($3);}
{driver.add_to_row_const($3);}
| triangular_row COMMA INT_NUMBER
{driver.add_to_row($3);}
{driver.add_to_row_const($3);}
| triangular_row '(' expression ')'
{driver.add_to_row($3);}
| triangular_row FLOAT_NUMBER
{driver.add_to_row($2);}
{driver.add_to_row_const($2);}
| triangular_row INT_NUMBER
{driver.add_to_row($2);}
{driver.add_to_row_const($2);}
| '(' expression ')'
{driver.add_to_row($2);}
| FLOAT_NUMBER
{driver.add_to_row($1);}
{driver.add_to_row_const($1);}
| INT_NUMBER
{driver.add_to_row($1);}
{driver.add_to_row_const($1);}
;
steady
......
This diff is collapsed.
/*! \file
\version 1.0
\date 04/09/2004
\par This file implements the Expression class methodes.
*/
//------------------------------------------------------------------------------
#include <stack>
using namespace std;
//------------------------------------------------------------------------------
#include "Expression.hh"
#include "OperatorTable.hh"
Expression::Expression()
{
// Empty
}
//------------------------------------------------------------------------------
Expression::~Expression()
{
// Empty
}
void
Expression::setNumericalConstants(NumericalConstants *num_constants_arg)
{
num_constants = num_constants_arg;
}
int Expression::AddToken(int id1,Type type1,int id2,Type type2,int op_code)
{
Token token;
// Making token structure
token.id1 = id1;
token.type1 = type1;
token.id2 = id2;
token.type2 = type2;
token.op_code = op_code;
token.op_name = OperatorTable::str(op_code);
// Inserting token into expression_list
expression_list.push_back(token);
return expression_list.size() -1;
}
//------------------------------------------------------------------------------
int Expression::AddToken(int id1,Type type1,int op_code)
{
Token token;
// Making token structure
token.id1 = id1;
token.type1 = type1;
token.id2 = -1;
token.type2 = eUNDEF;
token.op_code = op_code;
token.op_name = OperatorTable::str(op_code);;
// Inserting token into expression_list
expression_list.push_back(token);
return expression_list.size() -1;
}
//------------------------------------------------------------------------------
int Expression::AddToken(int id1,Type type1, string ufunction)
{
Token token;
// Making token structure
token.id1 = id1;
token.type1 = type1;
token.id2 = -1;
token.type2 = eUNDEF;
token.op_code = token::NAME;
token.op_name = ufunction;
// Inserting token into expression_list
expression_list.push_back(token);
return expression_list.size() -1;
}
//------------------------------------------------------------------------------
void Expression::set(void)
{
// Stack of temporary tokens
stack <int, vector<Token> > stack_token;
// Dtack of temporary expressions
stack <int, vector<string> > stack_expression;
// Temporary output
ostringstream exp;
// temporary variables for saving arguments and name oparator
string argument1, argument2, op_name;
// Define type for type operator (binary or unary)
enum OperatorType
{
unary,
binary
};
OperatorType op_type;
int current_op, last_op;
// Clearing output string
output.str("");
// Starting from the end of list
stack_token.push(expression_list.back());
// Main loop :
// Repeat for last token from the stack
// (1) if argument is temporary result, and not yet followed,
// set it as followed (flag) and push corresponding token
// on the token stack
// (2) argument followed, or final argument
// (2.1) if argument is followed
// - set argument1 (or argument2) by last expression on
// expression tack
// - pop last expression from expression stack
// (2.2) if final argument
// set argument1 (or argument2) by final argument
// (3) set op_name by last token from the token stack
// (3) pop last token from the token stack
// (4) write temporary expression (using argument1, argument2
// and op_name) and push it on the expression stack
// (5)
while (stack_token.size() > 0)
{
// First argument is a temporary result,
// pushing token on token stack and setting that argument to be followed
if ((stack_token.top().type1 == eTempResult) &&
(stack_token.top().followed1 == false))
{
stack_token.top().followed1 = true;
stack_token.push(expression_list[stack_token.top().id1]);
}
// Second argument is a temporary result,
// pushing token on stack and setting that argument to be followed
else if ((stack_token.top().type2 == eTempResult) &&
(stack_token.top().followed2 == false))
{
stack_token.top().followed2 = true;
stack_token.push(expression_list[stack_token.top().id2]);
}
// Writing expression
else
{
// Final token, no argment followed
if ((stack_token.top().followed1 == false) &&
(stack_token.top().followed2 == false))
{
argument1 = getArgument(stack_token.top().type1,stack_token.top().id1);
current_op = stack_token.top().op_code;
// Testing if unary or binary token
if (stack_token.top().id2 >= 0)
{
argument2 = getArgument(stack_token.top().type2,stack_token.top().id2);
op_type = binary;
}
else
{
op_type = unary;
}
}
// Both arguments are followed, writing stacked expressions
else if ((stack_token.top().followed1 == true) &&
(stack_token.top().followed2 == true))
{
// Testing if unary or binary token
if (stack_token.top().id2 >= 0)
{