Boost logo

Boost Users :

From: Anders Dalvander (boost_at_[hidden])
Date: 2007-08-13 12:51:30


Hi,

I'm trying to create a parser that shall create a number of derived
classes based on the input, put it in a shared_ptr<Base> and push_back
to a vector.

Example:

"Alpha" => vec.push_back(shared_ptr<Base>(new Alpha()))
"Beta[1]" => vec.push_back(shared_ptr<Base>(new Beta(1)))
"Gamma[2-3]" => vec.push_back(shared_ptr<Base>(new Gamma(2, 3)))
"Gamma[4-End]" => vec.push_back(shared_ptr<Base>(new Gamma(4)))

I've defined the actor as [push_back_a(self.vec, BasePtr(new Alpha()))],
but that obviously doesn't work as BasePtr(new Alpha()) creates a
temporary shared_ptr that will be destroyed by the end of the statement.
How can I delay the creation of the shared_ptr, and how can I delay the
new statement?

Using Boost 1.34.1, MSVC++ 2005.

Thanks,
Anders Dalvander

#include <vector>
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>

#include <boost/spirit.hpp>
#include <boost/spirit/actor/push_back_actor.hpp>
#include <boost/spirit/phoenix.hpp>

using namespace boost::spirit;
using namespace phoenix;

class Base
{
public:
  virtual ~Base() = 0 {}
};

typedef boost::shared_ptr<Base> BasePtr;

class Alpha : public Base
{
public:
  Alpha() {}
  virtual ~Alpha() {}
};

class Beta : public Base
{
public:
  explicit Beta(int var) : var(var) {}
  virtual ~Beta() {}

private:
  int var;
};

class Gamma : public Base
{
public:
  explicit Gamma(int var1) : var1(var1), var2() {}
  Gamma(int var1, int var2) : var1(var1), var2(var2) {}
  virtual ~Gamma() {}

private:
  int var1;
  boost::optional<int> var2;
};

struct my_grammar : grammar<my_grammar>
{
  template <typename ScannerT>
  struct definition
  {
     typedef rule<ScannerT> rule_t;

     explicit definition(const my_grammar& self)
     {
        my_rule
           = str_p("Alpha")[push_back_a(self.vec, BasePtr(new Alpha()))]
           | ("Beta[" >> int_p[var(var1) = arg1] >>
"]")[push_back_a(self.vec, BasePtr(new Beta(var1)))]
           | ("Gamma[" >> int_p[var(var1) = arg1] >> "-" >>
int_p[var(var2) = arg1] >> "]")[push_back_a(self.vec, BasePtr(new
Gamma(var1)))]
           | ("Gamma[" >> int_p[var(var1) = arg1] >>
"-End]")[push_back_a(self.vec, BasePtr(new Gamma(var1)))]
           ;
     }

     int var1;
     int var2;

     rule_t my_rule;

     const rule_t& start() const
     {
        return my_rule;
     }
  };

  my_grammar(std::vector<BasePtr>& vec)
   : vec(vec)
  {
  }

  std::vector<BasePtr>& vec;
};

int main()
{
  std::vector<BasePtr> vec;
  my_grammar g(vec);
  parse("Alpha", g);
  parse("Beta[1]", g);
  parse("Gamma[2-3]", g);
  parse("Gamma[4-End]", g);
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net