From f5bfdbb23f127cfa4fdb66834d8025c96b65cf87 Mon Sep 17 00:00:00 2001
From: Houtan Bastani <houtan.bastani@ens.fr>
Date: Sun, 11 Dec 2011 15:35:26 +0100
Subject: [PATCH] preprocessor: add prior statement

---
 matlab/global_initialization.m |  21 +++-
 preprocessor/ComputingTasks.cc | 184 +++++++++++++++++++++++++++++++++
 preprocessor/ComputingTasks.hh |  56 ++++++++++
 preprocessor/DynareBison.yy    | 100 +++++++++++++-----
 preprocessor/DynareFlex.ll     |  37 ++++++-
 preprocessor/ModFile.cc        |   2 +-
 preprocessor/ParsingDriver.cc  |  69 ++++++++++++-
 preprocessor/ParsingDriver.hh  |  18 ++++
 preprocessor/Statement.hh      |   6 ++
 9 files changed, 461 insertions(+), 32 deletions(-)

diff --git a/matlab/global_initialization.m b/matlab/global_initialization.m
index 00e9375550..e3325df195 100644
--- a/matlab/global_initialization.m
+++ b/matlab/global_initialization.m
@@ -28,7 +28,7 @@ function global_initialization()
 % You should have received a copy of the GNU General Public License
 % along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
 
-global oo_ M_ options_ estim_params_ bayestopt_
+global oo_ M_ options_ estim_params_ bayestopt_ estimation_info
 
 estim_params_ = [];
 bayestopt_ = [];
@@ -182,6 +182,25 @@ options_.ramsey_policy = 0;
 options_.timeless = 0;
 
 % estimation
+estimation_info.prior = struct('name', {}, 'shape', {}, 'mean', {}, ...
+                               'mode', {}, 'stdev', {}, 'date1', {}, ...
+                               'date2', {}, 'shift', {}, 'variance', {});
+estimation_info.structural_innovation.prior = struct('name', {}, 'shape', {}, 'mean', {}, ...
+                                                  'mode', {}, 'stdev', {}, 'date1', {}, ...
+                                                  'date2', {}, 'shift', {}, 'variance', {});
+estimation_info.structural_innovation_corr.prior = struct('name', {}, 'shape', {}, 'mean', {}, ...
+                                                  'mode', {}, 'stdev', {}, 'date1', {}, ...
+                                                  'date2', {}, 'shift', {}, 'variance', {});
+estimation_info.measurement_error.prior = struct('name', {}, 'shape', {}, 'mean', {}, ...
+                                                 'mode', {}, 'stdev', {}, 'date1', {}, ...
+                                                 'date2', {}, 'shift', {}, 'variance', {});
+estimation_info.measurement_error_corr.prior = struct('name', {}, 'shape', {}, 'mean', {}, ...
+                                                  'mode', {}, 'stdev', {}, 'date1', {}, ...
+                                                  'date2', {}, 'shift', {}, 'variance', {});
+estimation_info.measurement_error.prior_index = {};
+estimation_info.structural_innovation.prior_index = {};
+estimation_info.measurement_error_corr.prior_index = {};
+estimation_info.structural_innovation_corr.prior_index = {};
 options_.initial_period = dynDate(1);
 options_.dataset.firstobs = options_.initial_period;
 options_.dataset.lastobs = NaN;
diff --git a/preprocessor/ComputingTasks.cc b/preprocessor/ComputingTasks.cc
index 0a765469e6..aa3029dd78 100644
--- a/preprocessor/ComputingTasks.cc
+++ b/preprocessor/ComputingTasks.cc
@@ -1499,3 +1499,187 @@ EstimationDataStatement::writeOutput(ostream &output, const string &basename) co
   if (options_list.date_options.find("first_obs") == options_list.date_options.end())
     output << "options_.dataset.firstobs = options_.initial_period;" << endl;
 }
+
+BasicPriorStatement::~BasicPriorStatement()
+{
+}
+
+BasicPriorStatement::BasicPriorStatement(const string &name_arg,
+                                         const expr_t &variance_arg,
+                                         const OptionsList &options_list_arg) :
+  name(name_arg),
+  variance(variance_arg),
+  options_list(options_list_arg),
+  first_statement_encountered(false)
+{
+}
+
+void
+BasicPriorStatement::checkPass(ModFileStructure &mod_file_struct)
+{
+  if (options_list.num_options.find("shape") == options_list.num_options.end())
+    {
+      cerr << "ERROR: You must pass the shape option to the prior statement." << endl;
+      exit(EXIT_FAILURE);
+    }
+}
+
+void
+BasicPriorStatement::get_base_name(const SymbolType symb_type, string &lhs_field) const
+{
+  if (symb_type == eExogenous || symb_type == eExogenousDet)
+    lhs_field = "structural_innovation";
+  else
+    lhs_field = "measurement_error";
+}
+
+void
+BasicPriorStatement::writePriorIndex(ostream &output, const string &lhs_field) const
+{
+  if (first_statement_encountered)
+    output << "prior_indx = 1;" << endl;
+  else
+    output << "prior_indx = size(estimation_info" << lhs_field << "_index, 2) + 1;" << endl;
+}
+
+void
+BasicPriorStatement::writeVarianceOption(ostream &output, const string &lhs_field) const
+{
+  if (variance)
+    {
+      output << "estimation_info" << lhs_field << "(prior_indx).variance = ";
+      variance->writeOutput(output);
+      output << ";" << endl;
+    }
+}
+
+void
+BasicPriorStatement::writeOutputHelper(ostream &output, const string &field, const string &lhs_field) const
+{
+  OptionsList::num_options_t::const_iterator it = options_list.num_options.find(field);
+  if (it != options_list.num_options.end())
+    output << "estimation_info" << lhs_field << "(prior_indx)." << field
+           << " = " << it->second << ";" << endl;
+}
+
+PriorStatement::PriorStatement(const string &name_arg,
+                               const expr_t &variance_arg,
+                               const OptionsList &options_list_arg) :
+  BasicPriorStatement(name_arg, variance_arg, options_list_arg)
+{
+}
+
+void
+PriorStatement::checkPass(ModFileStructure &mod_file_struct)
+{
+  BasicPriorStatement::checkPass(mod_file_struct);
+  if (!mod_file_struct.prior_statement_present)
+    first_statement_encountered = true;
+  mod_file_struct.prior_statement_present = true;
+}
+
+void
+PriorStatement::writeOutput(ostream &output, const string &basename) const
+{
+  string lhs_field = ".prior";
+
+  BasicPriorStatement::writePriorIndex(output, lhs_field);
+  output << "estimation_info" << lhs_field << "_index(prior_indx) = {'" << name << "'};" << endl
+         << "estimation_info" << lhs_field <<"(prior_indx).name = '" << name << "';" << endl;
+
+  writeOutputHelper(output, "mean", lhs_field);
+  writeOutputHelper(output, "mode", lhs_field);
+  writeOutputHelper(output, "stdev", lhs_field);
+  writeOutputHelper(output, "shape", lhs_field);
+  writeOutputHelper(output, "shift", lhs_field);
+  writeOutputHelper(output, "domain", lhs_field);
+  writeOutputHelper(output, "interval", lhs_field);
+  BasicPriorStatement::writeVarianceOption(output, lhs_field);
+}
+
+StdPriorStatement::StdPriorStatement(const string &name_arg,
+                                     const expr_t &variance_arg,
+                                     const OptionsList &options_list_arg,
+                                     const SymbolTable &symbol_table_arg ) :
+  BasicPriorStatement(name_arg, variance_arg, options_list_arg),
+  symbol_table(symbol_table_arg)
+{
+}
+
+void
+StdPriorStatement::checkPass(ModFileStructure &mod_file_struct)
+{
+  BasicPriorStatement::checkPass(mod_file_struct);
+  if (!mod_file_struct.std_prior_statement_present)
+    first_statement_encountered = true;
+  mod_file_struct.std_prior_statement_present = true;
+}
+
+void
+StdPriorStatement::writeOutput(ostream &output, const string &basename) const
+{
+  string lhs_field;
+  get_base_name(symbol_table.getType(name), lhs_field);
+  lhs_field = "." + lhs_field + ".prior";
+
+  BasicPriorStatement::writePriorIndex(output, lhs_field);
+  output << "estimation_info" << lhs_field << "_index(prior_indx) = {'" << name << "'};" << endl;
+  output << "estimation_info" << lhs_field << "(prior_indx).name = '" << name << "';" << endl;
+
+  writeOutputHelper(output, "mean", lhs_field);
+  writeOutputHelper(output, "mode", lhs_field);
+  writeOutputHelper(output, "stdev", lhs_field);
+  writeOutputHelper(output, "shape", lhs_field);
+  writeOutputHelper(output, "shift", lhs_field);
+  writeOutputHelper(output, "domain", lhs_field);
+  writeOutputHelper(output, "interval", lhs_field);
+  BasicPriorStatement::writeVarianceOption(output, lhs_field);
+}
+
+CorrPriorStatement::CorrPriorStatement(const string &name_arg1, const string &name_arg2,
+                                       const expr_t &variance_arg,
+                                       const OptionsList &options_list_arg,
+                                       const SymbolTable &symbol_table_arg ) :
+  BasicPriorStatement(name_arg1, variance_arg, options_list_arg),
+  name1(name_arg2),
+  symbol_table(symbol_table_arg)
+{
+}
+
+void
+CorrPriorStatement::checkPass(ModFileStructure &mod_file_struct)
+{
+  BasicPriorStatement::checkPass(mod_file_struct);
+  if (symbol_table.getType(name) != symbol_table.getType(name1))
+    {
+      cerr << "ERROR: In the corr(A,B).prior statement, A and B must be of the same type. "
+           << "In your case, " << name << " and " << name1 << " are of different "
+           << "types." << endl;
+      exit(EXIT_FAILURE);
+    }
+  if (!mod_file_struct.corr_prior_statement_present)
+    first_statement_encountered = true;
+  mod_file_struct.corr_prior_statement_present = true;
+}
+
+void
+CorrPriorStatement::writeOutput(ostream &output, const string &basename) const
+{
+  string lhs_field;
+  get_base_name(symbol_table.getType(name), lhs_field);
+  lhs_field = "." + lhs_field + "_corr.prior";
+
+  BasicPriorStatement::writePriorIndex(output, lhs_field);
+  output << "estimation_info" << lhs_field << "_index(prior_indx) = {'" << name << "_" << name1 << "'};" << endl;
+  output << "estimation_info" << lhs_field << "(prior_indx).name1 = '" << name << "';" << endl;
+  output << "estimation_info" << lhs_field << "(prior_indx).name2 = '" << name1 << "';" << endl;
+
+  writeOutputHelper(output, "mean", lhs_field);
+  writeOutputHelper(output, "mode", lhs_field);
+  writeOutputHelper(output, "stdev", lhs_field);
+  writeOutputHelper(output, "shape", lhs_field);
+  writeOutputHelper(output, "shift", lhs_field);
+  writeOutputHelper(output, "domain", lhs_field);
+  writeOutputHelper(output, "interval", lhs_field);
+  BasicPriorStatement::writeVarianceOption(output, lhs_field);
+}
diff --git a/preprocessor/ComputingTasks.hh b/preprocessor/ComputingTasks.hh
index a04a7d18b2..c69043fb65 100644
--- a/preprocessor/ComputingTasks.hh
+++ b/preprocessor/ComputingTasks.hh
@@ -575,5 +575,61 @@ public:
   virtual void writeOutput(ostream &output, const string &basename) const;
 };
 
+class BasicPriorStatement : public Statement
+{
+public:
+  virtual ~BasicPriorStatement();
+protected:
+  const string name;
+  const expr_t variance;
+  const OptionsList options_list;
+  bool first_statement_encountered;
+  BasicPriorStatement(const string &name_arg,
+                      const expr_t &variance_arg,
+                      const OptionsList &options_list_arg);
+  virtual void checkPass(ModFileStructure &mod_file_struct);
+  void get_base_name(const SymbolType symb_type, string &lhs_field) const;
+  void writePriorIndex(ostream &output, const string &lhs_field) const;
+  void writeVarianceOption(ostream &output, const string &lhs_field) const;
+  void writeOutputHelper(ostream &output, const string &field, const string &lhs_field) const;
+};
+
+class PriorStatement : public BasicPriorStatement
+{
+public:
+  PriorStatement(const string &name_arg,
+                 const expr_t &variance_arg,
+                 const OptionsList &options_list_arg);
+  virtual void checkPass(ModFileStructure &mod_file_struct);
+  virtual void writeOutput(ostream &output, const string &basename) const;
+};
+
+class StdPriorStatement : public BasicPriorStatement
+{
+private:
+  const SymbolTable symbol_table;
+public:
+  StdPriorStatement(const string &name_arg,
+                    const expr_t &variance_arg,
+                    const OptionsList &options_list_arg,
+                    const SymbolTable &symbol_table_arg);
+  virtual void checkPass(ModFileStructure &mod_file_struct);
+  virtual void writeOutput(ostream &output, const string &basename) const;
+};
+
+class CorrPriorStatement : public BasicPriorStatement
+{
+private:
+  const string name1;
+  const SymbolTable symbol_table;
+public:
+  CorrPriorStatement(const string &name_arg1,
+                     const string &name_arg2,
+                     const expr_t &variance_arg,
+                     const OptionsList &options_list_arg,
+                     const SymbolTable &symbol_table_arg);
+  virtual void checkPass(ModFileStructure &mod_file_struct);
+  virtual void writeOutput(ostream &output, const string &basename) const;
+};
 
 #endif
diff --git a/preprocessor/DynareBison.yy b/preprocessor/DynareBison.yy
index 772369462f..299bae37d8 100644
--- a/preprocessor/DynareBison.yy
+++ b/preprocessor/DynareBison.yy
@@ -98,8 +98,8 @@ class ParsingDriver;
 %token END ENDVAL EQUAL ESTIMATION ESTIMATED_PARAMS ESTIMATED_PARAMS_BOUNDS ESTIMATED_PARAMS_INIT
 %token FILENAME FILTER_STEP_AHEAD FILTERED_VARS FIRST_OBS LAST_OBS SET_TIME
 %token <string_val> FLOAT_NUMBER
-%token FORECAST K_ORDER_SOLVER INSTRUMENTS
-%token GAMMA_PDF GRAPH CONDITIONAL_VARIANCE_DECOMPOSITION NOCHECK
+%token FORECAST K_ORDER_SOLVER INSTRUMENTS PRIOR SHIFT MEAN STDEV VARIANCE MODE INTERVAL SHAPE DOMAINN
+%token GAMMA_PDF GRAPH CONDITIONAL_VARIANCE_DECOMPOSITION NOCHECK STD
 %token HISTVAL HOMOTOPY_SETUP HOMOTOPY_MODE HOMOTOPY_STEPS HP_FILTER HP_NGRID
 %token IDENTIFICATION INF_CONSTANT INITVAL INITVAL_FILE
 %token <string_val> INT_NUMBER
@@ -147,7 +147,7 @@ class ParsingDriver;
 %token VLISTLOG VLISTPER
 %token RESTRICTION RESTRICTIONS RESTRICTION_FNAME CROSS_RESTRICTIONS NLAGS CONTEMP_REDUCED_FORM REAL_PSEUDO_FORECAST 
 %token NONE DUMMY_OBS NSTATES INDXSCALESSTATES NO_BAYESIAN_PRIOR SPECIFICATION SIMS_ZHA
-%token <string_val> ALPHA BETA ABAND NINV CMS NCMS CNUM
+%token <string_val> ALPHA BETA ABAND NINV CMS NCMS CNUM GAMMA INV_GAMMA INV_GAMMA1 INV_GAMMA2 NORMAL UNIFORM
 %token GSIG2_LMDM Q_DIAG FLAT_PRIOR NCSK NSTD
 %token INDXPARR INDXOVR INDXAP APBAND INDXIMF IMFBAND INDXFORE FOREBAND INDXGFOREHAT INDXGIMFHAT
 %token INDXESTIMA INDXGDLS EQ_MS FILTER_COVARIANCE FILTER_DECOMPOSITION
@@ -175,9 +175,9 @@ class ParsingDriver;
 %type <node_val> expression expression_or_empty
 %type <node_val> equation hand_side
 %type <string_val> non_negative_number signed_number signed_integer date_number
-%type <string_val> filename symbol
+%type <string_val> filename symbol prior_distribution
 %type <string_val> vec_value_1 vec_value
-%type <string_val> range prior
+%type <string_val> range prior_pdf_string
 %type <symbol_type_val> change_type_arg
 %type <vector_string_val> change_type_var_list
 %type <vector_int_val> vec_int_elem vec_int_1 vec_int vec_int_number
@@ -216,6 +216,7 @@ statement : parameters
           | estimated_params_init
           | set_time
           | data
+          | prior
           | varobs
           | observation_trends
           | unit_root_vars
@@ -1014,18 +1015,18 @@ estimated_elem1 : STDERR symbol
                   }
                 ;
 
-estimated_elem2 : prior COMMA estimated_elem3
+estimated_elem2 : prior_pdf_string COMMA estimated_elem3
                   {
                     driver.estim_params.prior = *$1;
                     delete $1;
                   }
-                | expression_or_empty COMMA prior COMMA estimated_elem3
+                | expression_or_empty COMMA prior_pdf_string COMMA estimated_elem3
                   {
                     driver.estim_params.init_val = $1;
                     driver.estim_params.prior = *$3;
                     delete $3;
                   }
-                | expression_or_empty COMMA expression_or_empty COMMA expression_or_empty COMMA prior COMMA estimated_elem3
+                | expression_or_empty COMMA expression_or_empty COMMA expression_or_empty COMMA prior_pdf_string COMMA estimated_elem3
                   {
                     driver.estim_params.init_val = $1;
                     driver.estim_params.low_bound = $3;
@@ -1144,21 +1145,37 @@ estimated_bounds_elem : STDERR symbol COMMA expression COMMA expression ';'
                         }
                       ;
 
-prior : BETA_PDF
-        { $$ = new string("1"); }
-      | GAMMA_PDF
-        { $$ = new string("2"); }
-      | NORMAL_PDF
-        { $$ = new string("3"); }
-      | INV_GAMMA_PDF
-        { $$ = new string("4"); }
-      | INV_GAMMA1_PDF
-        { $$ = new string("4"); }
-      | UNIFORM_PDF
-        { $$ = new string("5"); }
-      | INV_GAMMA2_PDF
-        { $$ = new string("6"); }
-      ;
+prior_distribution : BETA
+                     { $$ = new string("1"); }
+                   | GAMMA
+                     { $$ = new string("2"); }
+                   | NORMAL
+                     { $$ = new string("3"); }
+                   | INV_GAMMA
+                     { $$ = new string("4"); }
+                   | INV_GAMMA1
+                     { $$ = new string("4"); }
+                   | UNIFORM
+                     { $$ = new string("5"); }
+                   | INV_GAMMA2
+                     { $$ = new string("6"); }
+                   ;
+
+prior_pdf_string : BETA_PDF
+                   { $$ = new string("1"); }
+                 | GAMMA_PDF
+                   { $$ = new string("2"); }
+                 | NORMAL_PDF
+                   { $$ = new string("3"); }
+                 | INV_GAMMA_PDF
+                   { $$ = new string("4"); }
+                 | INV_GAMMA1_PDF
+                   { $$ = new string("4"); }
+                 | UNIFORM_PDF
+                   { $$ = new string("5"); }
+                 | INV_GAMMA2_PDF
+                   { $$ = new string("6"); }
+                 ;
 
 set_time : SET_TIME '(' date_number ')' ';'
            { driver.set_time($3); }
@@ -1180,6 +1197,28 @@ data_options : o_file
              | o_xls_range
              ;
 
+prior : symbol '.' PRIOR '(' prior_options_list ')' ';'
+        { driver.set_prior($1); }
+      | STD '(' symbol ')' '.' PRIOR '(' prior_options_list ')' ';'
+        { driver.set_std_prior($3); }
+      | CORR '(' symbol COMMA symbol')' '.' PRIOR '(' prior_options_list ')' ';'
+        { driver.set_corr_prior($3, $5); }
+      ;
+
+prior_options_list : prior_options_list COMMA prior_options
+                   | prior_options
+                   ;
+
+prior_options : o_shift
+              | o_mean
+              | o_stdev
+              | o_variance
+              | o_mode
+              | o_interval
+              | o_shape
+              | o_domain
+              ;
+
 estimation : ESTIMATION ';'
              { driver.run_estimation(); }
            | ESTIMATION '(' estimation_options_list ')' ';'
@@ -1898,8 +1937,15 @@ o_new_estimation_data_first_obs : FIRST_OBS EQUAL date_number
 o_last_obs : LAST_OBS EQUAL date_number
              { driver.option_date("last_obs", $3); }
            ;
+o_shift : SHIFT EQUAL signed_number { driver.option_num("shift", $3); };
+o_shape : SHAPE EQUAL prior_distribution { driver.option_num("shape", $3); };
+o_mode : MODE EQUAL signed_number { driver.option_num("mode", $3); };
+o_mean : MEAN EQUAL signed_number { driver.option_num("mean", $3); };
+o_stdev : STDEV EQUAL non_negative_number { driver.option_num("stdev", $3); };
+o_domain : DOMAINN EQUAL vec_value { driver.option_num("domain", $3); };
+o_interval : INTERVAL EQUAL vec_value { driver.option_num("interval", $3); };
+o_variance : VARIANCE EQUAL expression { driver.add_expression_to_prior_statement($3); }
 o_new_estimation_data_nobs : NOBS EQUAL INT_NUMBER { driver.option_num("nobs", $3); };
-
 o_prefilter : PREFILTER EQUAL INT_NUMBER { driver.option_num("prefilter", $3); };
 o_presample : PRESAMPLE EQUAL INT_NUMBER { driver.option_num("presample", $3); };
 o_lik_algo : LIK_ALGO EQUAL INT_NUMBER { driver.option_num("lik_algo", $3); };
@@ -2276,6 +2322,12 @@ symbol : NAME
        | CMS
        | NCMS
        | CNUM
+       | GAMMA
+       | INV_GAMMA
+       | INV_GAMMA1
+       | INV_GAMMA2
+       | NORMAL
+       | UNIFORM
        ;
 %%
 
diff --git a/preprocessor/DynareFlex.ll b/preprocessor/DynareFlex.ll
index ea17c7c630..56afce82ef 100644
--- a/preprocessor/DynareFlex.ll
+++ b/preprocessor/DynareFlex.ll
@@ -189,12 +189,24 @@ string eofbuff;
  /* End of a Dynare block */
 <DYNARE_BLOCK>end 	{BEGIN INITIAL; return token::END;}
 
+<DYNARE_STATEMENT>prior {return token::PRIOR;}
+<INITIAL>std {BEGIN DYNARE_STATEMENT; return token::STD;}
+<INITIAL>corr {BEGIN DYNARE_STATEMENT; return token::CORR;}
+
  /* Inside  of a Dynare statement */
 <DYNARE_STATEMENT>file                  {return token::FILE;}
 <DYNARE_STATEMENT>datafile 		{return token::DATAFILE;}
 <DYNARE_STATEMENT>nobs 			{return token::NOBS;}
 <DYNARE_STATEMENT>last_obs 		{return token::LAST_OBS;}
 <DYNARE_STATEMENT>first_obs 		{return token::FIRST_OBS;}
+<DYNARE_STATEMENT>mean                  {return token::MEAN;}
+<DYNARE_STATEMENT>stdev                 {return token::STDEV;}
+<DYNARE_STATEMENT>domain                {return token::DOMAINN;}
+<DYNARE_STATEMENT>variance              {return token::VARIANCE;}
+<DYNARE_STATEMENT>mode                  {return token::MODE;}
+<DYNARE_STATEMENT>interval              {return token::INTERVAL;}
+<DYNARE_STATEMENT>shape                 {return token::SHAPE;}
+<DYNARE_STATEMENT>shift                 {return token::SHIFT;}
 <DYNARE_STATEMENT>prefilter 		{return token::PREFILTER;}
 <DYNARE_STATEMENT>presample 		{return token::PRESAMPLE;}
 <DYNARE_STATEMENT>lik_algo  		{return token::LIK_ALGO;}
@@ -253,7 +265,6 @@ string eofbuff;
 <DYNARE_STATEMENT>nargs {return token::EXT_FUNC_NARGS;}
 <DYNARE_STATEMENT>first_deriv_provided {return token::FIRST_DERIV_PROVIDED;}
 <DYNARE_STATEMENT>second_deriv_provided {return token::SECOND_DERIV_PROVIDED;}
-
 <DYNARE_STATEMENT>freq {return token::FREQ;}
 <DYNARE_STATEMENT>monthly {return token::MONTHLY; }
 <DYNARE_STATEMENT>quarterly {return token::QUARTERLY; }
@@ -281,6 +292,30 @@ string eofbuff;
   yylval->string_val = new string(yytext);
   return token::BETA;
 }
+<DYNARE_STATEMENT>gamma {
+  yylval->string_val = new string(yytext);
+  return token::GAMMA;
+}
+<DYNARE_STATEMENT>inv_gamma {
+  yylval->string_val = new string(yytext);
+  return token::INV_GAMMA;
+}
+<DYNARE_STATEMENT>inv_gamma1 {
+  yylval->string_val = new string(yytext);
+  return token::INV_GAMMA1;
+}
+<DYNARE_STATEMENT>inv_gamma2 {
+  yylval->string_val = new string(yytext);
+  return token::INV_GAMMA2;
+}
+<DYNARE_STATEMENT>normal {
+  yylval->string_val = new string(yytext);
+  return token::NORMAL;
+}
+<DYNARE_STATEMENT>uniform {
+  yylval->string_val = new string(yytext);
+  return token::UNIFORM;
+}
 <DYNARE_STATEMENT>gsig2_lmdm {return token::GSIG2_LMDM;}
 <DYNARE_STATEMENT>specification {return token::SPECIFICATION;}
 <DYNARE_STATEMENT>sims_zha {return token::SIMS_ZHA;}
diff --git a/preprocessor/ModFile.cc b/preprocessor/ModFile.cc
index 20356dfbdf..6b79d10f30 100644
--- a/preprocessor/ModFile.cc
+++ b/preprocessor/ModFile.cc
@@ -449,7 +449,7 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool console,
     }
 
   mOutputFile << "tic;" << endl
-              << "global M_ oo_ options_ ys0_ ex0_" << endl
+              << "global M_ oo_ options_ ys0_ ex0_ estimation_info" << endl
               << "options_ = [];" << endl
               << "M_.fname = '" << basename << "';" << endl
               << "%" << endl
diff --git a/preprocessor/ParsingDriver.cc b/preprocessor/ParsingDriver.cc
index 541f08580e..9cf200c89f 100644
--- a/preprocessor/ParsingDriver.cc
+++ b/preprocessor/ParsingDriver.cc
@@ -46,6 +46,15 @@ ParsingDriver::check_symbol_existence(const string &name)
     error("Unknown symbol: " + name);
 }
 
