Roby
Roby

Reputation: 2061

parser doesn't fail, skipper doesn't skip

I have problem's with my grammar. I'm not sure why the date get parsed and why i doesn't need the lexeme parser.

Full Example

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;
}

Output:

<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

Without the lexeme parser:

changed the rule term_ to:

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

I thought the skipper would try to skip after the 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

Upvotes: 1

Views: 80

Answers (1)

Roby
Roby

Reputation: 2061

After the comment from jv_ who answered my question, here the working gramma:

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;                                                       

  }           

and the parser call without the skipper:

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

Upvotes: 1

Related Questions