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

时间:2016-08-14 08:06:18

标签: boost-spirit-x3

我的语法有问题。我不确定为什么解析 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

没有lexeme解析器:

将规则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

1 个答案:

答案 0 :(得分:1)

在回答我的问题的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);