diff --git a/src/ComputingTasks.cc b/src/ComputingTasks.cc
index 855da295f7928eb9085c453e0aa55fcf0e1ad289..37924dc92a061ac6083acdad3970bac689572707 100644
--- a/src/ComputingTasks.cc
+++ b/src/ComputingTasks.cc
@@ -3465,69 +3465,57 @@ SvarIdentificationStatement::writeJsonOutput(ostream &output) const
 MarkovSwitchingStatement::MarkovSwitchingStatement(OptionsList options_list_arg) :
   options_list{move(options_list_arg)}
 {
-  if (auto it_num = options_list.num_options.find("ms.restrictions");
-      it_num != options_list.num_options.end())
+  if (auto it_num = options_list.vector_of_vector_value_options.find("ms.restrictions");
+      it_num != options_list.vector_of_vector_value_options.end())
     {
-      using namespace boost;
       auto it_num_regimes = options_list.num_options.find("ms.number_of_regimes");
       assert(it_num_regimes != options_list.num_options.end());
       auto num_regimes = stoi(it_num_regimes->second);
 
-      vector<string> tokenizedRestrictions;
-      split(tokenizedRestrictions, it_num->second, is_any_of("["), token_compress_on);
-      for (auto &tokenizedRestriction : tokenizedRestrictions)
-        if (tokenizedRestriction.size() > 0)
-          {
-            vector<string> restriction;
-            split(restriction, tokenizedRestriction, is_any_of("], "));
-            for (auto it1 = restriction.begin(); it1 != restriction.end();)
-              if (it1->empty())
-                restriction.erase(it1);
-              else
-                ++it1;
-
-            if (restriction.size() != 3)
-              {
-                cerr << "ERROR: restrictions in the subsample statement must be specified in the form "
-                     << "[current_period_regime, next_period_regime, transition_probability]" << endl;
-                exit(EXIT_FAILURE);
-              }
+      for (const vector<string> &restriction : it_num->second)
+        {
+          if (restriction.size() != 3)
+            {
+              cerr << "ERROR: restrictions in the subsample statement must be specified in the form "
+                   << "[current_period_regime, next_period_regime, transition_probability]" << endl;
+              exit(EXIT_FAILURE);
+            }
 
-            try
-              {
-                auto from_regime = stoi(restriction[0]);
-                auto to_regime = stoi(restriction[1]);
-                if (from_regime > num_regimes || to_regime > num_regimes)
-                  {
-                    cerr << "ERROR: the regimes specified in the restrictions option must be "
-                         << "<= the number of regimes specified in the number_of_regimes option" << endl;
-                    exit(EXIT_FAILURE);
-                  }
-
-                if (restriction_map.contains({ from_regime, to_regime }))
-                  {
-                    cerr << "ERROR: two restrictions were given for: " << from_regime << ", "
-                         << to_regime << endl;
-                    exit(EXIT_FAILURE);
-                  }
-
-                auto transition_probability = stod(restriction[2]);
-                if (transition_probability > 1.0)
-                  {
-                    cerr << "ERROR: the transition probability, " << transition_probability
-                         << " must be less than 1" << endl;
-                    exit(EXIT_FAILURE);
-                  }
-                restriction_map[{ from_regime, to_regime }] = transition_probability;
-              }
-            catch (const invalid_argument &)
-              {
-                cerr << "ERROR: The first two arguments for a restriction must be integers "
-                     << "specifying the regime and the last must be a double specifying the "
-                     << "transition probability. You wrote [" << tokenizedRestriction << endl;
-                exit(EXIT_FAILURE);
-              }
-          }
+          try
+            {
+              auto from_regime = stoi(restriction[0]);
+              auto to_regime = stoi(restriction[1]);
+              if (from_regime > num_regimes || to_regime > num_regimes)
+                {
+                  cerr << "ERROR: the regimes specified in the restrictions option must be "
+                       << "<= the number of regimes specified in the number_of_regimes option" << endl;
+                  exit(EXIT_FAILURE);
+                }
+
+              if (restriction_map.contains({ from_regime, to_regime }))
+                {
+                  cerr << "ERROR: two restrictions were given for: " << from_regime << ", "
+                       << to_regime << endl;
+                  exit(EXIT_FAILURE);
+                }
+
+              auto transition_probability = stod(restriction[2]);
+              if (transition_probability > 1.0)
+                {
+                  cerr << "ERROR: the transition probability, " << transition_probability
+                       << " must be less than 1" << endl;
+                  exit(EXIT_FAILURE);
+                }
+              restriction_map[{ from_regime, to_regime }] = transition_probability;
+            }
+          catch (const invalid_argument &)
+            {
+              cerr << "ERROR: The first two arguments for a restriction must be integers "
+                   << "specifying the regime and the last must be a floating point specifying the "
+                   << "transition probability.";
+              exit(EXIT_FAILURE);
+            }
+        }
     }
 }
 
