From 65a6e5cf6e7491ac08277f95c1b23ea4d3c4a3f9 Mon Sep 17 00:00:00 2001
From: houtanb <houtanb@ac1d8469-bf42-47a9-8791-bf33cf982152>
Date: Wed, 9 Dec 2009 00:38:53 +0000
Subject: [PATCH] swz: implementation of svar

git-svn-id: https://www.dynare.org/svn/dynare/trunk@3214 ac1d8469-bf42-47a9-8791-bf33cf982152
---
 ComputingTasks.cc | 47 +++++++++++++++++++++++++++++++++++++
 ComputingTasks.hh |  9 ++++++++
 DynareBison.yy    | 22 +++++++++---------
 DynareFlex.ll     |  3 ++-
 ParsingDriver.cc  | 59 +++++++++++++++++++++++++++++++++++++++++++++++
 ParsingDriver.hh  |  2 ++
 6 files changed, 130 insertions(+), 12 deletions(-)

diff --git a/ComputingTasks.cc b/ComputingTasks.cc
index d33a42d1..dcf3b6eb 100644
--- a/ComputingTasks.cc
+++ b/ComputingTasks.cc
@@ -1181,3 +1181,50 @@ MarkovSwitchingStatement::writeOutput(ostream &output, const string &basename) c
       exit(EXIT_FAILURE);
     }
 }
+
+
+SvarStatement::SvarStatement(const OptionsList &options_list_arg) :
+  options_list(options_list_arg)
+{
+}
+
+void
+SvarStatement::writeOutput(ostream &output, const string &basename) const
+{
+  OptionsList::num_options_type::const_iterator it0, it1, it2;
+
+  it0 = options_list.num_options.find("ms.chain");
+  if (it0 != options_list.num_options.end())
+    output << "options_.ms.ms_chain(" << it0->second << ")";
+  else
+    {
+      cerr << "SvarStatement::writeOutput() Should not arrive here (1). Please report this to the Dynare Team." << endl;
+      exit(EXIT_FAILURE);
+    }
+
+
+  it0 = options_list.string_options.find("ms.coefficients");
+  it1 = options_list.string_options.find("ms.variances");
+  it2 = options_list.string_options.find("ms.constants");
+  if (it0 != options_list.string_options.end() && it1 == options_list.string_options.end() && it2 == options_list.string_options.end())
+    output << "." << it0->second;
+  else if (it0 == options_list.string_options.end() && it1 != options_list.string_options.end() && it2 == options_list.string_options.end())
+    output << "." << it1->second;
+  else if (it0 == options_list.string_options.end() && it1 == options_list.string_options.end() && it2 != options_list.string_options.end())
+    output << "." << it2->second;
+  else
+    {
+      cerr << "SvarStatement::writeOutput() Should not arrive here (2). Please report this to the Dynare Team." << endl;
+      exit(EXIT_FAILURE);
+    }
+
+
+  it0 = options_list.num_options.find("ms.equations");
+  if (it0 != options_list.num_options.end())
+    output << ".equations = " << it0->second << ";" << endl;
+  else
+    {
+      cerr << "SvarStatement::writeOutput() Should not arrive here (3). Please report this to the Dynare Team." << endl;
+      exit(EXIT_FAILURE);
+    }
+}
diff --git a/ComputingTasks.hh b/ComputingTasks.hh
index 1c59323f..d7ee489a 100644
--- a/ComputingTasks.hh
+++ b/ComputingTasks.hh
@@ -517,4 +517,13 @@ public:
   virtual void writeOutput(ostream &output, const string &basename) const;
 };
 
+class SvarStatement : public Statement
+{
+private:
+  const OptionsList options_list;
+public:
+  SvarStatement(const OptionsList &options_list_arg);
+  virtual void writeOutput(ostream &output, const string &basename) const;
+};
+
 #endif
diff --git a/DynareBison.yy b/DynareBison.yy
index 75feeb27..4e426691 100644
--- a/DynareBison.yy
+++ b/DynareBison.yy
@@ -156,7 +156,7 @@ class ParsingDriver;
 %token SBVAR MS_SBVAR
 %token SVAR_IDENTIFICATION EQUATION EXCLUSION LAG UPPER_CHOLESKY LOWER_CHOLESKY
 %token MARKOV_SWITCHING CHAIN STATE DURATION NUMBER_OF_STATES
-%token SVAR COEFFICIENTS VARIANCES CONSTANTS
+%token SVAR COEFFICIENTS VARIANCES CONSTANTS EQUATIONS
 
 %type <node_val> expression expression_or_empty
 %type <node_val> equation hand_side model_var
@@ -643,7 +643,7 @@ ms_options : o_chain
            ;
 
 svar : SVAR '(' svar_options_list ')' ';'
-       { ;}
+       { driver.svar(); }
      ;
 
 svar_options_list : svar_options_list COMMA svar_options
@@ -653,7 +653,7 @@ svar_options_list : svar_options_list COMMA svar_options
 svar_options : o_coefficients
              | o_variances
              | o_constants
-             | o_equation
+             | o_equations
              | o_chain
              ;
 
@@ -1867,14 +1867,14 @@ o_duration : DURATION EQUAL number
              { driver.option_num("ms.duration","Inf"); }
            ;
 o_number_of_states : NUMBER_OF_STATES EQUAL INT_NUMBER { driver.option_num("ms.number_of_states",$3); };
