ParsingDriver.cc 67.8 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
{
sebastien's avatar
sebastien committed
108
  cerr << "ERROR: " << l << ": " << m << endl;
109
  exit(EXIT_FAILURE);
110
111
112
}

void
113
ParsingDriver::error(const string &m)
114
{
sebastien's avatar
sebastien committed
115
  error(location, m);
116
117
}

118
void
sebastien's avatar
sebastien committed
119
120
ParsingDriver::warning(const string &m)
{
121
  warnings << "WARNING: " << location << ": " << m << endl;
sebastien's avatar
sebastien committed
122
123
124
}

void
125
ParsingDriver::declare_symbol(const string *name, SymbolType type, const string *tex_name)
126
{
sebastien's avatar
sebastien committed
127
128
  try
    {
129
130
131
132
      if (tex_name == NULL)
        mod_file->symbol_table.addSymbol(*name, type);
      else
        mod_file->symbol_table.addSymbol(*name, type, *tex_name);
sebastien's avatar
sebastien committed
133
    }
134
  catch (SymbolTable::AlreadyDeclaredException &e)
sebastien's avatar
sebastien committed
135
136
137
138
139
140
    {
      if (e.same_type)
        warning("Symbol " + *name + " declared twice.");
      else
        error("Symbol " + *name + " declared twice with different types!");
    }
141
142
}

sebastien's avatar
sebastien committed
143
144
145
146
void
ParsingDriver::declare_endogenous(string *name, string *tex_name)
{
  declare_symbol(name, eEndogenous, tex_name);
147
148
149
  delete name;
  if (tex_name != NULL)
    delete tex_name;
sebastien's avatar
sebastien committed
150
151
}

152
153
void
ParsingDriver::declare_exogenous(string *name, string *tex_name)
154
{
sebastien's avatar
sebastien committed
155
  declare_symbol(name, eExogenous, tex_name);
156
157
158
  delete name;
  if (tex_name != NULL)
    delete tex_name;
159
160
}

161
162
void
ParsingDriver::declare_exogenous_det(string *name, string *tex_name)
163
{
sebastien's avatar
sebastien committed
164
  declare_symbol(name, eExogenousDet, tex_name);
165
166
167
  delete name;
  if (tex_name != NULL)
    delete tex_name;
168
169
}

170
171
void
ParsingDriver::declare_parameter(string *name, string *tex_name)
172
{
sebastien's avatar
sebastien committed
173
  declare_symbol(name, eParameter, tex_name);
174
175
176
  delete name;
  if (tex_name != NULL)
    delete tex_name;
177
178
}

179
180
181
182
183
184
185
186
187
188
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");
  declare_symbol(name, eStatementDeclaredVariable, NULL);
  delete name;
}

189
void
190
ParsingDriver::declare_optimal_policy_discount_factor_parameter(expr_t exprnode)
191
{
192
193
194
195
196
197
  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);
198
199
}

200
201
202
203
204
205
206
void
ParsingDriver::begin_trend()
{
  set_current_data_tree(&mod_file->dynamic_model);
}

void
207
ParsingDriver::declare_trend_var(bool log_trend, string *name, string *tex_name)
208
{
209
  declare_symbol(name, log_trend ? eLogTrend : eTrend, tex_name);
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
  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();
}

231
232
233
void
ParsingDriver::add_predetermined_variable(string *name)
{
sebastien's avatar
sebastien committed
234
235
236
237
238
239
240
241
  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);
    }
242
  catch (SymbolTable::UnknownSymbolNameException &e)
sebastien's avatar
sebastien committed
243
244
245
    {
      error("Undeclared symbol name: " + *name);
    }
246
247
248
  delete name;
}

249
250
251
252
253
254
255
256
257
void
ParsingDriver::add_equation_tags(string *key, string *value)
{
  int n = model_tree->equation_number();
  model_tree->addEquationTags(n, *key, *value);
  delete key;
  delete value;
}