+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");
+}
+
 void
 ParsingDriver::set_current_data_tree(DataTree *data_tree_arg)
 {
@@ -372,13 +381,9 @@ ParsingDriver::dsample(string *arg1, string *arg2)
 void
 ParsingDriver::init_param(string *name, expr_t rhs)
 {
-  check_symbol_existence(*name);
+  check_symbol_is_parameter(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");
-
   mod_file->addStatement(new InitParamStatement(symb_id, rhs, mod_file->symbol_table));
-
   delete name;
 }
 
@@ -1219,6 +1224,60 @@ ParsingDriver::estimation_data()
   options_list.clear();
 }
 
+void
+ParsingDriver::set_prior(string *name)
+{
+  check_symbol_is_parameter(name);
+  mod_file->addStatement(new PriorStatement(*name, prior_variance, options_list));
+  options_list.clear();
+  prior_variance = NULL;
+  delete name;
+}
+
+void
+ParsingDriver::add_expression_to_prior_statement(expr_t variance)
+{
+  prior_variance = variance;
+}
+
+void
+ParsingDriver::check_symbol_is_endogenous_or_exogenous(string *name)
+{
+  check_symbol_existence(*name);
+  int symb_id = mod_file->symbol_table.getID(*name);
+  switch(mod_file->symbol_table.getType(symb_id))
+    {
+    case eEndogenous:
+    case eExogenous:
+    case eExogenousDet:
+      break;
+    default:
+      error(*name + " is neither endogenous or exogenous.");
+    }
+}
+
+void
+ParsingDriver::set_std_prior(string *name)
+{
+  check_symbol_is_endogenous_or_exogenous(name);
+  mod_file->addStatement(new StdPriorStatement(*name, prior_variance, options_list, mod_file->symbol_table));
+  options_list.clear();
+  prior_variance = NULL;
+  delete name;
+}
+
+void
+ParsingDriver::set_corr_prior(string *name1, string *name2)
+{
+  check_symbol_is_endogenous_or_exogenous(name1);
+  check_symbol_is_endogenous_or_exogenous(name2);
+  mod_file->addStatement(new CorrPriorStatement(*name1, *name2, prior_variance, options_list, mod_file->symbol_table));
+  options_list.clear();
+  prior_variance = NULL;
+  delete name1;
+  delete name2;
+}
+
 void
 ParsingDriver::run_estimation()
 {
diff --git a/preprocessor/ParsingDriver.hh b/preprocessor/ParsingDriver.hh
index 2afbd09c02..6c35297e80 100644
--- a/preprocessor/ParsingDriver.hh
+++ b/preprocessor/ParsingDriver.hh
@@ -81,6 +81,12 @@ private:
   //! Checks that a given symbol exists, and stops with an error message if it doesn't
   void check_symbol_existence(const string &name);
 
+  //! Checks that a given symbol exists and is a parameter, and stops with an error message if it isn't
+  void check_symbol_is_parameter(string *name);
+
+  //! Checks that a given symbol exists and is a endogenous or exogenous, and stops with an error message if it isn't
+  void check_symbol_is_endogenous_or_exogenous(string *name);
+
   //! Helper to add a symbol declaration
   void declare_symbol(const string *name, SymbolType type, const string *tex_name);
 
@@ -178,6 +184,8 @@ private:
   vector<int> declared_trend_vars;
   //! Temporary storage for declaring nonstationary variables
   vector<int> declared_nonstationary_vars;
+  //! Temporary storage for a variance declared in the prior statement
+  expr_t prior_variance;
   //! reset the values for temporary storage
   void reset_current_external_function_options();
   //! Adds a model lagged variable to ModelTree and VariableTable
@@ -359,6 +367,16 @@ public:
   void set_time(string *arg);
   //! Estimation Data
   void estimation_data();
+  //! Sets the prior for a parameter
+  void set_prior(string *arg);
+  //! Adds the variance option to its temporary holding place
+  void add_expression_to_prior_statement(expr_t variance);
+  //! Sets the prior for estimated std dev
+  void set_std_prior(string *arg);
+  //! Sets the prior for estimated correlation
+  void set_corr_prior(string *arg1, string *arg2);
+  //! Sets the subsamples for a parameter
+  void set_subsamples(string *arg);
   //! Runs estimation process
   void run_estimation();
   //! Runs dynare_sensitivy()
diff --git a/preprocessor/Statement.hh b/preprocessor/Statement.hh
index 0f0c2beeed..a6091437ab 100644
--- a/preprocessor/Statement.hh
+++ b/preprocessor/Statement.hh
@@ -88,6 +88,12 @@ public:
   bool bayesian_irf_present;
   //! Whether there is a data statement present
   bool estimation_data_statement_present;
+  //! Whether there is a prior statement present
+  bool prior_statement_present;
+  //! Whether there is a std prior statement present
+  bool std_prior_statement_present;
+  //! Whether there is a corr prior statement present
+  bool corr_prior_statement_present;
 };
 
 class Statement
-- 
GitLab