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
#include
#include
#include
#include
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
{
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);
}