ParsingDriver.cc 84.4 KB
Newer Older
1
/*
2
 * Copyright (C) 2003-2017 Dynare Team
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
 *
 * This file is part of Dynare.
 *
 * Dynare is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Dynare is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
 */

20
#include <cstdlib>
21 22
#include <fstream>
#include <iostream>
23
#include <cassert>
Sébastien Villemot's avatar
Sébastien Villemot committed
24
#include <sstream>
25
#include <cmath>
26 27 28

#include "ParsingDriver.hh"
#include "Statement.hh"
29
#include "ExprNode.hh"
30
#include "WarningConsolidation.hh"
31 32

bool
33
ParsingDriver::symbol_exists_and_is_not_modfile_local_or_external_function(const char *s)
34 35 36 37
{
  if (!mod_file->symbol_table.exists(s))
    return false;

38 39
  SymbolType type = mod_file->symbol_table.getType(s);

40
  return (type != eModFileLocalVariable && type != eExternalFunction);
41 42
}

43 44 45 46 47 48 49
void
ParsingDriver::check_symbol_existence_in_model_block(const string &name)
{
  if (!mod_file->symbol_table.exists(name))
    model_error("Unknown symbol: " + name);
}

50 51 52 53 54 55 56
void
ParsingDriver::check_symbol_existence(const string &name)
{
  if (!mod_file->symbol_table.exists(name))
    error("Unknown symbol: " + name);
}

57 58 59 60 61 62 63 64 65
void
ParsingDriver::check_symbol_is_parameter(string *name)
{
  check_symbol_existence(*name);
  int symb_id = mod_file->symbol_table.getID(*name);
  if (mod_file->symbol_table.getType(symb_id) != eParameter)
    error(*name + " is not a parameter");
}

66 67 68 69 70
void
ParsingDriver::set_current_data_tree(DataTree *data_tree_arg)
{
  data_tree = data_tree_arg;
  model_tree = dynamic_cast<ModelTree *>(data_tree_arg);
71
  dynamic_model = dynamic_cast<DynamicModel *>(data_tree_arg);
72 73 74 75 76 77 78 79
}

void
ParsingDriver::reset_data_tree()
{
  set_current_data_tree(&mod_file->expressions_tree);
}

80 81 82 83 84 85
void
ParsingDriver::reset_current_external_function_options()
{
  current_external_function_options.nargs = eExtFunSetDefaultNargs;
  current_external_function_options.firstDerivSymbID = eExtFunNotSet;
  current_external_function_options.secondDerivSymbID = eExtFunNotSet;
86
  current_external_function_id = eExtFunNotSet;
87 88
}

89
ModFile *
90
ParsingDriver::parse(istream &in, bool debug)
91
{
92
  mod_file = new ModFile(warnings);
93

sebastien's avatar
sebastien committed
94
  symbol_list.clear();
95 96

  reset_data_tree();
97
  estim_params.init(*data_tree);
98
  osr_params.init(*data_tree);
99
  reset_current_external_function_options();
100 101

  lexer = new DynareFlex(&in);
102
  lexer->set_debug(debug);
103 104

  Dynare::parser parser(*this);
105
  parser.set_debug_level(debug);
106 107 108 109 110 111 112 113 114 115
  parser.parse();

  delete lexer;

  return mod_file;
}

void
ParsingDriver::error(const Dynare::parser::location_type &l, const string &m)
{
116 117 118 119 120 121 122 123 124 125 126 127 128 129
  create_error_string(l, m, cerr);
  exit(EXIT_FAILURE);
}

void
ParsingDriver::error(const string &m)
{
  error(location, m);
}

void
ParsingDriver::create_error_string(const Dynare::parser::location_type &l, const string &m, ostream &stream)
{
  stream << "ERROR: " << *l.begin.filename << ": line " << l.begin.line;
130 131
  if (l.begin.line == l.end.line)
    if (l.begin.column == l.end.column - 1)
132
      stream << ", col " << l.begin.column;
133
    else
134
      stream << ", cols " << l.begin.column << "-" << l.end.column - 1;
135
  else
136
    stream << ", col " << l.begin.column << " -"
137
           << " line " << l.end.line << ", col " << l.end.column - 1;
138
  stream << ": " << m << endl;
139 140 141
}

void
142
ParsingDriver::model_error(const string &m)
143
{
144 145
  create_error_string(location, m, model_errors);
  model_error_encountered = true;
146 147 148 149 150
}

void
ParsingDriver::warning(const string &m)
{
151
  warnings << "WARNING: " << location << ": " << m << endl;
152 153 154
}

