解析器不会失败,船长不会跳过

parser doesn't fail, skipper doesn't skip

我的语法有问题。我不确定为什么 date 被解析以及为什么我不需要 lexeme 解析器。

完整示例

Live On Coliru

#define BOOST_SPIRIT_X3_DEBUG

#include <iostream>
#include <string>
#include <boost/spirit/home/x3.hpp>

namespace x3 = boost::spirit::x3;

namespace grammar
{
    using namespace x3;                                                                                                                                                                                                      

    auto const term_  = rule<struct term_>{"term"}                                                            
                      =  lexeme[ (lit("ppl_") | lit("type ") | lit("group ")) >> int_ ];                      
    auto const entry_ = rule<struct entry_>{"entry"}                                                          
                      =  +(term_ | float_);                                                                   
    auto const start_ = rule<struct start_>{"start"}                                                          
                      = (term_ >> entry_) % eol;        
}


int main(int argc, const char * argv[])
{
    std::string s{"ppl_1,group 2,type 1,2016-01-02"};

    auto beg = std::begin(s);
    auto end = std::end(s);

    auto ret = x3::phrase_parse(beg, end, grammar::start_, x3::char_(','));

    if(ret && beg == end)
        std::cout << "all done\n";
    else
        std::cout << "Unparsed part's : '" << std::string(beg, std::next(beg, 10)) << "'\n";

    return 0;
}

输出:

<start>
  <try>ppl_1,group 2,type 1</try>
  <term>
    <try>ppl_1,group 2,type 1</try>
    <success>,group 2,type 1,2016</success>
  </term>
  <entry>
    <try>,group 2,type 1,2016</try>
    <term>
      <try>,group 2,type 1,2016</try>
      <success>,type 1,2016-01-02</success>
    </term>
    <term>
      <try>,type 1,2016-01-02</try>
      <success>,2016-01-02</success>
    </term>
    <term>
      <try>,2016-01-02</try>
      <fail/>
    </term>
    <term>
      <try>-01-02</try>
      <fail/>
    </term>
    <term>
      <try>-02</try>
      <fail/>
    </term>
    <term>
      <try></try>
      <fail/>
    </term>
    <success></success>
  </entry>
  <success></success>
</start>
all done

没有词素解析器:

将规则 term_ 更改为:

 auto const term_  = rule<struct term_>{"term"}                                                            
                   =  (lit("ppl_") | lit("type ") | lit("group ")) >> int_ ;  

我以为船长会在 lit() 之后尝试跳过?

<start>
  <try>ppl_1,group 2,type 1</try>
  <term>
    <try>ppl_1,group 2,type 1</try>
    <success>,group 2,type 1,2016</success>
  </term>
  <entry>
    <try>,group 2,type 1,2016</try>
    <term>
      <try>,group 2,type 1,2016</try>
      <success>,type 1,2016-01-02</success>
    </term>
    <term>
      <try>,type 1,2016-01-02</try>
      <success>,2016-01-02</success>
    </term>
    <term>
      <try>,2016-01-02</try>
      <fail/>
    </term>
    <term>
      <try>-01-02</try>
      <fail/>
    </term>
    <term>
      <try>-02</try>
      <fail/>
    </term>
    <term>
      <try></try>
      <fail/>
    </term>
    <success></success>
  </entry>
  <success></success>
</start>
all done

在回答了我的问题的 jv_ 的评论之后,这里是工作语法:

namespace grammar                                                                                             
  {                                                                                                             
      using namespace x3;                                                                                       

      auto const date_  = rule<struct date_>{"time"}                                                            
                        = int_ >> '-' >> int_ >> '-' >> int_;                                                   

      auto const term_  = rule<struct term_>{"term"}                                                            
                        =  (lit("ppl_") | lit("type ") | lit("group ")) >> int_;                                

      auto const entry_ = rule<struct entry_>{"entry"}                                                          
                        =  (term_ | date_ | float_) % ',';                                              

      auto const start_ = rule<struct start_>{"start"}                                                          
                        = (term_ >> ',' >> entry_) % eol;                                                       

  }           

和没有船长的解析器调用:

auto ret = x3::parse(beg, end, grammar::start_, peoples);