ParsingDriver.cc 69.6 KB
Newer Older
sebastien's avatar
sebastien committed
1
/*
2
 * Copyright (C) 2003-2013 Dynare Team
sebastien's avatar
sebastien committed
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>
sebastien's avatar
sebastien committed
21
22
#include <fstream>
#include <iostream>
23
#include <cassert>
Sébastien Villemot's avatar
Sébastien Villemot committed
24
#include <sstream>
25
#include <cmath>
sebastien's avatar
sebastien committed
26

27
#include "ParsingDriver.hh"
sebastien's avatar
sebastien committed
28
#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
{
sebastien's avatar
sebastien committed
35
  if (!mod_file->symbol_table.exists(s))
sebastien's avatar
sebastien committed
36
37
    return false;

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

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

43
void
44
45
ParsingDriver::check_symbol_existence(const string &name)
{
sebastien's avatar
sebastien committed
46
  if (!mod_file->symbol_table.exists(name))
47
48
49
    error("Unknown symbol: " + name);
}

50
51
52
53
54
55
56
57
58
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");
}

sebastien's avatar
sebastien committed
59
60
void
ParsingDriver::set_current_data_tree(DataTree *data_tree_arg)
61
{
sebastien's avatar
sebastien committed
62
63
  data_tree = data_tree_arg;
  model_tree = dynamic_cast<ModelTree *>(data_tree_arg);
64
  dynamic_model = dynamic_cast<DynamicModel *>(data_tree_arg);
sebastien's avatar
sebastien committed
65
66
67
68
69
70
}

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

73
74
75
76
77
78
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;
79
  current_external_function_id = eExtFunNotSet;
80
81
}

82
ModFile *
83
ParsingDriver::parse(istream &in, bool debug)
84
{
85
  mod_file = new ModFile(warnings);
sebastien's avatar
sebastien committed
86

sebastien's avatar
sebastien committed
87
  symbol_list.clear();
sebastien's avatar
sebastien committed
88

sebastien's avatar
sebastien committed
89
  reset_data_tree();
90
  estim_params.init(*data_tree);
91
  reset_current_external_function_options();
sebastien's avatar
sebastien committed
92

93
  lexer = new DynareFlex(&in);
94
  lexer->set_debug(debug);
95

96
  Dynare::parser parser(*this);
97
  parser.set_debug_level(debug);
98
  parser.parse();
sebastien's avatar
sebastien committed
99

100
  delete lexer;
sebastien's avatar
sebastien committed
101

102
  return mod_file;
103
104
105
}

void
106
ParsingDriver::error(const Dynare::parser::location_type &l, const string &m)
107
{
108
109
110
111
112
113
114
115
116
117
  cerr << "ERROR: " << *l.begin.filename << ": line " << l.begin.line;
  if (l.begin.line == l.end.line)
    if (l.begin.column == l.end.column - 1)
      cerr << ", col " << l.begin.column;
    else
      cerr << ", cols " << l.begin.column << "-" << l.end.column - 1;
  else
    cerr << ", col " << l.begin.column << " -"
         << " line " << l.end.line << ", col " << l.end.column - 1;
  cerr << ": " << m << endl;
118
  exit(EXIT_FAILURE);
119
120
121
}

void
122
ParsingDriver::error(const string &m)
123
{
sebastien's avatar
sebastien committed
124
  error(location, m);
125
126
}

127
void
sebastien's avatar
sebastien committed
128
129
ParsingDriver::warning(const string &m)
{
130
  warnings << "WARNING: " << location << ": " << m << endl;
sebastien's avatar
sebastien committed
131
132
133
}

void
134
ParsingDriver::declare_symbol(const string *name, SymbolType type, const string *tex_name, const string *long_name)
135
{
sebastien's avatar
sebastien committed
136
137
  try
    {
138
      if (tex_name == NULL && long_name == NULL)
139
140
        mod_file->symbol_table.addSymbol(*name, type);
      else
141
        if (tex_name == NULL)
142
          mod_file->symbol_table.addSymbol(*name, type, "", *long_name);
143
        else if (long_name == NULL)
144
          mod_file->symbol_table.addSymbol(*name, type, *tex_name, "");
145
146
        else
          mod_file->symbol_table.addSymbol(*name, type, *tex_name, *long_name);
sebastien's avatar
sebastien committed
147
    }
148
  catch (SymbolTable::AlreadyDeclaredException &e)
sebastien's avatar
sebastien committed
149
150
151
152
153
154
    {
      if (e.same_type)
        warning("Symbol " + *name + " declared twice.");
      else
        error("Symbol " + *name + " declared twice with different types!");
    }
155
156
}

sebastien's avatar
sebastien committed
157
void
158
ParsingDriver::declare_endogenous(string *name, string *tex_name, string *long_name)
sebastien's avatar
sebastien committed
159
{
160
  declare_symbol(name, eEndogenous, tex_name, long_name);
161
162
163
  delete name;
  if (tex_name != NULL)
    delete tex_name;
164
165
  if (long_name != NULL)
    delete long_name;
sebastien's avatar
sebastien committed
166
167
}

168
void
169
ParsingDriver::declare_exogenous(string *name, string *tex_name, string *long_name)
170
{
171
  declare_symbol(name, eExogenous, tex_name, long_name);
172
173
174
  delete name;
  if (tex_name != NULL)
    delete tex_name;
175
176
  if (long_name != NULL)
    delete long_name;
177
178
}

179
void
180
ParsingDriver::declare_exogenous_det(string *name, string *tex_name, string *long_name)
181
{
182
  declare_symbol(name, eExogenousDet, tex_name, long_name);
183
184
185
  delete name;
  if (tex_name != NULL)
    delete tex_name;
186
187
  if (long_name != NULL)
    delete long_name;
188
189
}

190
void
191
ParsingDriver::declare_parameter(string *name, string *tex_name, string *long_name)
192
{
193
  declare_symbol(name, eParameter, tex_name, long_name);
194
195
196
  delete name;
  if (tex_name != NULL)
    delete tex_name;
197
198
  if (long_name != NULL)
    delete long_name;
199
200
}

201
202
203
204
205
206
void
ParsingDriver::declare_statement_local_variable(string *name)
{
  if (mod_file->symbol_table.exists(*name))
    error("Symbol " + *name + " cannot be assigned within a statement " +
          "while being assigned elsewhere in the modfile");
207
  declare_symbol(name, eStatementDeclaredVariable, NULL, NULL);
208
209
210
  delete name;
}

211
void
212
ParsingDriver::declare_optimal_policy_discount_factor_parameter(expr_t exprnode)
213
{
214
215
216
217
218
219
  string *optimalParName_declare = new string("optimal_policy_discount_factor");
  string *optimalParName_init = new string("optimal_policy_discount_factor");
  if (mod_file->symbol_table.exists(*optimalParName_declare))
    error("Symbol optimal_policy_discount_factor is needed by Dynare when using an ramsey_policy or a discretionary_policy statement");
  declare_parameter(optimalParName_declare, NULL);
  init_param(optimalParName_init, exprnode);
220
221
}

222
223
224
225
226
227
228
void
ParsingDriver::begin_trend()
{
  set_current_data_tree(&mod_file->dynamic_model);
}

void
229
ParsingDriver::declare_trend_var(bool log_trend, string *name, string *tex_name)
230
{
231
  declare_symbol(name, log_trend ? eLogTrend : eTrend, tex_name, NULL);
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
  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();
}

253
254
255
void
ParsingDriver::add_predetermined_variable(string *name)
{
sebastien's avatar
sebastien committed
256
257
258
259
260
261
262
263
  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);
    }
264
  catch (SymbolTable::UnknownSymbolNameException &e)
sebastien's avatar
sebastien committed
265
266
267
    {
      error("Undeclared symbol name: " + *name);
    }
268
269
270
  delete name;
}

271
272
273
void
ParsingDriver::add_equation_tags(string *key, string *value)
{
274
  eq_tags.push_back(make_pair(*key, *value));
275
276
277
278
  delete key;
  delete value;
}

279
expr_t
280
ParsingDriver::add_non_negative_constant(string *constant)
281
{
282
  expr_t id = data_tree->AddNonNegativeConstant(*constant);
283
  delete constant;
sebastien's avatar
sebastien committed
284
  return id;
285
286
}

287
expr_t
288
289
290
291
292
ParsingDriver::add_nan_constant()
{
  return data_tree->NaN;
}

293
expr_t
294
295
296
297
298
ParsingDriver::add_inf_constant()
{
  return data_tree->Infinity;
}

299
expr_t
300
ParsingDriver::add_model_variable(string *name)
301
{
302
303
304
305
  check_symbol_existence(*name);
  int symb_id = mod_file->symbol_table.getID(*name);
  delete name;
  return add_model_variable(symb_id, 0);
306
307
}

308
expr_t
309
ParsingDriver::add_model_variable(int symb_id, int lag)
310
{
311
312
  assert(symb_id >= 0);
  SymbolType type = mod_file->symbol_table.getType(symb_id);
313

sebastien's avatar
sebastien committed
314
  if (type == eModFileLocalVariable)
315
    error("Variable " + mod_file->symbol_table.getName(symb_id) + " not allowed inside model declaration. Its scope is only outside model.");
sebastien's avatar
sebastien committed
316

317
318
  if (type == eExternalFunction)
    error("Symbol " + mod_file->symbol_table.getName(symb_id) + " is a function name external to Dynare. It cannot be used inside model.");
sebastien's avatar
sebastien committed
319
320

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

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

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

330
expr_t
331
ParsingDriver::add_expression_variable(string *name)
332
{
sebastien's avatar
sebastien committed
333
  // If symbol doesn't exist, then declare it as a mod file local variable
sebastien's avatar
sebastien committed
334
335
  if (!mod_file->symbol_table.exists(*name))
    mod_file->symbol_table.addSymbol(*name, eModFileLocalVariable);
sebastien's avatar
sebastien committed
336

337
338
339
340
  // 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.");

341
342
343
344
  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.");

345
  int symb_id = mod_file->symbol_table.getID(*name);
346
  expr_t id = data_tree->AddVariable(symb_id);
sebastien's avatar
sebastien committed
347

348
  delete name;
sebastien's avatar
sebastien committed
349
  return id;
350
351
}

352
void
353
ParsingDriver::declare_nonstationary_var(string *name, string *tex_name, string *long_name)
354
{
355
  if (tex_name == NULL && long_name == NULL)
356
    declare_endogenous(new string(*name));
357
358
359
360
361
362
363
364
  else
    if (tex_name == NULL)
      declare_endogenous(new string(*name), NULL, new string(*long_name));
    else if (long_name == NULL)
      declare_endogenous(new string(*name), new string(*tex_name));
    else
      declare_endogenous(new string(*name), new string(*tex_name), new string(*long_name));

365
366
367
368
369
  declared_nonstationary_vars.push_back(mod_file->symbol_table.getID(*name));
  mod_file->nonstationary_variables = true;
  delete name;
  if (tex_name != NULL)
    delete tex_name;
370
371
  if (long_name != NULL)
    delete long_name;
372
373
374
}

void
375
ParsingDriver::end_nonstationary_var(bool log_deflator, expr_t deflator)
376
377
378
{
  try
    {
379
      dynamic_model->addNonstationaryVariables(declared_nonstationary_vars, log_deflator, deflator);
380
381
382
383
384
    }
  catch (DataTree::TrendException &e)
    {
      error("Variable " + e.name + " was listed more than once as following a trend.");
    }
385

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

392
393
394
395
  declared_nonstationary_vars.clear();
  reset_data_tree();
}

396
void
sebastien's avatar
sebastien committed
397
ParsingDriver::periods(string *periods)
398
{
399
  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.");
400

sebastien's avatar
sebastien committed
401
402
403
  int periods_val = atoi(periods->c_str());
  mod_file->addStatement(new PeriodsStatement(periods_val));
  delete periods;
404
405
}

406
void
sebastien's avatar
sebastien committed
407
ParsingDriver::dsample(string *arg1)
408
{
sebastien's avatar
sebastien committed
409
410
411
  int arg1_val = atoi(arg1->c_str());
  mod_file->addStatement(new DsampleStatement(arg1_val));
  delete arg1;
412
413
}

414
void
sebastien's avatar
sebastien committed
415
ParsingDriver::dsample(string *arg1, string *arg2)
416
{
sebastien's avatar
sebastien committed
417
418
419
420
421
422
423
424
  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
425
ParsingDriver::init_param(string *name, expr_t rhs)
sebastien's avatar
sebastien committed
426
{
427
  check_symbol_is_parameter(name);
sebastien's avatar
sebastien committed
428
429
  int symb_id = mod_file->symbol_table.getID(*name);
  mod_file->addStatement(new InitParamStatement(symb_id, rhs, mod_file->symbol_table));
430
  delete name;
431
432
}

433
void
434
ParsingDriver::init_val(string *name, expr_t rhs)
435
{
436
437
438
  if (nostrict)
    if (!mod_file->symbol_table.exists(*name))
      {
439
440
        warnings << "WARNING: discarding '" << *name
                 << "' not recognized in initval or endval statement" << endl;
441
442
443
444
        delete name;
        return;
      }

sebastien's avatar
sebastien committed
445
  check_symbol_existence(*name);
sebastien's avatar
sebastien committed
446
447
  int symb_id = mod_file->symbol_table.getID(*name);
  SymbolType type = mod_file->symbol_table.getType(symb_id);
sebastien's avatar
sebastien committed
448
449
450
451
452

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

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

sebastien's avatar
sebastien committed
456
  delete name;
457
458
}

sebastien's avatar
sebastien committed
459
void
michel's avatar
michel committed
460
ParsingDriver::initval_file(string *filename)
sebastien's avatar
sebastien committed
461
{
sebastien's avatar
sebastien committed
462
  mod_file->addStatement(new InitvalFileStatement(*filename));
sebastien's avatar
sebastien committed
463
464
465
  delete filename;
}

466
void
467
ParsingDriver::hist_val(string *name, string *lag, expr_t rhs)
468
{
sebastien's avatar
sebastien committed
469
  check_symbol_existence(*name);
sebastien's avatar
sebastien committed
470
471
  int symb_id = mod_file->symbol_table.getID(*name);
  SymbolType type = mod_file->symbol_table.getType(symb_id);
472

sebastien's avatar
sebastien committed
473
474
475
  if (type != eEndogenous
      && type != eExogenous
      && type != eExogenousDet)
Sébastien Villemot's avatar
Sébastien Villemot committed
476
    error("histval: " + *name + " should be an endogenous or exogenous variable");
477

sebastien's avatar
sebastien committed
478
  int ilag = atoi(lag->c_str());
sebastien's avatar
sebastien committed
479
  pair<int, int> key(symb_id, ilag);
480

Sébastien Villemot's avatar
Sébastien Villemot committed
481
482
483
484
485
486
487
  if (mod_file->dynamic_model.minLagForSymbol(symb_id) > ilag - 1)
    {
      ostringstream s;
      s << ilag-1;
      error("histval: variable " + *name + " does not appear in the model with the lag " + s.str() + " (see the reference manual for the timing convention in 'histval')");
    }

sebastien's avatar
sebastien committed
488
489
  if (hist_values.find(key) != hist_values.end())
    error("hist_val: (" + *name + ", " + *lag + ") declared twice");
490

sebastien's avatar
sebastien committed
491
  hist_values[key] = rhs;
492

sebastien's avatar
sebastien committed
493
494
  delete name;
  delete lag;
sebastien's avatar
sebastien committed
495
496
}

497
void
498
ParsingDriver::homotopy_val(string *name, expr_t val1, expr_t val2)
499
500
{
  check_symbol_existence(*name);
sebastien's avatar
sebastien committed
501
502
  int symb_id = mod_file->symbol_table.getID(*name);
  SymbolType type = mod_file->symbol_table.getType(symb_id);
503
504
505
506
507
508

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

sebastien's avatar
sebastien committed
509
  homotopy_values.push_back(make_pair(symb_id, make_pair(val1, val2)));
510
511
512
513

  delete name;
}

514
515
516
517
518
519
520
521
void
ParsingDriver::forecast()
{
  mod_file->addStatement(new ForecastStatement(symbol_list, options_list));
  symbol_list.clear();
  options_list.clear();
}

522
void
sebastien's avatar
sebastien committed
523
ParsingDriver::use_dll()
524
{
525
  mod_file->use_dll = true;
526
527
}

sebastien's avatar
sebastien committed
528
void
529
ParsingDriver::block()
sebastien's avatar
sebastien committed
530
{
531
  mod_file->block = true;
sebastien's avatar
sebastien committed
532
533
}

534
535
536
537
538
539
void
ParsingDriver::no_static()
{
  mod_file->no_static = true;
}

ferhat's avatar
ferhat committed
540
void
541
ParsingDriver::byte_code()
ferhat's avatar
ferhat committed
542
{
543
  mod_file->byte_code = true;
ferhat's avatar
ferhat committed
544
545
}

546
void
547
ParsingDriver::differentiate_forward_vars_all()
548
549
550
551
{
  mod_file->differentiate_forward_vars = true;
}

552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
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();
}

567
568
569
570
571
void
ParsingDriver::cutoff(string *value)
{
  double val = atof(value->c_str());
  mod_file->dynamic_model.cutoff = val;
572
  mod_file->static_model.cutoff = val;
573
574
575
576
577
578
579
580
  delete value;
}

void
ParsingDriver::mfs(string *value)
{
  int val = atoi(value->c_str());
  mod_file->dynamic_model.mfs = val;
581
  mod_file->static_model.mfs = val;
582
583
584
  delete value;
}

585
void
586
ParsingDriver::end_initval(bool all_values_required)
587
{
588
  mod_file->addStatement(new InitValStatement(init_values, mod_file->symbol_table, all_values_required));
sebastien's avatar
sebastien committed
589
  init_values.clear();
590
591
}

592
void
593
ParsingDriver::end_endval(bool all_values_required)
594
{
595
  mod_file->addStatement(new EndValStatement(init_values, mod_file->symbol_table, all_values_required));
sebastien's avatar
sebastien committed
596
  init_values.clear();
597
598
}

599
void
sebastien's avatar
sebastien committed
600
ParsingDriver::end_histval()
601
{
sebastien's avatar
sebastien committed
602
603
  mod_file->addStatement(new HistValStatement(hist_values, mod_file->symbol_table));
  hist_values.clear();
604
605
}

606
607
608
609
610
611
612
void
ParsingDriver::end_homotopy()
{
  mod_file->addStatement(new HomotopyStatement(homotopy_values, mod_file->symbol_table));
  homotopy_values.clear();
}

sebastien's avatar
sebastien committed
613
614
615
void
ParsingDriver::begin_model()
{
sebastien's avatar
sebastien committed
616
  set_current_data_tree(&mod_file->dynamic_model);
sebastien's avatar
sebastien committed
617
618
}

619
void
sebastien's avatar
sebastien committed
620
ParsingDriver::end_shocks()
621
{
sebastien's avatar
sebastien committed
622
623
624
625
626
627
628
  mod_file->addStatement(new ShocksStatement(det_shocks, var_shocks, std_shocks,
                                             covar_shocks, corr_shocks, mod_file->symbol_table));
  det_shocks.clear();
  var_shocks.clear();
  std_shocks.clear();
  covar_shocks.clear();
  corr_shocks.clear();
629
630
}

631
void
sebastien's avatar
sebastien committed
632
ParsingDriver::end_mshocks()
633
{
634
  mod_file->addStatement(new MShocksStatement(det_shocks, mod_file->symbol_table));
sebastien's avatar
sebastien committed
635
  det_shocks.clear();
636
637
}

638
void
639
ParsingDriver::add_det_shock(string *var, bool conditional_forecast)
640
{
641
  check_symbol_existence(*var);
Sébastien Villemot's avatar
Sébastien Villemot committed
642
643
  int symb_id = mod_file->symbol_table.getID(*var);
  SymbolType type = mod_file->symbol_table.getType(symb_id);
644
645
646
647

  if (conditional_forecast)
    {
      if (type != eEndogenous)
648
        error("conditional_forecast_paths: shocks can only be applied to endogenous variables");
649
650
651
652
653
654
    }
  else
    {
      if (type != eExogenous && type != eExogenousDet)
        error("shocks: shocks can only be applied to exogenous variables");
    }
sebastien's avatar
sebastien committed
655

Sébastien Villemot's avatar
Sébastien Villemot committed
656
  if (det_shocks.find(symb_id) != det_shocks.end())
657
    error("shocks/conditional_forecast_paths: variable " + *var + " declared twice");
sebastien's avatar
sebastien committed
658
659

  if (det_shocks_periods.size() != det_shocks_values.size())
660
    error("shocks/conditional_forecast_paths: variable " + *var + ": number of periods is different from number of shock values");
sebastien's avatar
sebastien committed
661
662
663

  vector<ShocksStatement::DetShockElement> v;

664
  for (size_t i = 0; i < det_shocks_periods.size(); i++)
665
    {
sebastien's avatar
sebastien committed
666
667
668
669
670
      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);
671
    }
sebastien's avatar
sebastien committed
672

673
674
  det_shocks[symb_id].first = v;
  det_shocks[symb_id].second = det_shocks_expectation_pf;
sebastien's avatar
sebastien committed
675
676
677

  det_shocks_periods.clear();
  det_shocks_values.clear();
678
  det_shocks_expectation_pf = false;
679
  delete var;
680
681
}

682
void
683
ParsingDriver::add_stderr_shock(string *var, expr_t value)
684
{
685
  check_symbol_existence(*var);
Sébastien Villemot's avatar
Sébastien Villemot committed
686
687
688
689
  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())
sebastien's avatar
sebastien committed
690
691
    error("shocks: variance or stderr of shock on " + *var + " declared twice");

Sébastien Villemot's avatar
Sébastien Villemot committed
692
  std_shocks[symb_id] = value;
sebastien's avatar
sebastien committed
693

694
  delete var;
695
696
}

697
void
698
ParsingDriver::add_var_shock(string *var, expr_t value)
699
{
700
  check_symbol_existence(*var);
Sébastien Villemot's avatar
Sébastien Villemot committed
701
702
703
704
  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())
sebastien's avatar
sebastien committed
705
706
    error("shocks: variance or stderr of shock on " + *var + " declared twice");

Sébastien Villemot's avatar
Sébastien Villemot committed
707
  var_shocks[symb_id] = value;
sebastien's avatar
sebastien committed
708

709
  delete var;
710
711
}

712
void
713
ParsingDriver::add_covar_shock(string *var1, string *var2, expr_t value)
714
{
715
716
  check_symbol_existence(*var1);
  check_symbol_existence(*var2);
Sébastien Villemot's avatar
Sébastien Villemot committed
717
718
  int symb_id1 = mod_file->symbol_table.getID(*var1);
  int symb_id2 = mod_file->symbol_table.getID(*var2);
sebastien's avatar
sebastien committed
719

Sébastien Villemot's avatar
Sébastien Villemot committed
720
  pair<int, int> key(symb_id1, symb_id2), key_inv(symb_id2, symb_id1);
sebastien's avatar
sebastien committed
721
722
723
724
725
726
727

  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");
728

sebastien's avatar
sebastien committed
729
  covar_shocks[key] = value;
sebastien's avatar
sebastien committed
730

731
732
  delete var1;
  delete var2;
733
734
}

735
void
736
ParsingDriver::add_correl_shock(string *var1, string *var2, expr_t value)
737
{
738
739
  check_symbol_existence(*var1);
  check_symbol_existence(*var2);
Sébastien Villemot's avatar
Sébastien Villemot committed
740
741
742
743
  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);
sebastien's avatar
sebastien committed
744
745
746
747
748
749
750

  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");
751

sebastien's avatar
sebastien committed
752
  corr_shocks[key] = value;
sebastien's avatar
sebastien committed
753

754
755
756
757
758
759
760
  delete var1;
  delete var2;
}

void
ParsingDriver::add_period(string *p1, string *p2)
{
sebastien's avatar
sebastien committed
761
762
  int p1_val = atoi(p1->c_str());
  int p2_val = atoi(p2->c_str());
763
764
  if (p1_val > p2_val)
    error("shocks/conditional_forecast_paths: can't have first period index greater than second index in range specification");
sebastien's avatar
sebastien committed
765
  det_shocks_periods.push_back(make_pair(p1_val, p2_val));
766
767
  delete p1;
  delete p2;
768
769
}

770
771
void
ParsingDriver::add_period(string *p1)
772
{
sebastien's avatar
sebastien committed
773
  int p1_val = atoi(p1->c_str());
sebastien's avatar
sebastien committed
774
  det_shocks_periods.push_back(make_pair(p1_val, p1_val));
775
  delete p1;
776
777
}

sebastien's avatar
sebastien committed
778
void
779
ParsingDriver::add_value(expr_t value)
sebastien's avatar
sebastien committed
780
781
{
  det_shocks_values.push_back(value);
782
783
}

ferhat's avatar
ferhat committed
784
void
785
ParsingDriver::add_value(string *v)
ferhat's avatar
ferhat committed
786
{
787
  expr_t id;
788
789
790
791
792

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

794
795
  delete v;
  det_shocks_values.push_back(id);
ferhat's avatar
ferhat committed
796
797
}

798
799
800
801
802
803
void
ParsingDriver::add_expectation_pf(bool pf)
{
  det_shocks_expectation_pf = pf;
}

Houtan Bastani's avatar
Houtan Bastani committed
804
805
806
807
808
809
810
811
void
ParsingDriver::begin_svar_identification()
{
  svar_upper_cholesky = false;
  svar_lower_cholesky = false;
  svar_constants_exclusion = false;
}

houtanb's avatar
houtanb committed
812
813
814
void
ParsingDriver::end_svar_identification()
{
815
  mod_file->addStatement(new SvarIdentificationStatement(svar_ident_restrictions,
houtanb's avatar
houtanb committed
816
817
                                                         svar_upper_cholesky,
                                                         svar_lower_cholesky,
818
							 svar_constants_exclusion,
houtanb's avatar
houtanb committed
819
820
821
                                                         mod_file->symbol_table));
  svar_restriction_symbols.clear();
  svar_equation_restrictions.clear();
822
  svar_ident_restrictions.clear();
823
824
  svar_Qi_restriction_nbr.clear();
  svar_Ri_restriction_nbr.clear();
houtanb's avatar
houtanb committed
825
826
827
828
829
830
831
}

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

832
833
834
  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
835
836
      error("lag " + *lag + " used more than once.");

837
838
  for (map<int, vector<int> >::const_iterator it = svar_equation_restrictions.begin();
       it != svar_equation_restrictions.end(); it++)
839
840
841
842
843
    for (vector<int>::const_iterator it1 = it->second.begin();
	 it1 != it->second.end(); it1++)
      {
	SvarIdentificationStatement::svar_identification_restriction new_restriction;
	new_restriction.equation = it->first;
844
845
846
847
	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];
848
849
850
851
852
853
	new_restriction.lag = current_lag;
	new_restriction.variable = *it1;
	new_restriction.value = data_tree->One;
	svar_ident_restrictions.push_back(new_restriction);
      } 
  //    svar_ident_exclusion_values[make_pair(current_lag, it->first)] = it->second;
houtanb's avatar
houtanb committed
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880

  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);
881
882
  int symb_id = mod_file->symbol_table.getID(*tmp_var);

883
884
885
  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
886
887
      error(*tmp_var + " restriction added twice.");

888
  svar_restriction_symbols.push_back(symb_id);
houtanb's avatar
houtanb committed
889
890
891
  delete tmp_var;
}

892
893
894
895
896
void 
ParsingDriver::add_restriction_equation_nbr(string *eq_nbr)
{
  svar_equation_nbr = atoi(eq_nbr->c_str());
  svar_left_handside = true;
897
898
  // reinitialize restriction type that must be set from the first restriction element
  svar_restriction_type = ParsingDriver::NOT_SET;
899
900
901
902
903
904
905