void
155
ParsingDriver::declare_symbol(const string *name, SymbolType type, const string *tex_name, const vector<pair<string *, string *> *> *partition_value)
156 157 158
{
  try
    {
159
      if (tex_name == NULL && partition_value == NULL)
160 161
        mod_file->symbol_table.addSymbol(*name, type);
      else
162
        if (tex_name == NULL)
163 164 165
          mod_file->symbol_table.addSymbol(*name, type, "", partition_value);
        else if (partition_value == NULL)
          mod_file->symbol_table.addSymbol(*name, type, *tex_name, NULL);
166
        else
167
          mod_file->symbol_table.addSymbol(*name, type, *tex_name, partition_value);
168
    }
169
  catch (SymbolTable::AlreadyDeclaredException &e)
170 171 172 173 174 175 176 177 178
    {
      if (e.same_type)
        warning("Symbol " + *name + " declared twice.");
      else
        error("Symbol " + *name + " declared twice with different types!");
    }
}

void
179
ParsingDriver::declare_endogenous(string *name, string *tex_name, vector<pair<string *, string *> *> *partition_value)
180
{
181
  declare_symbol(name, eEndogenous, tex_name, partition_value);
182 183 184
  delete name;
  if (tex_name != NULL)
    delete tex_name;
185 186
  if (partition_value != NULL)
    {
187 188 189 190 191 192 193
      for (vector<pair<string *, string *> *>::iterator it = partition_value->begin();
           it != partition_value->end(); ++it)
        {
          delete (*it)->first;
          delete (*it)->second;
          delete (*it);
        }
194 195
      delete partition_value;
    }
196 197 198
}

void
199
ParsingDriver::declare_exogenous(string *name, string *tex_name, vector<pair<string *, string *> *> *partition_value)
200
{
201
  declare_symbol(name, eExogenous, tex_name, partition_value);
202 203 204
  delete name;
  if (tex_name != NULL)
    delete tex_name;
205 206
  if (partition_value != NULL)
    {
207 208 209 210 211 212 213
      for (vector<pair<string *, string *> *>::iterator it = partition_value->begin();
           it != partition_value->end(); ++it)
        {
          delete (*it)->first;
          delete (*it)->second;
          delete (*it);
        }
214 215
      delete partition_value;
    }
216 217 218
}

void
219
ParsingDriver::declare_exogenous_det(string *name, string *tex_name, vector<pair<string *, string *> *> *partition_value)
220
{
221
  declare_symbol(name, eExogenousDet, tex_name, partition_value);
222 223 224
  delete name;
  if (tex_name != NULL)
    delete tex_name;
225 226
  if (partition_value != NULL)
    {
227 228 229 230 231 232 233
      for (vector<pair<string *, string *> *>::iterator it = partition_value->begin();
           it != partition_value->end(); ++it)
        {
          delete (*it)->first;
          delete (*it)->second;
          delete (*it);
        }
234 235
      delete partition_value;
    }
236 237 238
}

void
239
ParsingDriver::declare_parameter(string *name, string *tex_name, vector<pair<string *, string *> *> *partition_value)
240
{
241
  declare_symbol(name, eParameter, tex_name, partition_value);
242 243 244
  delete name;
  if (tex_name != NULL)
    delete tex_name;
245 246
  if (partition_value != NULL)
    {
247 248 249 250 251 252 253
      for (vector<pair<string *, string *> *>::iterator it = partition_value->begin();
           it != partition_value->end(); ++it)
        {
          delete (*it)->first;
          delete (*it)->second;
          delete (*it);
        }
254 255
      delete partition_value;
    }
256 257
}

258 259 260 261
void
ParsingDriver::declare_statement_local_variable(string *name)
{
  if (mod_file->symbol_table.exists(*name))
262 263
    error("Symbol " + *name + " cannot be assigned within a statement "
          +"while being assigned elsewhere in the modfile");
264
  declare_symbol(name, eStatementDeclaredVariable, NULL, NULL);
265 266 267
  delete name;
}

268
void
269
ParsingDriver::declare_optimal_policy_discount_factor_parameter(expr_t exprnode)
270
{
271 272 273 274
  string *optimalParName_declare = new string("optimal_policy_discount_factor");
  string *optimalParName_init = new string("optimal_policy_discount_factor");
  declare_parameter(optimalParName_declare, NULL);
  init_param(optimalParName_init, exprnode);
275 276
}

277 278 279 280 281 282 283
void
ParsingDriver::begin_trend()
{
  set_current_data_tree(&mod_file->dynamic_model);
}

void
284
ParsingDriver::declare_trend_var(bool log_trend, string *name, string *tex_name)
285
{
286
  declare_symbol(name, log_trend ? eLogTrend : eTrend, tex_name, NULL);
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
  declared_trend_vars.push_back(mod_file->symbol_table.getID(*name));
  delete name;
  if (tex_name != NULL)
    delete tex_name;
}

void
ParsingDriver::end_trend_var(expr_t growth_factor)
{
  try
    {
      dynamic_model->addTrendVariables(declared_trend_vars, growth_factor);
    }
  catch (DataTree::TrendException &e)
    {
      error("Trend variable " + e.name + " was declared twice.");
    }
  declared_trend_vars.clear();
  reset_data_tree();
}

308 309 310
void
ParsingDriver::add_predetermined_variable(string *name)
{
sebastien's avatar
sebastien committed
311 312 313 314 315 316 317 318
  try
    {
      int symb_id = mod_file->symbol_table.getID(*name);
      if (mod_file->symbol_table.getType(symb_id) != eEndogenous)
        error("Predetermined variables must be endogenous variables");

      mod_file->symbol_table.markPredetermined(symb_id);
    }
319
  catch (SymbolTable::UnknownSymbolNameException &e)
sebastien's avatar
sebastien committed
320 321 322
    {
      error("Undeclared symbol name: " + *name);
    }
323 324 325
  delete name;
}

326 327 328
void
ParsingDriver::add_equation_tags(string *key, string *value)
{
329
  eq_tags.push_back(make_pair(*key, *value));
330 331 332 333
  delete key;
  delete value;
}

334
expr_t
335
ParsingDriver::add_non_negative_constant(string *constant)
336
{
337
  expr_t id = data_tree->AddNonNegativeConstant(*constant);
338 339 340 341
  delete constant;
  return id;
}

342
expr_t
343 344 345 346 347
ParsingDriver::add_nan_constant()
{
  return data_tree->NaN;
}

348
expr_t
349 350 351 352 353
ParsingDriver::add_inf_constant()
{
  return data_tree->Infinity;
}

354
expr_t
355 356
ParsingDriver::add_model_variable(string *name)
{
357 358 359 360 361
  check_symbol_existence_in_model_block(*name);
  int symb_id;
  try
    {
      symb_id = mod_file->symbol_table.getID(*name);
362 363
      if (undeclared_model_vars.find(*name) != undeclared_model_vars.end())
        model_error("Unknown symbol: " + *name);
364 365 366
    }
  catch (SymbolTable::UnknownSymbolNameException &e)
    {
367 368
      // This could be endog or param too. Just declare something to continue parsing,
      // knowing that processing will end at the end of parsing of the model block
369
      declare_exogenous(new string(*name));
370
      undeclared_model_vars.insert(*name);
371 372
      symb_id = mod_file->symbol_table.getID(*name);
    }
373 374
  delete name;
  return add_model_variable(symb_id, 0);
375 376
}

377
expr_t
378
ParsingDriver::add_model_variable(int symb_id, int lag)
379
{
380 381
  assert(symb_id >= 0);
  SymbolType type = mod_file->symbol_table.getType(symb_id);
382 383

  if (type == eModFileLocalVariable)
384
    error("Variable " + mod_file->symbol_table.getName(symb_id) + " not allowed inside model declaration. Its scope is only outside model.");
385

386
  if (type == eExternalFunction)
387
    error("Symbol " + mod_file->symbol_table.getName(symb_id) + " is a function name external to Dynare. It cannot be used like a variable without input argument inside model.");
sebastien's avatar
sebastien committed
388 389

  if (type == eModelLocalVariable && lag != 0)
390
    error("Model local variable " + mod_file->symbol_table.getName(symb_id) + " cannot be given a lead or a lag.");
sebastien's avatar
sebastien committed
391

392 393 394
  if (dynamic_cast<StaticModel *>(model_tree) != NULL && lag != 0)
    error("Leads and lags on variables are forbidden in 'planner_objective'.");

395 396 397
  if (dynamic_cast<StaticModel *>(model_tree) != NULL && type == eModelLocalVariable)
    error("Model local variable " + mod_file->symbol_table.getName(symb_id) + " cannot be used in 'planner_objective'.");

sebastien's avatar
sebastien committed
398
  // It makes sense to allow a lead/lag on parameters: during steady state calibration, endogenous and parameters can be swapped
399
  return model_tree->AddVariable(symb_id, lag);
400 401
}

402
expr_t
403 404 405 406 407 408
ParsingDriver::add_expression_variable(string *name)
{
  // If symbol doesn't exist, then declare it as a mod file local variable
  if (!mod_file->symbol_table.exists(*name))
    mod_file->symbol_table.addSymbol(*name, eModFileLocalVariable);

409 410 411 412
  // This check must come after the previous one!
  if (mod_file->symbol_table.getType(*name) == eModelLocalVariable)
    error("Variable " + *name + " not allowed outside model declaration. Its scope is only inside model.");

413 414 415 416
  if (mod_file->symbol_table.getType(*name) == eTrend
      || mod_file->symbol_table.getType(*name) == eLogTrend)
    error("Variable " + *name + " not allowed outside model declaration, because it is a trend variable.");

417 418 419
  if (mod_file->symbol_table.getType(*name) == eExternalFunction)
    error("Symbol '" + *name + "' is the name of a MATLAB/Octave function, and cannot be used as a variable.");

420
  int symb_id = mod_file->symbol_table.getID(*name);
421
  expr_t id = data_tree->AddVariable(symb_id);
422 423 424 425 426

  delete name;
  return id;
}

427
void
428
ParsingDriver::declare_nonstationary_var(string *name, string *tex_name, vector<pair<string *, string *> *> *partition_value)
429
{
430
  if (tex_name == NULL && partition_value == NULL)
431
    declare_endogenous(new string(*name));
432 433
  else
    if (tex_name == NULL)
434
      declare_endogenous(new string(*name), NULL, partition_value);
435
    else if (partition_value == NULL)
436
      declare_endogenous(new string(*name), tex_name);
437
    else
438
      declare_endogenous(new string(*name), tex_name, partition_value);
439

440 441 442 443 444 445
  declared_nonstationary_vars.push_back(mod_file->symbol_table.getID(*name));
  mod_file->nonstationary_variables = true;
  delete name;
}

void
446
ParsingDriver::end_nonstationary_var(bool log_deflator, expr_t deflator)
447 448 449
{
  try
    {
450
      dynamic_model->addNonstationaryVariables(declared_nonstationary_vars, log_deflator, deflator);
451 452 453 454 455
    }
  catch (DataTree::TrendException &e)
    {
      error("Variable " + e.name + " was listed more than once as following a trend.");
    }
456

457
  set<int> r;
458
  deflator->collectVariables(eEndogenous, r);
459 460
  for (set<int>::const_iterator it = r.begin(); it != r.end(); ++it)
    if (dynamic_model->isNonstationary(*it))
461 462
      error("The deflator contains a non-stationary endogenous variable. This is not allowed. Please use only stationary endogenous and/or {log_}trend_vars.");

463 464 465 466
  declared_nonstationary_vars.clear();
  reset_data_tree();
}

467 468 469
void
ParsingDriver::periods(string *periods)
{
470
  warning("periods: this command is now deprecated and may be removed in a future version of Dynare. Please use the ''periods'' option of the ''simul'' command instead.");
471

472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495
  int periods_val = atoi(periods->c_str());
  mod_file->addStatement(new PeriodsStatement(periods_val));
  delete periods;
}

void
ParsingDriver::dsample(string *arg1)
{
  int arg1_val = atoi(arg1->c_str());
  mod_file->addStatement(new DsampleStatement(arg1_val));
  delete arg1;
}

void
ParsingDriver::dsample(string *arg1, string *arg2)
{
  int arg1_val = atoi(arg1->c_str());
  int arg2_val = atoi(arg2->c_str());
  mod_file->addStatement(new DsampleStatement(arg1_val, arg2_val));
  delete arg1;
  delete arg2;
}

void
496
ParsingDriver::init_param(string *name, expr_t rhs)
497
{
498
  check_symbol_is_parameter(name);
sebastien's avatar
sebastien committed
499 500
  int symb_id = mod_file->symbol_table.getID(*name);
  mod_file->addStatement(new InitParamStatement(symb_id, rhs, mod_file->symbol_table));
501 502 503 504
  delete name;
}

void
505
ParsingDriver::init_val(string *name, expr_t rhs)
506
{
507 508 509
  if (nostrict)
    if (!mod_file->symbol_table.exists(*name))
      {
510
        warning("discarding '" + *name + "' as it was not recognized in the initval or endval statement");
511 512 513 514
        delete name;
        return;
      }

515
  check_symbol_existence(*name);
sebastien's avatar
sebastien committed
516 517
  int symb_id = mod_file->symbol_table.getID(*name);
  SymbolType type = mod_file->symbol_table.getType(symb_id);
518 519 520 521 522

  if (type != eEndogenous
      && type != eExogenous
      && type != eExogenousDet)
    error("initval/endval: " + *name + " should be an endogenous or exogenous variable");
sebastien's avatar
sebastien committed
523 524 525

  init_values.push_back(make_pair(symb_id, rhs));

526 527 528 529
  delete name;
}

void
michel's avatar
michel committed
530
ParsingDriver::initval_file(string *filename)
531
{
sebastien's avatar
sebastien committed
532
  mod_file->addStatement(new InitvalFileStatement(*filename));
533 534 535 536
  delete filename;
}

void
537
ParsingDriver::hist_val(string *name, string *lag, expr_t rhs)
538 539
{
  check_symbol_existence(*name);
sebastien's avatar
sebastien committed
540 541
  int symb_id = mod_file->symbol_table.getID(*name);
  SymbolType type = mod_file->symbol_table.getType(symb_id);
542 543 544 545

  if (type != eEndogenous
      && type != eExogenous
      && type != eExogenousDet)
Sébastien Villemot's avatar
Sébastien Villemot committed
546
    error("histval: " + *name + " should be an endogenous or exogenous variable");
547 548

  int ilag = atoi(lag->c_str());
549 550 551
  if (ilag > 0)
    error("histval: the lag on " + *name + " should be less than or equal to 0");

sebastien's avatar
sebastien committed
552
  pair<int, int> key(symb_id, ilag);
553

Sébastien Villemot's avatar
Sébastien Villemot committed
554
  if (mod_file->dynamic_model.minLagForSymbol(symb_id) > ilag - 1)
555
    hist_vals_wrong_lag[symb_id] = ilag;
Sébastien Villemot's avatar
Sébastien Villemot committed
556

557 558 559 560 561 562 563 564 565 566
  if (hist_values.find(key) != hist_values.end())
    error("hist_val: (" + *name + ", " + *lag + ") declared twice");

  hist_values[key] = rhs;

  delete name;
  delete lag;
}