258
expr_t
259
ParsingDriver::add_non_negative_constant(string *constant)
260
{
261
  expr_t id = data_tree->AddNonNegativeConstant(*constant);
262
  delete constant;
sebastien's avatar
sebastien committed
263
  return id;
264
265
}

266
expr_t
267
268
269
270
271
ParsingDriver::add_nan_constant()
{
  return data_tree->NaN;
}

272
expr_t
273
274
275
276
277
ParsingDriver::add_inf_constant()
{
  return data_tree->Infinity;
}

278
expr_t
279
ParsingDriver::add_model_variable(string *name)
280
{
281
282
283
284
  check_symbol_existence(*name);
  int symb_id = mod_file->symbol_table.getID(*name);
  delete name;
  return add_model_variable(symb_id, 0);
285
286
}

287
expr_t
288
ParsingDriver::add_model_variable(int symb_id, int lag)
289
{
290
291
  assert(symb_id >= 0);
  SymbolType type = mod_file->symbol_table.getType(symb_id);
292

sebastien's avatar
sebastien committed
293
  if (type == eModFileLocalVariable)
294
    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
295

296
297
  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
298
299

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

302
303
304
  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
305
  // It makes sense to allow a lead/lag on parameters: during steady state calibration, endogenous and parameters can be swapped
306
  return model_tree->AddVariable(symb_id, lag);
307
308
}

309
expr_t
310
ParsingDriver::add_expression_variable(string *name)
311
{
sebastien's avatar
sebastien committed
312
  // If symbol doesn't exist, then declare it as a mod file local variable
sebastien's avatar
sebastien committed
313
314
  if (!mod_file->symbol_table.exists(*name))
    mod_file->symbol_table.addSymbol(*name, eModFileLocalVariable);
sebastien's avatar
sebastien committed
315

316
317
318
319
  // 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.");

320
  int symb_id = mod_file->symbol_table.getID(*name);
321
  expr_t id = data_tree->AddVariable(symb_id);
sebastien's avatar
sebastien committed
322

323
  delete name;
sebastien's avatar
sebastien committed
324
  return id;
325
326
}

327
328
329
void
ParsingDriver::declare_nonstationary_var(string *name, string *tex_name)
{
330
331
332
333
  if (tex_name != NULL)
    declare_endogenous(new string(*name), new string(*tex_name));
  else
    declare_endogenous(new string(*name), tex_name);
334
335
336
337
338
339
340
341
  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;
}

void
342
ParsingDriver::end_nonstationary_var(bool log_deflator, expr_t deflator)
343
344
345
{
  try
    {
346
      dynamic_model->addNonstationaryVariables(declared_nonstationary_vars, log_deflator, deflator);
347
348
349
350
351
352
353
354
355
    }
  catch (DataTree::TrendException &e)
    {
      error("Variable " + e.name + " was listed more than once as following a trend.");
    }
  declared_nonstationary_vars.clear();
  reset_data_tree();
}

356
void
sebastien's avatar
sebastien committed
357
ParsingDriver::periods(string *periods)
358
{
359
  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.");
360

sebastien's avatar
sebastien committed
361
362
363
  int periods_val = atoi(periods->c_str());
  mod_file->addStatement(new PeriodsStatement(periods_val));
  delete periods;
364
365
}

366
void
sebastien's avatar
sebastien committed
367
ParsingDriver::dsample(string *arg1)
368
{
sebastien's avatar
sebastien committed
369
370
371
  int arg1_val = atoi(arg1->c_str());
  mod_file->addStatement(new DsampleStatement(arg1_val));
  delete arg1;
372
373
}

