変更できないオブジェクトのツリー用のスピリットパーサーを作成したいと思います。コードを単純化するために、式の例を使用できます。
class Expr
{
public:
virtual ~Expr() = 0;
};
Expr::~Expr() {}
class Plus : public Expr
{
public:
Plus (Expr* e1, Expr* e2) : _e1(e1), _e2(e2) {}
~Plus () {}
private:
Expr* _e1;
Expr* _e2;
};
class Num : public Expr
{
public:
Num(double n) : _n(n) {}
private:
double _n;
};
ドキュメントを確認したところ、便利なBOOST_ADAPT_STRUCTが見つかりましたが、次のように宣言されたルールを使用しています。
qi::rule<Iterator, Expr()> r;
ルールがたとえばPlusオブジェクトを返すときに、オブジェクトをスライスします。だから私はこのように試します:
template <typename Iterator>
struct ExprParser : qi::grammar<Iterator, Expr*(), ascii::space_type>
{
ExprParser()
: ExprParser::base_type (start, "expr")
{
expr = qi::double_ [ qi::_val = phoenix::new_<Num>(::_1) ]
| '('
>> expr
>> '+'
>> expr
>> ')' [ qi::_val = phoenix::new_<Plus>(::_1, ::_2) ]
;
start %= expr;
}
qi::rule<Iterator, Expr*(), ascii::space_type> expr;
qi::rule<Iterator, Expr*(), ascii::space_type> start;
};
しかし、セマンティックアクション内の割り当てでコンパイルエラーが発生します。私は何が間違っているのですか?
編集
seheの答えは良いです!括弧の欠落とプレースホルダーの誤った使用があります。しかし、解析エラーが発生したときのメモリリークはどうでしょうか?