void
567
ParsingDriver::homotopy_val(string *name, expr_t val1, expr_t val2)
568 569
{
  check_symbol_existence(*name);
sebastien's avatar
sebastien committed
570 571
  int symb_id = mod_file->symbol_table.getID(*name);
  SymbolType type = mod_file->symbol_table.getType(symb_id);
572 573 574 575 576 577

  if (type != eParameter
      && type != eExogenous
      && type != eExogenousDet)
    error("homotopy_val: " + *name + " should be a parameter or exogenous variable");

sebastien's avatar
sebastien committed
578
  homotopy_values.push_back(make_pair(symb_id, make_pair(val1, val2)));
579 580 581 582

  delete name;
}

583 584 585 586
void
ParsingDriver::end_generate_irfs()
{
  mod_file->addStatement(new GenerateIRFsStatement(options_list, generate_irf_names, generate_irf_elements));
587

588 589 590 591 592 593
  generate_irf_elements.clear();
  generate_irf_names.clear();
  options_list.clear();
}

void
594
ParsingDriver::add_generate_irfs_element(string *name)
595 596 597 598
{
  for (vector<string>::const_iterator it = generate_irf_names.begin();
       it != generate_irf_names.end(); it++)
    if (*it == *name)
599 600
      error("Names in the generate_irfs block must be unique but you entered '"
            + *name + "' more than once.");
601 602

  generate_irf_names.push_back(*name);
603 604 605
  generate_irf_elements.push_back(generate_irf_exos);

  generate_irf_exos.clear();
606 607

  delete name;
608 609 610 611 612 613 614 615 616 617 618 619 620
}

void
ParsingDriver::add_generate_irfs_exog_element(string *exo, string *value)
{
  check_symbol_is_exogenous(exo);
  if (generate_irf_exos.find(*exo) != generate_irf_exos.end())
    error("You have set the exogenous variable " + *exo + " twice.");

  generate_irf_exos[*exo] = atof(value->c_str());

  delete exo;
  delete value;
621 622
}

623 624 625 626 627 628 629 630
void
ParsingDriver::forecast()
{
  mod_file->addStatement(new ForecastStatement(symbol_list, options_list));
  symbol_list.clear();
  options_list.clear();
}

631 632 633
void
ParsingDriver::use_dll()
{
634
  mod_file->use_dll = true;
635 636 637
}

void
638
ParsingDriver::block()
639
{
640
  mod_file->block = true;
641 642
}

643 644 645 646 647 648
void
ParsingDriver::no_static()
{
  mod_file->no_static = true;
}

649
void
650
ParsingDriver::byte_code()
651
{
652
  mod_file->byte_code = true;
653 654
}

655
void
656
ParsingDriver::differentiate_forward_vars_all()
657 658 659 660
{
  mod_file->differentiate_forward_vars = true;
}

661 662 663 664 665 666 667 668 669 670 671 672 673 674 675
void
ParsingDriver::differentiate_forward_vars_some()
{
  mod_file->differentiate_forward_vars = true;
  mod_file->differentiate_forward_vars_subset = symbol_list.get_symbols();
  for (vector<string>::const_iterator it = mod_file->differentiate_forward_vars_subset.begin();
       it != mod_file->differentiate_forward_vars_subset.end(); ++it)
    {
      check_symbol_existence(*it);
      if (mod_file->symbol_table.getType(*it) != eEndogenous)
        error("Symbol " + *it + " is not an endogenous");
    }
  symbol_list.clear();
}

676 677 678 679 680
void
ParsingDriver::cutoff(string *value)
{
  double val = atof(value->c_str());
  mod_file->dynamic_model.cutoff = val;
681
  mod_file->static_model.cutoff = val;
682 683 684 685 686 687 688 689
  delete value;
}

void
ParsingDriver::mfs(string *value)
{
  int val = atoi(value->c_str());
  mod_file->dynamic_model.mfs = val;
690
  mod_file->static_model.mfs = val;
691 692 693
  delete value;
}

694
void
695
ParsingDriver::end_initval(bool all_values_required)
696
{
697
  mod_file->addStatement(new InitValStatement(init_values, mod_file->symbol_table, all_values_required));
sebastien's avatar
sebastien committed
698
  init_values.clear();
699 700 701
}

void
702
ParsingDriver::end_endval(bool all_values_required)
703
{
704
  mod_file->addStatement(new EndValStatement(init_values, mod_file->symbol_table, all_values_required));
sebastien's avatar
sebastien committed
705
  init_values.clear();
706 707 708
}