374
void
sebastien's avatar
sebastien committed
375
ParsingDriver::dsample(string *arg1, string *arg2)
376
{
sebastien's avatar
sebastien committed
377
378
379
380
381
382
383
384
  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
385
ParsingDriver::init_param(string *name, expr_t rhs)
sebastien's avatar
sebastien committed
386
{
387
  check_symbol_is_parameter(name);
sebastien's avatar
sebastien committed
388
389
  int symb_id = mod_file->symbol_table.getID(*name);
  mod_file->addStatement(new InitParamStatement(symb_id, rhs, mod_file->symbol_table));
390
  delete name;
391
392
}

393
void
394
ParsingDriver::init_val(string *name, expr_t rhs)
395
{
sebastien's avatar
sebastien committed
396
  check_symbol_existence(*name);
sebastien's avatar
sebastien committed
397
398
  int symb_id = mod_file->symbol_table.getID(*name);
  SymbolType type = mod_file->symbol_table.getType(symb_id);
sebastien's avatar
sebastien committed
399
400
401
402
403

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

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

sebastien's avatar
sebastien committed
407
  delete name;
408
409
}

sebastien's avatar
sebastien committed
410
void
michel's avatar
michel committed
411
ParsingDriver::initval_file(string *filename)
sebastien's avatar
sebastien committed
412
{
sebastien's avatar
sebastien committed
413
  mod_file->addStatement(new InitvalFileStatement(*filename));
sebastien's avatar
sebastien committed
414
415
416
  delete filename;
}

417
void
418
ParsingDriver::hist_val(string *name, string *lag, expr_t rhs)
419
{
sebastien's avatar
sebastien committed
420
  check_symbol_existence(*name);
sebastien's avatar
sebastien committed
421
422
  int symb_id = mod_file->symbol_table.getID(*name);
  SymbolType type = mod_file->symbol_table.getType(symb_id);
423

sebastien's avatar
sebastien committed
424
425
426
  if (type != eEndogenous
      && type != eExogenous
      && type != eExogenousDet)
Sébastien Villemot's avatar
Sébastien Villemot committed
427
    error("histval: " + *name + " should be an endogenous or exogenous variable");
428

sebastien's avatar
sebastien committed
429
  int ilag = atoi(lag->c_str());
sebastien's avatar
sebastien committed
430
  pair<int, int> key(symb_id, ilag);
431

Sébastien Villemot's avatar
Sébastien Villemot committed
432
433
434
435
436
437
438
  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
439
440
  if (hist_values.find(key) != hist_values.end())
    error("hist_val: (" + *name + ", " + *lag + ") declared twice");
441

sebastien's avatar
sebastien committed
442
  hist_values[key] = rhs;
443

sebastien's avatar
sebastien committed
444
445
  delete name;
  delete lag;
sebastien's avatar
sebastien committed
446
447
}

448
void
449
ParsingDriver::homotopy_val(string *name, expr_t val1, expr_t val2)
450
451
{
  check_symbol_existence(*name);
sebastien's avatar
sebastien committed
452
453
  int symb_id = mod_file->symbol_table.getID(*name);
  SymbolType type = mod_file->symbol_table.getType(symb_id);
454
455
456
457
458
459

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

sebastien's avatar
sebastien committed
460
  homotopy_values.push_back(make_pair(symb_id, make_pair(val1, val2)));
461
462
463
464

  delete name;
}

465
466
467
468
469
470
471
472
void
ParsingDriver::forecast()
{
  mod_file->addStatement(new ForecastStatement(symbol_list, options_list));
  symbol_list.clear();
  options_list.clear();
}

473
void
sebastien's avatar
sebastien committed
474
ParsingDriver::use_dll()
475
{
476
  mod_file->use_dll = true;
477
478
}

sebastien's avatar
sebastien committed
479
void
480
ParsingDriver::block()
sebastien's avatar
sebastien committed
481
{
482
  mod_file->block = true;
sebastien's avatar
sebastien committed
483
484
}

485
486
487
488
489
490
void
ParsingDriver::no_static()
{
  mod_file->no_static = true;
}

ferhat's avatar
ferhat committed
491
void
492
ParsingDriver::byte_code()
ferhat's avatar
ferhat committed
493
{
494
  mod_file->byte_code = true;
ferhat's avatar
ferhat committed
495
496
}

497
498
499
500
501
void
ParsingDriver::cutoff(string *value)
{
  double val = atof(value->c_str());
  mod_file->dynamic_model.cutoff = val;
502
  mod_file->static_model.cutoff = val;
503
504
505
506
507
508
509
510
  delete value;
}

void
ParsingDriver::mfs(string *value)
{
  int val = atoi(value->c_str());
  mod_file->dynamic_model.mfs = val;
511
  mod_file->static_model.mfs = val;
512
513
514
  delete value;
}

515
516
517
518
519
520
void
ParsingDriver::transform_logpow()
{
  mod_file->transform_logpow = true;
}

521
void
522
ParsingDriver::end_initval(bool all_values_required)
523
{
524
  mod_file->addStatement(new InitValStatement(init_values, mod_file->symbol_table, all_values_required));
sebastien's avatar
sebastien committed
525
  init_values.clear();
526
527
}

528
void
529
ParsingDriver::end_endval(bool all_values_required)
530
{
531
  mod_file->addStatement(new EndValStatement(init_values, mod_file->symbol_table, all_values_required));
sebastien's avatar
sebastien committed
532
  init_values.clear();
533
534
}

535
void
sebastien's avatar
sebastien committed
536
ParsingDriver::end_histval()
537
{
sebastien's avatar
sebastien committed
538
539
  mod_file->addStatement(new HistValStatement(hist_values, mod_file->symbol_table));
  hist_values.clear();
540
541
}

542
543
544
545
546
547
548
void
ParsingDriver::end_homotopy()
{
  mod_file->addStatement(new HomotopyStatement(homotopy_values, mod_file->symbol_table));
  homotopy_values.clear();
}

sebastien's avatar
sebastien committed
549
550
551
void
ParsingDriver::begin_model()
{
sebastien's avatar
sebastien committed
552
  set_current_data_tree(&mod_file->dynamic_model);
sebastien's avatar
sebastien committed
553
554
}

555
void
sebastien's avatar
sebastien committed
556
ParsingDriver::end_shocks()
557
{
sebastien's avatar
sebastien committed
558
559
560
561
562
563
564
  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();
565
566
}

567
void
sebastien's avatar
sebastien committed
568
ParsingDriver::end_mshocks()
569
{
570
  mod_file->addStatement(new MShocksStatement(det_shocks, mod_file->symbol_table));
sebastien's avatar
sebastien committed
571
  det_shocks.clear();
572
573
}

574
void
575
ParsingDriver::add_det_shock(string *var, bool conditional_forecast)
576
{
577
  check_symbol_existence(*var);
Sébastien Villemot's avatar
Sébastien Villemot committed
578
579
  int symb_id = mod_file->symbol_table.getID(*var);
  SymbolType type = mod_file->symbol_table.getType(symb_id);
580
581
582
583

  if (conditional_forecast)
    {
      if (type != eEndogenous)
584
        error("conditional_forecast_paths: shocks can only be applied to endogenous variables");
585
586
587
588
589
590
    }
  else
    {
      if (type != eExogenous && type != eExogenousDet)
        error("shocks: shocks can only be applied to exogenous variables");
    }
sebastien's avatar
sebastien committed
591

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

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

  vector<ShocksStatement::DetShockElement> v;

600
  for (size_t i = 0; i < det_shocks_periods.size(); i++)
601
    {
sebastien's avatar
sebastien committed
602
603
604
605
606
      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);
607
    }
sebastien's avatar
sebastien committed
608

609
610
  det_shocks[symb_id].first = v;
  det_shocks[symb_id].second = det_shocks_expectation_pf;
sebastien's avatar
sebastien committed
611
612
613

  det_shocks_periods.clear();
  det_shocks_values.clear();
614
  det_shocks_expectation_pf = false;
615
  delete var;
616
617
}

618
void
619
ParsingDriver::add_stderr_shock(string *var, expr_t value)
620
{
621
  check_symbol_existence(*var);
Sébastien Villemot's avatar
Sébastien Villemot committed
622
623
624
625
626
627
628
629
  int symb_id = mod_file->symbol_table.getID(*var);

  SymbolType type = mod_file->symbol_table.getType(symb_id);
  if (type != eExogenous && !mod_file->symbol_table.isObservedVariable(symb_id))
    error("shocks: standard error can only be specified for exogenous or observed endogenous variables");

  if (var_shocks.find(symb_id) != var_shocks.end()
      || std_shocks.find(symb_id) != std_shocks.end())
sebastien's avatar
sebastien committed
630
631
    error("shocks: variance or stderr of shock on " + *var + " declared twice");

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

634
  delete var;
635
636
}

637
void
638
ParsingDriver::add_var_shock(string *var, expr_t value)
639
{
640
  check_symbol_existence(*var);
Sébastien Villemot's avatar
Sébastien Villemot committed
641
642
643
644
645
646
647
648
  int symb_id = mod_file->symbol_table.getID(*var);

  SymbolType type = mod_file->symbol_table.getType(symb_id);
  if (type != eExogenous && !mod_file->symbol_table.isObservedVariable(symb_id))
    error("shocks: variance can only be specified for exogenous or observed endogenous variables");

  if (var_shocks.find(symb_id) != var_shocks.end()
      || std_shocks.find(symb_id) != std_shocks.end())
sebastien's avatar
sebastien committed
649
650
    error("shocks: variance or stderr of shock on " + *var + " declared twice");

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

653
  delete var;
654
655
}

656
void
657
ParsingDriver::add_covar_shock(string *var1, string *var2, expr_t value)
658
{
659
660
  check_symbol_existence(*var1);
  check_symbol_existence(*var2);
Sébastien Villemot's avatar
Sébastien Villemot committed
661
662
  int symb_id1 = mod_file->symbol_table.getID(*var1);
  int symb_id2 = mod_file->symbol_table.getID(*var2);
sebastien's avatar
sebastien committed
663

Sébastien Villemot's avatar
Sébastien Villemot committed
664
665
666
667
668
669
670
  SymbolType type1 = mod_file->symbol_table.getType(symb_id1);
  SymbolType type2 = mod_file->symbol_table.getType(symb_id2);
  if (!((type1 == eExogenous && type2 == eExogenous)
        || (mod_file->symbol_table.isObservedVariable(symb_id1) && mod_file->symbol_table.isObservedVariable(symb_id2))))
    error("shocks: covariance can only be specified for exogenous or observed endogenous variables of same type");

  pair<int, int> key(symb_id1, symb_id2), key_inv(symb_id2, symb_id1);
sebastien's avatar
sebastien committed
671
672
673
674
675
676
677

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

sebastien's avatar
sebastien committed
679
  covar_shocks[key] = value;
sebastien's avatar
sebastien committed
680

681
682
  delete var1;
  delete var2;
683
684
}

685
void
686
ParsingDriver::add_correl_shock(string *var1, string *var2, expr_t value)
687
{
688
689
  check_symbol_existence(*var1);
  check_symbol_existence(*var2);
Sébastien Villemot's avatar
Sébastien Villemot committed
690
691
692
693
694
695
696
697
  int symb_id1 = mod_file->symbol_table.getID(*var1);
  int symb_id2 = mod_file->symbol_table.getID(*var2);

  SymbolType type1 = mod_file->symbol_table.getType(symb_id1);
  SymbolType type2 = mod_file->symbol_table.getType(symb_id2);
  if (!((type1 == eExogenous && type2 == eExogenous)
        || (mod_file->symbol_table.isObservedVariable(symb_id1) && mod_file->symbol_table.isObservedVariable(symb_id2))))
    error("shocks: correlation can only be specified for exogenous or observed endogenous variables of same type");
sebastien's avatar
sebastien committed
698

Sébastien Villemot's avatar
Sébastien Villemot committed
699
  pair<int, int> key(symb_id1, symb_id2), key_inv(symb_id2, symb_id1);
sebastien's avatar
sebastien committed
700
701
702
703
704
705
706

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

sebastien's avatar
sebastien committed
708
  corr_shocks[key] = value;
sebastien's avatar
sebastien committed
709

710
711
712
713
714
715
716
  delete var1;
  delete var2;
}

