解析器不会失败,船长不会跳过
parser doesn't fail, skipper doesn't skip
我的语法有问题。我不确定为什么 date 被解析以及为什么我不需要 lexeme 解析器。
完整示例
#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);
我的语法有问题。我不确定为什么 date 被解析以及为什么我不需要 lexeme 解析器。
完整示例
#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);