void
709
ParsingDriver::end_histval(bool all_values_required)
710
{
711
  mod_file->addStatement(new HistValStatement(hist_values, hist_vals_wrong_lag, mod_file->symbol_table, all_values_required));
712 713 714 715 716 717 718 719 720 721 722 723 724
  hist_values.clear();
}

void
ParsingDriver::end_homotopy()
{
  mod_file->addStatement(new HomotopyStatement(homotopy_values, mod_file->symbol_table));
  homotopy_values.clear();
}

void
ParsingDriver::begin_model()
{
sebastien's avatar
sebastien committed
725
  set_current_data_tree(&mod_file->dynamic_model);
726 727
}

728 729 730 731 732 733 734 735 736 737 738
void
ParsingDriver::end_model()
{
  if (model_error_encountered)
    {
      cerr << model_errors.str();
      exit(EXIT_FAILURE);
    }
  reset_data_tree();
}

739
void
740
ParsingDriver::end_shocks(bool overwrite)
741
{
742
  mod_file->addStatement(new ShocksStatement(overwrite, det_shocks, var_shocks, std_shocks,
743 744 745 746 747 748 749 750 751
                                             covar_shocks, corr_shocks, mod_file->symbol_table));
  det_shocks.clear();
  var_shocks.clear();
  std_shocks.clear();
  covar_shocks.clear();
  corr_shocks.clear();
}

void
752
ParsingDriver::end_mshocks(bool overwrite)
753
{
754
  mod_file->addStatement(new MShocksStatement(overwrite, det_shocks, mod_file->symbol_table));
755 756 757 758
  det_shocks.clear();
}

void
759
ParsingDriver::add_det_shock(string *var, bool conditional_forecast)
760 761
{
  check_symbol_existence(*var);
Sébastien Villemot's avatar
Sébastien Villemot committed
762 763
  int symb_id = mod_file->symbol_table.getID(*var);
  SymbolType type = mod_file->symbol_table.getType(symb_id);
764 765 766 767

  if (conditional_forecast)
    {
      if (type != eEndogenous)
768
        error("conditional_forecast_paths: shocks can only be applied to endogenous variables");
769 770 771 772 773 774
    }
  else
    {
      if (type != eExogenous && type != eExogenousDet)
        error("shocks: shocks can only be applied to exogenous variables");
    }
775

Sébastien Villemot's avatar
Sébastien Villemot committed
776
  if (det_shocks.find(symb_id) != det_shocks.end())
777
    error("shocks/conditional_forecast_paths: variable " + *var + " declared twice");
778 779

  if (det_shocks_periods.size() != det_shocks_values.size())
780
    error("shocks/conditional_forecast_paths: variable " + *var + ": number of periods is different from number of shock values");
781 782 783

  vector<ShocksStatement::DetShockElement> v;

784
  for (size_t i = 0; i < det_shocks_periods.size(); i++)
785 786 787 788 789 790 791 792
    {
      ShocksStatement::DetShockElement dse;
      dse.period1 = det_shocks_periods[i].first;
      dse.period2 = det_shocks_periods[i].second;
      dse.value = det_shocks_values[i];
      v.push_back(dse);
    }

793
  det_shocks[symb_id] = v;
794

795 796 797 798 799 800
  det_shocks_periods.clear();
  det_shocks_values.clear();
  delete var;
}

void
801
ParsingDriver::add_stderr_shock(string *var, expr_t value)
802 803
{
  check_symbol_existence(*var);
Sébastien Villemot's avatar
Sébastien Villemot committed
804 805 806 807
  int symb_id = mod_file->symbol_table.getID(*var);

  if (var_shocks.find(symb_id) != var_shocks.end()
      || std_shocks.find(symb_id) != std_shocks.end())
808 809
    error("shocks: variance or stderr of shock on " + *var + " declared twice");

Sébastien Villemot's avatar
Sébastien Villemot committed
810
  std_shocks[symb_id] = value;
811 812 813 814 815

  delete var;
}

void
816
ParsingDriver::add_var_shock(string *var, expr_t value)
817 818
{
  check_symbol_existence(*var);
Sébastien Villemot's avatar
Sébastien Villemot committed
819 820 821 822
  int symb_id = mod_file->symbol_table.getID(*var);

  if (var_shocks.find(symb_id) != var_shocks.end()
      || std_shocks.find(symb_id) != std_shocks.end())
823 824
    error("shocks: variance or stderr of shock on " + *var + " declared twice");

Sébastien Villemot's avatar
Sébastien Villemot committed
825
  var_shocks[symb_id] = value;
826 827 828 829 830

  delete var;
}