void
ParsingDriver::add_period(string *p1, string *p2)
{
sebastien's avatar
sebastien committed
717
718
  int p1_val = atoi(p1->c_str());
  int p2_val = atoi(p2->c_str());
719
720
  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
721
  det_shocks_periods.push_back(make_pair(p1_val, p2_val));
722
723
  delete p1;
  delete p2;
724
725
}

726
727
void
ParsingDriver::add_period(string *p1)
728
{
sebastien's avatar
sebastien committed
729
  int p1_val = atoi(p1->c_str());
sebastien's avatar
sebastien committed
730
  det_shocks_periods.push_back(make_pair(p1_val, p1_val));
731
  delete p1;
732
733
}

sebastien's avatar
sebastien committed
734
void
735
ParsingDriver::add_value(expr_t value)
sebastien's avatar
sebastien committed
736
737
{
  det_shocks_values.push_back(value);
738
739
}

ferhat's avatar
ferhat committed
740
void
741
ParsingDriver::add_value(string *v)
ferhat's avatar
ferhat committed
742
{
743
  expr_t id;
744
745
746
747
748

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

750
751
  delete v;
  det_shocks_values.push_back(id);
ferhat's avatar
ferhat committed
752
753
}

754
755
756
757
758
759
void
ParsingDriver::add_expectation_pf(bool pf)
{
  det_shocks_expectation_pf = pf;
}

Houtan Bastani's avatar
Houtan Bastani committed
760
761
762
763
764
765
766
767
void
ParsingDriver::begin_svar_identification()
{
  svar_upper_cholesky = false;
  svar_lower_cholesky = false;
  svar_constants_exclusion = false;
}

houtanb's avatar
houtanb committed
768
769
770
void
ParsingDriver::end_svar_identification()
{
771
  mod_file->addStatement(new SvarIdentificationStatement(svar_ident_restrictions,
houtanb's avatar
houtanb committed
772
773
                                                         svar_upper_cholesky,
                                                         svar_lower_cholesky,
774
							 svar_constants_exclusion,
houtanb's avatar
houtanb committed
775
776
777
                                                         mod_file->symbol_table));
  svar_restriction_symbols.clear();
  svar_equation_restrictions.clear();
778
  svar_ident_restrictions.clear();
779
780
  svar_Qi_restriction_nbr.clear();
  svar_Ri_restriction_nbr.clear();
houtanb's avatar
houtanb committed
781
782
783
784
785
786
787
}

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

788
789
790
  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
791
792
      error("lag " + *lag + " used more than once.");

793
794
  for (map<int, vector<int> >::const_iterator it = svar_equation_restrictions.begin();
       it != svar_equation_restrictions.end(); it++)
795
796
797
798
799
    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;
800
801
802
803
	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];
804
805
806
807
808
809
	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
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836

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

839
840
841
  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
842
843
      error(*tmp_var + " restriction added twice.");

844
  svar_restriction_symbols.push_back(symb_id);
houtanb's avatar
houtanb committed
845
846
847
  delete tmp_var;
}

848
849
850
851
852
void 
ParsingDriver::add_restriction_equation_nbr(string *eq_nbr)
{
  svar_equation_nbr = atoi(eq_nbr->c_str());
  svar_left_handside = true;
853
854
  // reinitialize restriction type that must be set from the first restriction element
  svar_restriction_type = ParsingDriver::NOT_SET;
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
}

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);
872
873
  
  add_restriction_element(value, variable, lag);
874
875
876
877
878
879
880
881
882
883
884
}

void
ParsingDriver::add_positive_restriction_element(string *variable, string *lag)
{
  expr_t value(data_tree->One); 

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

885
  add_restriction_element(value, variable, lag);
886
887
888
889
890
891
892
893
894
}

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

895
  add_restriction_element(value, variable, lag);
896
897
898
899
900
901
902
903
904
905
906
}

void
ParsingDriver::add_negative_restriction_element(string *variable, string *lag)
{
  expr_t value(data_tree->One); 

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

907
908
909
910
911
912
913
914
915
  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);

916
  int current_lag = atoi(lag->c_str());
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
  if (svar_restriction_type == ParsingDriver::NOT_SET)
    {
      if (current_lag == 0)
	{
	  svar_restriction_type = ParsingDriver::Qi_TYPE;
	  ++svar_Qi_restriction_nbr[svar_equation_nbr];
	}
      else
	{
	  svar_restriction_type = ParsingDriver::Ri_TYPE;
	  ++svar_Ri_restriction_nbr[svar_equation_nbr];
	}
    }
  else
    {
      if ((svar_restriction_type == Qi_TYPE && current_lag > 0)
	  || (svar_restriction_type == Ri_TYPE && current_lag == 0))
	error("SVAR_IDENTIFICATION: a single restrictions must affect either Qi or Ri, but not both");
    }
936
937
  SvarIdentificationStatement::svar_identification_restriction new_restriction;
  new_restriction.equation = svar_equation_nbr;
938
  if (current_lag > 0)
939
    new_restriction.restriction_nbr = svar_Ri_restriction_nbr[svar_equation_nbr];
940
  else
941
    new_restriction.restriction_nbr = svar_Qi_restriction_nbr[svar_equation_nbr];
942
  new_restriction.lag = current_lag;
943
944
945
946
947
948
  new_restriction.variable = symb_id;
  new_restriction.value = value;

  svar_ident_restrictions.push_back(new_restriction);
}

949
950
951
952
953
954
955
void
ParsingDriver::check_restriction_expression_constant(expr_t value)
{
  if (value->eval(eval_context_t()) != 0)
    error("SVAR_INDENTIFICATION restrictions must be homogenous");
}

houtanb's avatar
houtanb committed
956
957
958
959
960
961
962
963
964
965
966
967
void
ParsingDriver::add_upper_cholesky()
{
  svar_upper_cholesky = true;
}

void
ParsingDriver::add_lower_cholesky()
{
  svar_lower_cholesky = true;
}

Houtan Bastani's avatar
Houtan Bastani committed
968
969
970
971
972
973
void
ParsingDriver::add_constants_exclusion()
{
  svar_constants_exclusion = true;
}

974
975
void
ParsingDriver::do_sigma_e()
976
{
977
  warning("Sigma_e: this command is now deprecated and may be removed in a future version of Dynare. Please use the ''shocks'' command instead.");
978

sebastien's avatar
sebastien committed
979
980
981
982
  try
    {
      mod_file->addStatement(new SigmaeStatement(sigmae_matrix));
    }
983
  catch (SigmaeStatement::MatrixFormException &e)
sebastien's avatar
sebastien committed
984
985
986
987
    {
      error("Sigma_e: matrix is neither upper triangular nor lower triangular");
    }
  sigmae_matrix.clear();
988
989
}

990
991
void
ParsingDriver::end_of_row()
992
{
sebastien's avatar
sebastien committed
993
994
  sigmae_matrix.push_back(sigmae_row);
  sigmae_row.clear();
995
996
}

997
void
998
ParsingDriver::add_to_row_const(string *v)
999
{
1000
  expr_t id;
1001
1002
1003
1004
1005

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