簡體   English   中英

Boost.Spirit.Qi替代(|)解析器問題

[英]Boost.Spirit.Qi alternative ( | ) parser issue

我正在編寫一個Qi解析器來解析IRC消息,並記錄RFC 2812 在語法中有一個完全替代的替代:

auto const hostname = shortname >> *('.' >> shortname);
auto const nickUserHost = nickname >> -(-('!' >> user) >> '@' >> host);

auto const prefix = hostname | nickUserHost;

此處為Coliru的完整代碼

我迷惑地看到,我的測試字符串( "Dz!Dz@mib-A3A026FF.rev.sfr.net" )相匹配nickUserHost ,而不是prefix

我看到的唯一值得注意的事情是nickUserHosthost本身是根據hostname定義的,但是我不確定它會以何種方式影響解析。

通過附加>> eoi可以使解析未達到輸入末尾時顯式失敗。

生活在Coliru

#include <string>
#include <iostream>
#include <iomanip>

#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;

template <typename Expr>
void test(std::string name, Expr const& expr) {
    std::string const test = "D-z!D-z@mib-A3A026FF.rev.sfr.net";

    auto f = begin(test);
    bool ok = qi::parse(f, end(test), expr);
    std::cout << name << ": " << ok << "\n";
    if (f != end(test))
        std::cout << " -- remaining input: '" << std::string(f, end(test)) << "'\n";
}

int main() {
    auto const hexdigit = qi::char_("0123456789ABCDEF");
    auto const special = qi::char_("\x5b-\x60\x7b-\x7d");

    auto const oneToThreeDigits = qi::repeat(1, 3)[qi::digit];
    auto const ip4addr = oneToThreeDigits >> '.' >> oneToThreeDigits >> '.' >> oneToThreeDigits >> '.' >> oneToThreeDigits;
    auto const ip6addr = +(hexdigit >> qi::repeat(7)[':' >> +hexdigit]) | ("0:0:0:0:0:" >> (qi::lit('0') | "FFFF") >> ':' >> ip4addr);
    auto const hostaddr = ip4addr | ip6addr;

    auto const nickname = (qi::alpha | special) >> qi::repeat(0, 8)[qi::alnum | special | '-'];
    auto const user = +(~qi::char_("\x0d\x0a\x20\x40"));

    auto const shortname = qi::alnum >> *(qi::alnum | '-');
    auto const hostname = shortname >> *('.' >> shortname);
    auto const host = hostname | hostaddr;

    auto const nickUserHost = nickname >> -(-('!' >> user) >> '@' >> host);

    auto const prefix = hostname | nickUserHost; // The problematic alternative

    std::cout << std::boolalpha;
    test("hostname",     hostname);
    test("nickUserHost", nickUserHost);
    test("prefix",       prefix);
}

打印

hostname: true
-- remaining input: '!D-z@mib-A3A026FF.rev.sfr.net'
nickUserHost: true
prefix: true
-- remaining input: '!D-z@mib-A3A026FF.rev.sfr.net'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM