将 Boost.Spirit Qi 解析器间接聚合到规则中会产生错误
aggregating Boost.Spirit Qi parsers into rule indirectly gives error
我有这个语法
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
;
我在这里违反了 Boost Spirit 的基本规则是什么?
为了不让问题得不到解答,我还将添加一些关于 post-解决方案条件的评论。
最好的解决方案是转移到 Spirit X3,它完全支持使用 auto
和 lambda,正如@sehe 所建议的。
我必须做出的一些重大改变:
symbols
现在只接受一个模板参数,即它映射的类型。
- X3没有语法,只有规则
- 我遵循的教程建议使用宏来定义规则。这在 MSVC 上是个坏主意,最好只使用构造后跟定义
示例:
auto r = rule<...> { "Name" }
= definition;
我有这个语法
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
;
我在这里违反了 Boost Spirit 的基本规则是什么?
为了不让问题得不到解答,我还将添加一些关于 post-解决方案条件的评论。
最好的解决方案是转移到 Spirit X3,它完全支持使用 auto
和 lambda,正如@sehe 所建议的。
我必须做出的一些重大改变:
symbols
现在只接受一个模板参数,即它映射的类型。- X3没有语法,只有规则
- 我遵循的教程建议使用宏来定义规则。这在 MSVC 上是个坏主意,最好只使用构造后跟定义
示例:
auto r = rule<...> { "Name" }
= definition;