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