@@ -3544,10 +3532,8 @@ MarkovSwitchingStatement::checkPass(ModFileStructure &mod_file_struct, WarningCo
       exit(EXIT_FAILURE);
     }
 
-  if (auto it_num = options_list.num_options.find("ms.restrictions");
-      it_num != options_list.num_options.end())
+  if (options_list.vector_of_vector_value_options.contains("ms.restrictions"))
     {
-      using namespace boost;
       auto it_num_regimes = options_list.num_options.find("ms.number_of_regimes");
       assert(it_num_regimes != options_list.num_options.end());
       auto num_regimes = stoi(it_num_regimes->second);
@@ -3613,21 +3599,32 @@ MarkovSwitchingStatement::checkPass(ModFileStructure &mod_file_struct, WarningCo
 void
 MarkovSwitchingStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
 {
-  bool isDurationAVec = true;
-  string infStr("Inf");
-  OptionsList::num_options_t::const_iterator itChain, itNOR, itDuration;
-  map<pair<int, int>, double >::const_iterator itR;
-
-  itChain = options_list.num_options.find("ms.chain");
+  auto itChain = options_list.num_options.find("ms.chain");
   assert(itChain != options_list.num_options.end());
 
-  itDuration = options_list.num_options.find("ms.duration");
-  assert(itDuration != options_list.num_options.end());
-  if (stod(itDuration->second) || infStr.compare(itDuration->second) == 0)
-    isDurationAVec = false;
-  output << "options_.ms.duration = " << itDuration->second << ";" << endl;
+  assert(options_list.num_options.contains("ms.duration")
+         || options_list.vector_value_options.contains("ms.duration"));
 
-  itNOR = options_list.num_options.find("ms.number_of_regimes");
+  bool isDurationAVec = options_list.vector_value_options.contains("ms.duration");
+
+  output << "options_.ms.duration = ";
+  if (isDurationAVec)
+    {
+      output << "[";
+      auto &v = options_list.vector_value_options.at("ms.duration");
+      for (auto it = v.begin(); it != v.end(); ++it)
+        {
+          if (it != v.begin())
+            output << ", ";
+          output << *it;
+        }
+      output << "]";
+    }
+  else
+    output << options_list.num_options.at("ms.duration");
+  output << ";" << endl;
+
+  auto itNOR = options_list.num_options.find("ms.number_of_regimes");
   assert(itNOR != options_list.num_options.end());
   for (int i = 0; i < stoi(itNOR->second); i++)
     {
@@ -3639,7 +3636,7 @@ MarkovSwitchingStatement::writeOutput(ostream &output, const string &basename, b
     }
 
   int restrictions_index = 0;
-  for (itR = restriction_map.begin(); itR != restriction_map.end(); itR++)
+  for (auto itR = restriction_map.begin(); itR != restriction_map.end(); itR++)
     output << "options_.ms.ms_chain(" << itChain->second << ").restrictions("
            << ++restrictions_index << ") = {[" << itR->first.first << ", "
            << itR->first.second << ", " << itR->second << "]};" << endl;
@@ -4034,21 +4031,19 @@ JointPriorStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsoli
     }
 
   if (!options_list.num_options.contains("mean")
+      && !options_list.vector_value_options.contains("mean")
       && !options_list.num_options.contains("mode"))
     {
       cerr << "ERROR: You must pass at least one of mean and mode to the prior statement." << endl;
       exit(EXIT_FAILURE);
     }
 
-  if (auto it_num = options_list.num_options.find("domain");
-      it_num != options_list.num_options.end())
+  if (auto it = options_list.vector_value_options.find("domain");
+      it != options_list.vector_value_options.end())
     {
-      using namespace boost;
-      vector<string> tokenizedDomain;
-      split(tokenizedDomain, it_num->second, is_any_of("[ ]"), token_compress_on);
-      if (tokenizedDomain.size() != 4)
+      if (it->second.size() != 4)
         {
-          cerr << "ERROR: You must pass exactly two values to the domain option." << endl;
+          cerr << "ERROR: You must pass exactly four values to the domain option." << endl;
           exit(EXIT_FAILURE);
         }
     }
@@ -4103,15 +4098,38 @@ void
 JointPriorStatement::writeOutputHelper(ostream &output, const string &field, const string &lhs_field) const
 {
   output << lhs_field << "." << field << " = {";
-  if (field == "variance")
-    output << "{";
-  if (auto itn = options_list.num_options.find(field);
-      itn != options_list.num_options.end())
-    output << itn->second;
-  else
-    output << "{}";
-  if (field == "variance")
-    output << "}";
+  if (auto it = options_list.num_options.find(field);
+      it != options_list.num_options.end())
+    output << it->second;
+  else if (auto it = options_list.vector_value_options.find(field);
+           it != options_list.vector_value_options.end())
+    {
+      output << "[";
+      for (auto it2 = it->second.begin(); it2 != it->second.end(); ++it2)
+        {
+          if (it2 != it->second.begin())
+            output << ", ";
+          output << *it2;
+        }
+      output << "]";
+    }
+  else if (auto it = options_list.vector_of_vector_value_options.find(field);
+           it != options_list.vector_of_vector_value_options.end())
+    {
+      for (auto it2 = it->second.begin(); it2 != it->second.end(); ++it2)
+        {
+          if (it2 != it->second.begin())
+            output << ", ";
+          output << "[";
+          for (auto it3 = it2->begin(); it3 != it2->end(); ++it3)
+            {
+              if (it3 != it2->begin())
+                output << ", ";
+              output << *it3;
+            }
+          output << "]";
+        }
+    }
   output << "};" << endl;
 }
 
@@ -4191,6 +4209,7 @@ BasicPriorStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsoli
     }
 
   if (!options_list.num_options.contains("mean")
+      && !options_list.vector_value_options.contains("mean")
       && !options_list.num_options.contains("mode"))
     {
       cerr << "ERROR: You must pass at least one of mean and mode to the prior statement." << endl;
diff --git a/src/DynareBison.yy b/src/DynareBison.yy
index 3ebfb6879624f67f011333a83e5ac9c251a1367a..69761e37cd68180317ac8d2c7953f25da04876ee 100644
--- a/src/DynareBison.yy
+++ b/src/DynareBison.yy
@@ -194,15 +194,15 @@ class ParsingDriver;
 %type <expr_t> equation hand_side
 %type <string> non_negative_number signed_number signed_integer date_str
 %type <string> filename symbol namespace_qualified_filename namespace_qualified_symbol
-%type <string> vec_of_vec_value vec_value_list date_expr
-%type <string> vec_value_1 vec_value signed_inf signed_number_w_inf
-%type <string> range vec_value_w_inf vec_value_1_w_inf
+%type <string> date_expr signed_inf signed_number_w_inf range
 %type <string> integer_range signed_integer_range boolean
 %type <string> name_value_pair name_value_pair_list
 %type <string> name_value_pair_with_boolean name_value_pair_with_boolean_list
 %type <string> name_value_pair_with_suboptions name_value_pair_with_suboptions_list
 %type <SymbolType> change_type_arg
 %type <vector<string>> vec_str vec_str_1
+%type <vector<string>> vec_value vec_value_1 vec_value_w_inf vec_value_w_inf_1
+%type <vector<vector<string>>> vec_of_vec_value vec_of_vec_value_1
 %type <vector<string>> symbol_list symbol_list_or_wildcard
 %type <vector<int>> vec_int_elem vec_int_1 vec_int vec_int_number
 %type <PriorDistributions> prior_pdf prior_distribution
@@ -3535,16 +3535,16 @@ o_shift : SHIFT EQUAL signed_number { driver.option_num("shift", $3); };
 o_shape : SHAPE EQUAL prior_distribution { driver.prior_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_mean_vec : MEAN EQUAL vec_value { driver.option_num("mean", $3); };
-o_truncate : TRUNCATE EQUAL vec_value { driver.option_num("truncate", $3); };
+o_mean_vec : MEAN EQUAL vec_value { driver.option_vec_value("mean", $3); };
+o_truncate : TRUNCATE EQUAL vec_value { driver.option_vec_value("truncate", $3); };
 o_stdev : STDEV EQUAL non_negative_number { driver.option_num("stdev", $3); };
 o_jscale : JSCALE EQUAL non_negative_number { driver.option_num("jscale", $3); };
 o_init : INIT EQUAL signed_number { driver.option_num("init", $3); };
-o_bounds : BOUNDS EQUAL vec_value_w_inf { driver.option_num("bounds", $3); };
-o_domain : DOMAINN EQUAL vec_value { driver.option_num("domain", $3); };
-o_interval : INTERVAL EQUAL vec_value { driver.option_num("interval", $3); };
+o_bounds : BOUNDS EQUAL vec_value_w_inf { driver.option_vec_value("bounds", $3); };
+o_domain : DOMAINN EQUAL vec_value { driver.option_vec_value("domain", $3); };
+o_interval : INTERVAL EQUAL vec_value { driver.option_vec_value("interval", $3); };
 o_variance : VARIANCE EQUAL expression { driver.set_prior_variance($3); }
-o_variance_mat : VARIANCE EQUAL vec_of_vec_value { driver.option_num("variance",$3); }
+o_variance_mat : VARIANCE EQUAL vec_of_vec_value { driver.option_vec_of_vec_value("variance",$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); };
@@ -3684,9 +3684,9 @@ o_xls_sheet : XLS_SHEET EQUAL symbol { driver.option_str("xls_sheet", $3); } //
 o_xls_range : XLS_RANGE EQUAL range { driver.option_str("xls_range", $3); };
 o_filter_step_ahead : FILTER_STEP_AHEAD EQUAL vec_int { driver.option_vec_int("filter_step_ahead", $3); };
 o_taper_steps : TAPER_STEPS EQUAL vec_int { driver.option_vec_int("convergence.geweke.taper_steps", $3); };
-o_geweke_interval : GEWEKE_INTERVAL EQUAL vec_value { driver.option_num("convergence.geweke.geweke_interval",$3); };
+o_geweke_interval : GEWEKE_INTERVAL EQUAL vec_value { driver.option_vec_value("convergence.geweke.geweke_interval",$3); };
 o_raftery_lewis_diagnostics : RAFTERY_LEWIS_DIAGNOSTICS { driver.option_num("convergence.rafterylewis.indicator", "true"); };
-o_raftery_lewis_qrs : RAFTERY_LEWIS_QRS EQUAL vec_value { driver.option_num("convergence.rafterylewis.qrs",$3); };
+o_raftery_lewis_qrs : RAFTERY_LEWIS_QRS EQUAL vec_value { driver.option_vec_value("convergence.rafterylewis.qrs",$3); };
 o_constant : CONSTANT { driver.option_num("noconstant", "false"); };
 o_noconstant : NOCONSTANT { driver.option_num("noconstant", "true"); };
 o_mh_recover : MH_RECOVER { driver.option_num("mh_recover", "true"); };
@@ -3796,7 +3796,7 @@ o_gsa_load_rmse : LOAD_RMSE EQUAL INT_NUMBER { driver.option_num("load_rmse", $3
 o_gsa_load_stab : LOAD_STAB EQUAL INT_NUMBER { driver.option_num("load_stab", $3); };
 o_gsa_alpha2_stab : ALPHA2_STAB EQUAL non_negative_number { driver.option_num("alpha2_stab", $3); };
 o_gsa_logtrans_redform : LOGTRANS_REDFORM EQUAL INT_NUMBER { driver.option_num("logtrans_redform", $3); };
-o_gsa_threshold_redform : THRESHOLD_REDFORM EQUAL vec_value_w_inf { driver.option_num("threshold_redform",$3); };
+o_gsa_threshold_redform : THRESHOLD_REDFORM EQUAL vec_value_w_inf { driver.option_vec_value("threshold_redform",$3); };
 o_gsa_ksstat_redform : KSSTAT_REDFORM EQUAL non_negative_number { driver.option_num("ksstat_redform", $3); };
 o_gsa_alpha2_redform : ALPHA2_REDFORM EQUAL non_negative_number { driver.option_num("alpha2_redform", $3); };
 o_gsa_namendo : NAMENDO EQUAL '(' symbol_list_or_wildcard ')' { driver.option_symbol_list("namendo", $4); };
@@ -3923,12 +3923,12 @@ o_k_order_solver : K_ORDER_SOLVER {driver.option_num("k_order_solver","true"); }
 o_pruning : PRUNING { driver.option_num("pruning", "true"); };
 o_chain : CHAIN EQUAL INT_NUMBER { driver.option_num("ms.chain",$3); };
 o_restrictions : RESTRICTIONS EQUAL vec_of_vec_value
-                 { driver.option_num("ms.restrictions",$3); }
+                 { driver.option_vec_of_vec_value("ms.restrictions",$3); }
                ;
 o_duration : DURATION EQUAL non_negative_number
              { driver.option_num("ms.duration",$3); }
            | DURATION EQUAL vec_value_w_inf
-             { driver.option_num("ms.duration",$3); }
+             { driver.option_vec_value("ms.duration",$3); }
            ;
 o_number_of_regimes : NUMBER_OF_REGIMES EQUAL INT_NUMBER { driver.option_num("ms.number_of_regimes",$3); };
 o_number_of_lags : NUMBER_OF_LAGS EQUAL INT_NUMBER { driver.option_num("ms.number_of_lags",$3); };
@@ -3981,7 +3981,7 @@ o_file_tag : FILE_TAG EQUAL filename { driver.option_str("ms.file_tag", $3); };
 o_no_create_init : NO_CREATE_INIT { driver.option_num("ms.create_init", "false"); };
 o_simulation_file_tag : SIMULATION_FILE_TAG EQUAL filename { driver.option_str("ms.simulation_file_tag", $3); };
 o_coefficients_prior_hyperparameters : COEFFICIENTS_PRIOR_HYPERPARAMETERS EQUAL vec_value
-                                       { driver.option_num("ms.coefficients_prior_hyperparameters",$3); };
+                                       { driver.option_vec_value("ms.coefficients_prior_hyperparameters",$3); };
 o_convergence_starting_value : CONVERGENCE_STARTING_VALUE EQUAL non_negative_number
                                { driver.option_num("ms.convergence_starting_value",$3); };
 o_convergence_ending_value : CONVERGENCE_ENDING_VALUE EQUAL non_negative_number
@@ -4025,10 +4025,10 @@ o_horizon : HORIZON EQUAL INT_NUMBER { driver.option_num("ms.horizon",$3); };
 o_filtered_probabilities : FILTERED_PROBABILITIES { driver.option_num("ms.filtered_probabilities","true"); };
 o_real_time_smoothed : REAL_TIME_SMOOTHED { driver.option_num("ms.real_time_smoothed_probabilities","true"); };
 o_no_error_bands : NO_ERROR_BANDS { driver.option_num("ms.error_bands","false"); };
-o_error_band_percentiles : ERROR_BAND_PERCENTILES EQUAL vec_value { driver.option_num("ms.percentiles",$3); };
+o_error_band_percentiles : ERROR_BAND_PERCENTILES EQUAL vec_value { driver.option_vec_value("ms.percentiles",$3); };
 o_shock_draws : SHOCK_DRAWS EQUAL INT_NUMBER { driver.option_num("ms.shock_draws",$3); };
 o_shocks_per_parameter : SHOCKS_PER_PARAMETER EQUAL INT_NUMBER { driver.option_num("ms.shocks_per_parameter",$3); };
-o_free_parameters : FREE_PARAMETERS EQUAL vec_value { driver.option_num("ms.free_parameters",$3); };
+o_free_parameters : FREE_PARAMETERS EQUAL vec_value { driver.option_vec_value("ms.free_parameters",$3); };
 o_median : MEDIAN { driver.option_num("ms.median","1"); }
          | MEDIAN EQUAL signed_number { driver.option_num("median", $3); };
 o_regimes : REGIMES { driver.option_num("ms.regimes","true"); };
@@ -4240,39 +4240,55 @@ vec_str : vec_str_1 ']'
         ;
 
 vec_value_1 : '[' signed_number
-              { $$ = '[' + $2; }
+              { $$ = { $2 }; }
             | '[' COMMA signed_number
-              { $$ = '[' + $3; }
+              { $$ = { $3 }; }
             | vec_value_1 signed_number
-              { $$ = $1 + ' ' + $2; }
+              {
+                $$ = $1;
+                $$.push_back($2);
+              }
             | vec_value_1 COMMA signed_number
-              { $$ = $1 + ' ' + $3; }
+              {
+                $$ = $1;
+                $$.push_back($3);
+              }
             ;
 
 vec_value : vec_value_1 ']'
-             { $$ = $1 + ']'; }
           | vec_value_1 COMMA ']'
-             { $$ = $1 + ']'; }
           ;
 
-vec_value_list : vec_value_list COMMA vec_value
-                 { $$ = $1 + ',' + $3; }
-               | vec_value
-               ;
+vec_value_w_inf_1 : signed_number_w_inf
+                    { $$ = { $1 }; }
+                  | vec_value_w_inf_1 signed_number_w_inf
+                    {
+                      $$ = $1;
+                      $$.push_back($2);
+                    }
+                  | vec_value_w_inf_1 COMMA signed_number_w_inf
+                    {
+                      $$ = $1;
+                      $$.push_back($3);
+                    }
+                  ;
 
-vec_of_vec_value : '[' vec_value_list ']'
-                   { $$ = $2; }
-                 | vec_value
-                 ;
+vec_value_w_inf : '[' vec_value_w_inf_1 ']'
+                  { $$ = $2; }
+                ;
 
-vec_value_1_w_inf : '[' signed_number_w_inf
-                    { $$ = '[' + $2; }
-                  | vec_value_1_w_inf signed_number_w_inf
-                    { $$ = $1 + ' ' + $2; }
-                  ;
+vec_of_vec_value_1 : vec_of_vec_value_1 COMMA vec_value
+                     {
+                       $$ = $1;
+                       $$.push_back($3);
+                     }
+                   | vec_value
+                     { $$ = { $1 }; }
+                   ;
 
-vec_value_w_inf : vec_value_1_w_inf ']'
-                  { $$ = $1 + ']'; };
+vec_of_vec_value : '[' vec_of_vec_value_1 ']'
+                   { $$ = $2; }
+                 ;
 
 symbol : NAME
        | ALPHA
diff --git a/src/ParsingDriver.cc b/src/ParsingDriver.cc
index 4a10761423d2d109287c022d6b54e57637501acb..c576e9ab05e98278ef77e1729a07fb33d064192e 100644
--- a/src/ParsingDriver.cc
+++ b/src/ParsingDriver.cc
@@ -1471,6 +1471,30 @@ ParsingDriver::option_vec_cellstr(string name_option, vector<string> opt)
   options_list.vector_cellstr_options[move(name_option)] = move(opt);
 }
 
+void
+ParsingDriver::option_vec_value(string name_option, vector<string> opt)
+{
+  if (options_list.vector_value_options.contains(name_option))
+    error("option " + name_option + " declared twice");
+
+  if (opt.empty())
+    error("option " + name_option + " was passed an empty vector.");
+
+  options_list.vector_value_options[move(name_option)] = move(opt);
+}
+
+void
+ParsingDriver::option_vec_of_vec_value(string name_option, vector<vector<string>> opt)
+{
+  if (options_list.vector_of_vector_value_options.contains(name_option))
+    error("option " + name_option + " declared twice");
+
+  if (opt.empty())
+    error("option " + name_option + " was passed an empty vector.");
+
+  options_list.vector_of_vector_value_options[move(name_option)] = move(opt);
+}
+
 void
 ParsingDriver::linear()
 {
diff --git a/src/ParsingDriver.hh b/src/ParsingDriver.hh
index 2284720d5354334eb43a9f750256e7c1d6ec9cc9..c17d7eed892cc27d94f077435a04414a36cc324d 100644
--- a/src/ParsingDriver.hh
+++ b/src/ParsingDriver.hh
@@ -512,6 +512,10 @@ public:
   void option_vec_str(string name_option, vector<string> opt);
   //! Sets an option to a celll array of strings
   void option_vec_cellstr(string name_option, vector<string> opt);
+  //! Sets an option to a vector of (numerical) values
+  void option_vec_value(string name_option, vector<string> opt);
+  //! Sets an option to a vector of vectors of (numerical) values
+  void option_vec_of_vec_value(string name_option, vector<vector<string>> opt);
   //! Indicates that the model is linear
   void linear();
   //! Writes a rplot() command
diff --git a/src/Statement.cc b/src/Statement.cc
index 1631283629ec45a17201520af42905873710f3a9..ba574eb8213de816c955712b96503b775f6cc7fa 100644
--- a/src/Statement.cc
+++ b/src/Statement.cc
@@ -238,6 +238,30 @@ OptionsList::writeOutputCommon(ostream &output, const string &option_group) cons
         output << "'" << viit << "';";
       output << "};" << endl;
     }
+
+  /* For historical reason, those vectors are output as row vectors (contrary
+     to vectors of integers which are output as column vectors) */
+  for (const auto &[name, vals] : vector_value_options)
+    {
+      output << option_group << "." << name << " = [";
+      for (const auto &viit : vals)
+        output << viit << ",";
+      output << "];" << endl;
+    }
+
+  // Same remark as for vectors of (floating point) values
+  for (const auto &[name, vec_vals] : vector_of_vector_value_options)
+    {
+      output << option_group << "." << name << " = {";
+      for (const auto &vals : vec_vals)
+        {
+          output << "[";
+          for (const auto &viit : vals)
+            output << viit << ",";
+          output << "], ";
+        }
+      output << "};" << endl;
+    }
 }
 
 void
@@ -336,6 +360,43 @@ OptionsList::writeJsonOutput(ostream &output) const
       opt_written = true;
     }
 
+  for (const auto &[name, vals] : vector_value_options)
+    {
+      if (opt_written)
+        output << ", ";
+      output << R"(")" << name << R"(": [)";
+      for (auto it = vals.begin(); it != vals.end(); ++it)
+        {
+          if (it != vals.begin())
+            output << ", ";
+          output << *it;
+        }
+      output << "]";
+      opt_written = true;
+    }
+
+  for (const auto &[name, vec_vals] : vector_of_vector_value_options)
+    {
+      if (opt_written)
+        output << ", ";
+      output << R"(")" << name << R"(": [)";
+      for (auto it = vec_vals.begin(); it != vec_vals.end(); ++it)
+        {
+          if (it != vec_vals.begin())
+            output << ", ";
+          output << "[";
+          for (auto it2 = it->begin(); it2 != it->end(); ++it2)
+            {
+              if (it2 != it->begin())
+                output << ", ";
+              output << *it2;
+            }
+          output << "]";
+        }
+      output << "]";
+      opt_written = true;
+    }
+
   output << "}";
 }
 
@@ -350,6 +411,8 @@ OptionsList::clear()
   vector_int_options.clear();
   vector_str_options.clear();
   vector_cellstr_options.clear();
+  vector_value_options.clear();
+  vector_of_vector_value_options.clear();
 }
 
 int
@@ -362,5 +425,7 @@ OptionsList::getNumberOfOptions() const
     + symbol_list_options.size()
     + vector_int_options.size()
     + vector_str_options.size()
-    + vector_cellstr_options.size();
+    + vector_cellstr_options.size()
+    + vector_value_options.size()
+    + vector_of_vector_value_options.size();
 }
diff --git a/src/Statement.hh b/src/Statement.hh
index 16f04fcce8ece6440abc948cd66a47ac75cde662..4b800123e29f54a158b7dc51224bff9e1637ebe8 100644
--- a/src/Statement.hh
+++ b/src/Statement.hh
@@ -215,6 +215,8 @@ public:
   using vec_int_options_t = map<string, vector<int>>;
   using vec_str_options_t = map<string, vector<string >>;
   using vec_cellstr_options_t = map<string, vector<string >>;
+  using vec_value_options_t = map<string, vector<string>>;
+  using vec_of_vec_value_options_t = map<string, vector<vector<string>>>;
   num_options_t num_options;
   paired_num_options_t paired_num_options;
   string_options_t string_options;
@@ -223,6 +225,8 @@ public:
   vec_int_options_t vector_int_options;
   vec_str_options_t vector_str_options;
   vec_cellstr_options_t vector_cellstr_options;
+  vec_value_options_t vector_value_options;
+  vec_of_vec_value_options_t vector_of_vector_value_options;
   int getNumberOfOptions() const;
   void writeOutput(ostream &output) const;
   void writeOutput(ostream &output, const string &option_group) const;