-o_coefficients : COEFFICIENTS { ;};
-o_variances : VARIANCES { ;};
-o_constants : CONSTANTS { ;};
-o_equation : EQUATION EQUAL vec_int
-             { ; }
-           | EQUATION EQUAL INT_NUMBER
-             { ; }
-           ;
+o_coefficients : COEFFICIENTS { driver.option_str("ms.coefficients","svar_coefficients"); };
+o_variances : VARIANCES { driver.option_str("ms.variances","svar_variances"); };
+o_constants : CONSTANTS { driver.option_str("ms.constants","svar_constants"); };
+o_equations : EQUATIONS EQUAL vec_int
+              { driver.option_num("ms.equations",$3); }
+            | EQUATIONS EQUAL INT_NUMBER
+              { driver.option_num("ms.equations",$3); }
+            ;
 
 range : symbol ':' symbol
         {
diff --git a/DynareFlex.ll b/DynareFlex.ll
index 28d2d67c..d2245072 100644
--- a/DynareFlex.ll
+++ b/DynareFlex.ll
@@ -395,7 +395,7 @@ int sigma_e = 0;
 <DYNARE_STATEMENT>planner_discount {return token::PLANNER_DISCOUNT;}
 <DYNARE_STATEMENT>labels {return token::LABELS;}
 
-<DYNARE_STATEMENT,DYNARE_BLOCK>equation {return token::EQUATION;}
+<DYNARE_BLOCK>equation {return token::EQUATION;}
 <DYNARE_BLOCK>exclusion {return token::EXCLUSION;}
 <DYNARE_BLOCK>lag {return token::LAG;}
 <DYNARE_BLOCK>upper_cholesky {return token::UPPER_CHOLESKY;}
@@ -407,6 +407,7 @@ int sigma_e = 0;
 <DYNARE_STATEMENT>coefficients {return token::COEFFICIENTS;}
 <DYNARE_STATEMENT>variances {return token::VARIANCES;}
 <DYNARE_STATEMENT>constants {return token::CONSTANTS;}
+<DYNARE_STATEMENT>equations {return token::EQUATIONS;}
 
 <DYNARE_STATEMENT>[\.] {return Dynare::parser::token_type (yytext[0]);}
 <DYNARE_STATEMENT>[\\] {return Dynare::parser::token_type (yytext[0]);}
diff --git a/ParsingDriver.cc b/ParsingDriver.cc
index bc754ff3..ebcbc65f 100644
--- a/ParsingDriver.cc
+++ b/ParsingDriver.cc
@@ -1194,6 +1194,65 @@ ParsingDriver::ms_sbvar()
   options_list.clear();
 }
 
+void
+ParsingDriver::svar()
+{
+  OptionsList::num_options_type::const_iterator it0, it1, it2;
+
+  it0 = options_list.string_options.find("ms.coefficients");
+  it1 = options_list.string_options.find("ms.variances");
+  it2 = options_list.string_options.find("ms.constants");
+  if (it0 == options_list.string_options.end() &&
+      it1 == options_list.string_options.end() &&
+      it2 == options_list.string_options.end())
+    error("You must pass one of 'coefficients', 'variances', or 'constants'.");
+
+  if ((it0 != options_list.string_options.end() &&
+       it1 != options_list.string_options.end()) ||
+      (it1 != options_list.string_options.end() &&
+       it2 != options_list.string_options.end()) ||
+      (it0 != options_list.string_options.end() &&
+       it2 != options_list.string_options.end()))
+    error("You may only pass one 'coefficients', 'variances', or 'constants' option.");
+
+  it0 = options_list.num_options.find("ms.chain");
+  if (it0 == options_list.num_options.end())
+    error("A chain option must be passed to the svar statement.");
+  else if (atoi(it0->second.c_str()) <= 0)
+    error("The value passed to the chain option must be greater than zero.");
+
+  it0 = options_list.num_options.find("ms.equations");
+  if (it0 == options_list.num_options.end())
+    error("A chain option must be passed to the svar statement.");
+  else
+    {
+      string strNextNumber;
+      for (string::const_iterator it=it0->second.begin(); it<it0->second.end(); it++)
+        {
+          if (*it == '[' ||
+              *it == ',' ||
+              *it == ' ' ||
+              *it == ':' ||
+              *it == ']')
+            {
+              if (!strNextNumber.empty())
+                if (atoi(strNextNumber.c_str()) <= 0)
+                  error("The value(s) passed to the equation option must be greater than zero.");
+              strNextNumber.clear();
+            }
+          else
+            strNextNumber += *it;
+        }
+
+      if (!strNextNumber.empty())
+        if (atoi(strNextNumber.c_str()) <= 0)
+          error("The value(s) passed to the equation option must be greater than zero.");
+    }
+
+  mod_file->addStatement(new SvarStatement(options_list));
+  options_list.clear();
+}
+
 void
 ParsingDriver::markov_switching()
 {
diff --git a/ParsingDriver.hh b/ParsingDriver.hh
index a9d3253b..4498aaee 100644
--- a/ParsingDriver.hh
+++ b/ParsingDriver.hh
@@ -371,6 +371,8 @@ public:
   void sbvar();
   //! MS_SBVAR statement
   void ms_sbvar();
+  //! Svar statement
+  void svar();
   //! MarkovSwitching statement
   void markov_switching();
   //! Shock decomposition
-- 
GitLab