void
831
ParsingDriver::add_covar_shock(string *var1, string *var2, expr_t value)
832 833 834
{
  check_symbol_existence(*var1);
  check_symbol_existence(*var2);
Sébastien Villemot's avatar
Sébastien Villemot committed
835 836
  int symb_id1 = mod_file->symbol_table.getID(*var1);
  int symb_id2 = mod_file->symbol_table.getID(*var2);
837

Sébastien Villemot's avatar
Sébastien Villemot committed
838
  pair<int, int> key(symb_id1, symb_id2), key_inv(symb_id2, symb_id1);
839 840 841 842 843 844 845 846 847 848 849 850 851 852 853

  if (covar_shocks.find(key) != covar_shocks.end()
      || covar_shocks.find(key_inv) != covar_shocks.end()
      || corr_shocks.find(key) != corr_shocks.end()
      || corr_shocks.find(key_inv) != corr_shocks.end())
    error("shocks: covariance or correlation shock on variable pair (" + *var1 + ", "
          + *var2 + ") declared twice");

  covar_shocks[key] = value;

  delete var1;
  delete var2;
}

void
854
ParsingDriver::add_correl_shock(string *var1, string *var2, expr_t value)
855 856 857
{
  check_symbol_existence(*var1);
  check_symbol_existence(*var2);
Sébastien Villemot's avatar
Sébastien Villemot committed
858 859 860 861
  int symb_id1 = mod_file->symbol_table.getID(*var1);
  int symb_id2 = mod_file->symbol_table.getID(*var2);

  pair<int, int> key(symb_id1, symb_id2), key_inv(symb_id2, symb_id1);
862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880

  if (covar_shocks.find(key) != covar_shocks.end()
      || covar_shocks.find(key_inv) != covar_shocks.end()
      || corr_shocks.find(key) != corr_shocks.end()
      || corr_shocks.find(key_inv) != corr_shocks.end())
    error("shocks: covariance or correlation shock on variable pair (" + *var1 + ", "
          + *var2 + ") declared twice");

  corr_shocks[key] = value;

  delete var1;
  delete var2;
}

void
ParsingDriver::add_period(string *p1, string *p2)
{
  int p1_val = atoi(p1->c_str());
  int p2_val = atoi(p2->c_str());
881 882
  if (p1_val > p2_val)
    error("shocks/conditional_forecast_paths: can't have first period index greater than second index in range specification");
883 884 885 886 887 888 889 890 891 892 893 894 895 896
  det_shocks_periods.push_back(make_pair(p1_val, p2_val));
  delete p1;
  delete p2;
}

void
ParsingDriver::add_period(string *p1)
{
  int p1_val = atoi(p1->c_str());
  det_shocks_periods.push_back(make_pair(p1_val, p1_val));
  delete p1;
}

void
897
ParsingDriver::add_value(expr_t value)
898 899 900 901 902
{
  det_shocks_values.push_back(value);
}

void
903
ParsingDriver::add_value(string *v)
904
{
905
  expr_t id;
906 907 908 909 910

  if (v->at(0) == '-')
    id = data_tree->AddUMinus(data_tree->AddNonNegativeConstant(v->substr(1, string::npos)));
  else
    id = data_tree->AddNonNegativeConstant(*v);
911

912 913
  delete v;
  det_shocks_values.push_back(id);
914 915
}

Houtan Bastani's avatar
Houtan Bastani committed
916 917 918 919 920 921 922 923
void
ParsingDriver::begin_svar_identification()
{
  svar_upper_cholesky = false;
  svar_lower_cholesky = false;
  svar_constants_exclusion = false;
}

houtanb's avatar
houtanb committed
924 925 926
void
ParsingDriver::end_svar_identification()
{
927
  mod_file->addStatement(new SvarIdentificationStatement(svar_ident_restrictions,
houtanb's avatar
houtanb committed
928 929
                                                         svar_upper_cholesky,
                                                         svar_lower_cholesky,
930
                                                         svar_constants_exclusion,
houtanb's avatar
houtanb committed
931 932 933
                                                         mod_file->symbol_table));
  svar_restriction_symbols.clear();
  svar_equation_restrictions.clear();
934
  svar_ident_restrictions.clear();
935 936
  svar_Qi_restriction_nbr.clear();
  svar_Ri_restriction_nbr.clear();
houtanb's avatar
houtanb committed
937 938 939 940 941 942 943
}

