0

我想解析以下结构的载体:提振精神的预期失败

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明星规范切换到序列匹配没有错误。

//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)规则(这也不行)。使用'*'和'+'运算符会导致期望失败的原因是什么?但是在匹配一个序列时没有。我该如何解决它。

+0

我已经通过将data_member_line规则的data_identifier部分的期望点更改为序列运算符来解决该问题。现在它以我想要的方式工作。我仍然想要一个解释, – 2011-02-17 12:59:03

回答

3

期望失败的原因是,只要您开始使用plus或Kleene,嵌入式解析器(data_member_line)就会被多次调用。由于没有更多的输入可用,它的最后一次调用自然会失败。在你的情况下,这个事件将被认可为迟到第一个期望点,因为之前的所有组件都是可选的(它们从不失败)。

+0

非常感谢Haimut,(因为我的序列版本说匹配2,所以请重新说明答案以备将来参考)。鉴于一个kleene星和一个或多个运算符,尽可能地说匹配,并且因为解析器头向前移动以找到可选元素(在这种情况下不存在),并且我的期望点可防止回溯,需要回退才能成功退出。 – 2011-02-18 12:33:15