将Boost.Spirit Qi解析器聚合成规则间接给出错误

时间:2015-11-27 04:07:13

标签: c++ boost boost-spirit

我有这个语法

template<typename Iterator>
struct brainDSL : qi::grammar<Iterator, _problem(), ascii::space_type>
{
    brainDSL() : base_type(p_rule)
    {
        p_rule = problem_;
    }

    qi::rule<Iterator, _problem(), ascii::space_type> p_rule;
};

这些是解析器:

struct type_ : qi::symbols<char, _problem::_type>
{
    type_()
    {
        add
            ("single_stage", _problem::_type::single_stage)
            ("two_stage", _problem::_type::two_stage)
            ("multi_stage", _problem::_type::multi_stage)
        ;
    }
} type_;

struct command_ : qi::symbols<char, _problem::_command>
{
    command_()
    {
        add
            ("maximize", _problem::_command::maximize)
            ("minimize", _problem::_command::minimize)
        ;
    }
} command_;

auto name_ = qi::lexeme[*(qi::char_ - ':')];

auto problem_ =
    type_
    >> command_
    >> name_ >> ':'
;

我会添加结构和融合宏,但我不认为这是必要的。针对测试字符串执行此操作,此代码正确编译,但在boost中引发异常。

如果我删除name_解析器并离开problem_,请执行以下操作:

auto problem_ =
        type_
        >> command_
    ;

匹配正确。但是,如果我添加任何内容,即使qi::eps,我又会遇到异常:

auto problem_ =
        type_
        >> command_
        >> qi::eps
    ;

我在这里违反了提升精神的基本规则是什么?

1 个答案:

答案 0 :(得分:1)

为了不让问题得不到回答,我还会补充一些有关解决方案后条件的评论。

最好的解决方案是转移到Spirit X3,它完全支持auto和lambdas的使用,正如@sehe所建议的那样。

我必须做出的一些重大改变:

  • symbols现在只接受一个模板参数,即它映射的类型。
  • X3没有语法,只有规则
  • 我以下的教程建议使用宏来定义规则。这对于MSVC来说是个坏主意,最好只使用构造后跟定义

示例:

auto r = rule<...> { "Name" }
       = definition;