void
ParsingDriver::combine_lag_and_restriction(string *lag)
{
  int current_lag = atoi(lag->c_str());

944 945 946
  for (SvarIdentificationStatement::svar_identification_restrictions_t::const_iterator it = svar_ident_restrictions.begin();
       it != svar_ident_restrictions.end(); it++)
    if (it->lag == current_lag)
houtanb's avatar
houtanb committed
947 948
      error("lag " + *lag + " used more than once.");

949 950
  for (map<int, vector<int> >::const_iterator it = svar_equation_restrictions.begin();
       it != svar_equation_restrictions.end(); it++)
951
    for (vector<int>::const_iterator it1 = it->second.begin();
952
         it1 != it->second.end(); it1++)
953
      {
954 955 956 957 958 959 960 961 962 963 964
        SvarIdentificationStatement::svar_identification_restriction new_restriction;
        new_restriction.equation = it->first;
        if (current_lag > 0)
          new_restriction.restriction_nbr = ++svar_Ri_restriction_nbr[it->first];
        else
          new_restriction.restriction_nbr = ++svar_Qi_restriction_nbr[it->first];
        new_restriction.lag = current_lag;
        new_restriction.variable = *it1;
        new_restriction.value = data_tree->One;
        svar_ident_restrictions.push_back(new_restriction);
      }
965
  //    svar_ident_exclusion_values[make_pair(current_lag, it->first)] = it->second;
houtanb's avatar
houtanb committed
966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992

  svar_upper_cholesky = false;
  svar_lower_cholesky = false;
  svar_equation_restrictions.clear();
  delete lag;
}

void
ParsingDriver::add_restriction_in_equation(string *equation)
{
  int eqn = atoi(equation->c_str());
  if (eqn < 1)
    error("equation numbers must be greater than or equal to 1.");

  if (svar_equation_restrictions.count(eqn) > 0)
    error("equation number " + *equation + " referenced more than once under a single lag.");

  svar_equation_restrictions[eqn] = svar_restriction_symbols;

  svar_restriction_symbols.clear();
  delete equation;
}

void
ParsingDriver::add_in_svar_restriction_symbols(string *tmp_var)
{
  check_symbol_existence(*tmp_var);
993 994
  int symb_id = mod_file->symbol_table.getID(*tmp_var);

995 996 997
  for (vector<int>::const_iterator viit = svar_restriction_symbols.begin();
       viit != svar_restriction_symbols.end(); viit++)
    if (symb_id == *viit)
houtanb's avatar
houtanb committed
998 999
      error(*tmp_var + " restriction added twice.");

1000
  svar_restriction_symbols.push_back(symb_id);
houtanb's avatar
houtanb committed
1001 1002 1003
  delete tmp_var;
}

1004
void
1005 1006 1007 1008
ParsingDriver::add_restriction_equation_nbr(string *eq_nbr)
{
  svar_equation_nbr = atoi(eq_nbr->c_str());
  svar_left_handside = true;
1009 1010
  // reinitialize restriction type that must be set from the first restriction element
  svar_restriction_type = ParsingDriver::NOT_SET;
1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027
}

void
ParsingDriver::add_restriction_equal()
{
  if (svar_left_handside)
    svar_left_handside = false;
  else
    error("svar_identification: there are more than one EQUAL sign in a restriction equation");
}

void
ParsingDriver::add_positive_restriction_element(expr_t value, string *variable, string *lag)
{
  // if the expression is not on the left handside, change its sign
  if (!svar_left_handside)
    value = add_uminus(value);
1028

1029
  add_restriction_element(value, variable, lag);
1030 1031 1032 1033 1034
}

void
ParsingDriver::add_positive_restriction_element(string *variable, string *lag)
{
1035
  expr_t value(data_tree->One);
1036 1037 1038 1039 1040

  // if the expression is not on the left handside, change its sign
  if (!svar_left_handside)
    value = add_uminus(value);

1041
  add_restriction_element(value, variable, lag);
1042 1043 1044 1045 1046 1047 1048 1049 1050
}

void
ParsingDriver::add_negative_restriction_element(expr_t value, string *variable, string *lag)
{
  // if the expression is on the left handside, change its sign
  if (svar_left_handside)
    value = add_uminus(value);

1051
  add_restriction_element(value, variable, lag);
1052 1053 1054 1055 1056
}

void
ParsingDriver::add_negative_restriction_element(string *variable, string *lag)
{
1057
  expr_t value(data_tree->One);
1058 1059 1060 1061 1062

  // if the expression is on the left handside, change its sign
  if (svar_left_handside)
    value = add_uminus(value);

1063 1064 1065 1066 1067 1068 1069 1070 1071
  add_restriction_element(value, variable, lag);
}

void
ParsingDriver::add_restriction_element(expr_t value, string *variable, string *lag)
{
  check_symbol_existence(*variable);
  int symb_id = mod_file->symbol_table.getID(*variable);

1072
  int current_lag = atoi(lag->c_str());
1073 1074 1075
  if (svar_restriction_type == ParsingDriver::NOT_SET)
    {
      if (current_lag == 0)
1076 1077 1078 1079
        {
          svar_restriction_type = ParsingDriver::Qi_TYPE;
          ++svar_Qi_restriction_nbr[svar_equation_nbr];
        }
1080
      else
1081 1082 1083 1084
        {
          svar_restriction_type = ParsingDriver::Ri_TYPE;
          ++svar_Ri_restriction_nbr[svar_equation_nbr];
        }
1085 1086 1087 1088
    }
  else
    {
      if ((svar_restriction_type == Qi_TYPE && current_lag > 0)
1089