简体   繁体   English

Boost Spirit是不正确的解析

[英]Boost Spirit is incorrect parsing

I have a following code: 我有以下代码:

namespace qi = boost::spirit::qi;
std::string input("d:/std/prte/type.spr#12");
std::string::iterator strbegin = input.begin();
std::pair<std::string, int> p;
qi::parse(
    strbegin, 
    input.end(),
    *qi::char_ >> '#' >> qi::int_,       // parser grammar 
    p
);

I want to get ("d:/std/prte/type.spr", 12) , but I got ("d:/std/prte/type.spr#12", 0) . 我想得到("d:/std/prte/type.spr", 12) ,但我得到了("d:/std/prte/type.spr#12", 0) What is wrong? 怎么了?

Spirit does not do backoffs like regular expressions do. 精神不像正则表达式那样做退避。 *char_ will capture as many characters as possible, hence grabbing the entire string. *char_将捕获尽可能多的字符,因此抓取整个字符串。 If you check the return from parse, it should indicate that you failed to match because, after consuming d:/std/prte/type.spr#12 as *char_ , it could not find a # 如果你从parse检查返回,它应该表明你没有匹配,因为在使用d:/std/prte/type.spr#12作为*char_ ,它找不到#

The solution should be to change it to *(char_ - '#') >> # >> int_ 解决方案应该是将其更改为*(char_ - '#') >> # >> int_

You forgot to check the result of parsing: See it Live On Coliru clearly prints: 你忘了检查解析的结果:看到Live On Coliru清楚地打印:

Parse failed
Remaining unparsed: 'd:/std/prte/type.spr#12'

Here's the error handling code for future reference: 以下是错误处理代码以供将来参考:

#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;

int main()
{
    std::string input("d:/std/prte/type.spr#12");
    std::string::const_iterator iter = input.begin(), end = input.end();
    std::pair<std::string, int> p;
    bool ok = qi::parse(iter, end,
            *qi::char_ >> '#' >> qi::int_,       // parser grammar 
            p
        );

    if (ok)
        std::cout << "Parse success\n";
    else
        std::cout << "Parse failed\n";


    if (iter != end)
        std::cout << "Remaining unparsed: '" << std::string(iter,end) << "'\n";
}

Of course, you want non-greedy match until # : 当然,你需要非贪婪的比赛,直到#

        *(qi::char_ - '#') >> '#' >> qi::int_,       // parser grammar 

Also look at BOOST_SPIRIT_DEBUG_NODE to debug your rules: 另请查看BOOST_SPIRIT_DEBUG_NODE以调试规则:

qi::rule<It, std::string()> srule = *qi::char_;
qi::rule<It, int()> irule         = qi::int_;
BOOST_SPIRIT_DEBUG_NODES((srule)(irule))

It iter = input.begin(), end = input.end();
bool ok = qi::parse(iter, end,
        srule >> '#' >> irule,       // parser grammar 
        p
    );

Would print 会打印

<srule>
  <try>d:/std/prte/type.spr#12</try>
  <success></success>
  <attributes>[[d, :, /, s, t, d, /, p, r, t, e, /, t, y, p, e, ., s, p, r, #, 1, 2]]</attributes>
</srule>
Parse failed
Remaining unparsed: 'd:/std/prte/type.spr#12'

As you can see Live On Coliru as well 正如你可以看到Live On Coliru

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM