提振精神 期待失败
我想解析以下结构的向量:
BOOST_FUSION_ADAPT_STRUCT(
event_model::OTNDescriptor,
(int32_t, qualifier)
(int32_t, ordinal)
(std::string, name)
(int32_t, type)
)
我的语法如下所示:
struct swat_types_ : qi::symbols<char, unsigned>
{
swat_types_()
{
using namespace event_model;
add
("int", SWAT_INT4)
("int4", SWAT_INT4)
("int8", SWAT_INT8)
("bigint", SWAT_INT8)
("string", SWAT_STRING)
;
}
} swat_types;
template<typename Iterator>
struct Rules
{
qi::rule<Iterator, event_model::OTNDescriptor(), ascii::space_type>
data_member_line;
qi::rule<Iterator, std::string()> data_name;
qi::rule<Iterator, void(int&, std::string&)> data_identifier_pair;
qi::rule< Iterator,
std::vector< event_model::OTNDescriptor>(),
ascii::space_type> dm_lines;
Rules() {
data_name =
+ (char_("a","z") | char_("A","Z") | char_('_'));
data_identifier_pair =
lexeme[int_ [ _r1 = _1] > ':' > data_name [ _r2 = _1]];
data_member_line =
eps [ at_c<0>(_val) = event_model::OTN_REQUIRED ]
>> -( no_case[lit("optional")]
[at_c<0>(_val) = event_model::OTN_OPTIONAL]
| no_case[lit("required")]
[at_c<0>(_val) = event_model::OTN_REQUIRED])
> data_identifier_pair( at_c<1>(_val), at_c<2>(_val) )
> no_case[swat_types [at_c<3>(_val) = _1]]
> ';'
;
//dm_lines = data_member_line >> data_member_line;
dm_lines = data_member_line >> *(data_member_line);
}
};
我的 Harnass 如下所示:
std::string str4("REquireD 0:lala int4; REquireD 1:googoo int4; ");
std::string::const_iterator iter4=str4.begin();
std::string::const_iterator end4=str4.end();
std::vector<event_model::OTNDescriptor> res4;
r = phrase_parse(iter4, end4, rules.dm_lines, boost::spirit::ascii::space, res4);
for(std::vector<event_model::OTNDescriptor>::iterator it = res4.begin(); it < ires4.end(); it++)
{
std::cout << it->name << "\n";
}
如果我将规则规范从 kleene star 规范切换为序列匹配,则不会出现错误。
//dm_lines = data_member_line >> data_member_line;
dm_lines = data_member_line >> *(data_member_line);
否则,当我尝试解析我的例句时,我会收到期望错误(如 harnass 所示)。
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::spirit::qi::expectation_failure<__gnu_cxx::__normal_iterator<char const*, std::string> > > >'
what(): boost::spirit::qi::expectation_failure
Aborted
理想情况下,我想编写这样的规则 dm_lines = +(data_member_line)
(这也不起作用)。使用“*”和“+”运算符时,发生了什么导致期望失败?但在匹配序列时则不然?以及如何修复它。
I want to parse a vector of the following struct:
BOOST_FUSION_ADAPT_STRUCT(
event_model::OTNDescriptor,
(int32_t, qualifier)
(int32_t, ordinal)
(std::string, name)
(int32_t, type)
)
My grammer looks as follows:
struct swat_types_ : qi::symbols<char, unsigned>
{
swat_types_()
{
using namespace event_model;
add
("int", SWAT_INT4)
("int4", SWAT_INT4)
("int8", SWAT_INT8)
("bigint", SWAT_INT8)
("string", SWAT_STRING)
;
}
} swat_types;
template<typename Iterator>
struct Rules
{
qi::rule<Iterator, event_model::OTNDescriptor(), ascii::space_type>
data_member_line;
qi::rule<Iterator, std::string()> data_name;
qi::rule<Iterator, void(int&, std::string&)> data_identifier_pair;
qi::rule< Iterator,
std::vector< event_model::OTNDescriptor>(),
ascii::space_type> dm_lines;
Rules() {
data_name =
+ (char_("a","z") | char_("A","Z") | char_('_'));
data_identifier_pair =
lexeme[int_ [ _r1 = _1] > ':' > data_name [ _r2 = _1]];
data_member_line =
eps [ at_c<0>(_val) = event_model::OTN_REQUIRED ]
>> -( no_case[lit("optional")]
[at_c<0>(_val) = event_model::OTN_OPTIONAL]
| no_case[lit("required")]
[at_c<0>(_val) = event_model::OTN_REQUIRED])
> data_identifier_pair( at_c<1>(_val), at_c<2>(_val) )
> no_case[swat_types [at_c<3>(_val) = _1]]
> ';'
;
//dm_lines = data_member_line >> data_member_line;
dm_lines = data_member_line >> *(data_member_line);
}
};
My Harnass looks like this:
std::string str4("REquireD 0:lala int4; REquireD 1:googoo int4; ");
std::string::const_iterator iter4=str4.begin();
std::string::const_iterator end4=str4.end();
std::vector<event_model::OTNDescriptor> res4;
r = phrase_parse(iter4, end4, rules.dm_lines, boost::spirit::ascii::space, res4);
for(std::vector<event_model::OTNDescriptor>::iterator it = res4.begin(); it < ires4.end(); it++)
{
std::cout << it->name << "\n";
}
If I switch the rule specification from a kleene star specification to a sequence match no errors.
//dm_lines = data_member_line >> data_member_line;
dm_lines = data_member_line >> *(data_member_line);
otherwise I get an expectation error when trying to parse my example sentence (shown in harnass).
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::spirit::qi::expectation_failure<__gnu_cxx::__normal_iterator<char const*, std::string> > > >'
what(): boost::spirit::qi::expectation_failure
Aborted
Ideally I want to write the rule like this dm_lines = +(data_member_line)
(this doesn't work either). What is going on that causes the expectation failure when using '*' and '+' operators ? but NOT when matching a sequence ?. And how do I fix it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
预期失败的原因是,一旦您开始使用 plus 或 Kleene,嵌入式解析器 (
data_member_line
) 将被多次调用。它的最后一次调用自然会失败,因为没有更多的输入可用。在您的情况下,此事件将在第一个期望点之前被“识别”,因为之前的所有组件都是可选的(它们永远不会失败)。The reason for the expectation failure is that as soon as you start using plus or Kleene, the embedded parser (
data_member_line
) will be invoked more than once. Its last invocation will naturally fail as no more input is available. In your case this event will be 'recognized' as late as by the first expectation point only as all components before that are optional (they never fail).