簡體   English   中英

為什么boost :: spirit :: qi規則不能成功解析?

[英]Why doesn't this boost::spirit::qi rule successfully parse?

我有以下boost :: spirit :: qi解析器規則:

namespace qi = boost::spirit::qi;
qi::rule<Iterator, BroadbandCurve(), Skipper> Cmd_BBNSET;


Cmd_BBNSET = +(qi::float_ >> qi::float_) >> qi::int_ >> qi::int_ >> lit("BBNSET");

我正在嘗試使其發出以下屬性:

struct FreqLevelPair
{
    float freq;
    float dbLevel;
};
BOOST_FUSION_ADAPT_STRUCT(
    FreqLevelPair,
    (float, freq)
    (float, dbLevel)
)

struct BroadbandCurve
{
    std::vector<FreqLevelPair> freqPairs;
    int numFreqPairs; //Ignored since we can just count the number of pairs outright...
    int curveNum; //ID number
};
BOOST_FUSION_ADAPT_STRUCT(
    BroadbandCurve,
    (std::vector<FreqLevelPair>, freqPairs)
    (int, numFreqPairs)
    (int, curveNum)
)

如您所見,我嘗試解析一對或多對浮點數,然后解析兩個int,然后解析文字“ BBNSET”。 所有這些代碼都可以編譯,但是當我嘗試解析以下形式的有效BBNSET命令時:

0.0 80.0 50.0 25.0 100.0 10.0 3 0 BBNSET

解析失敗。 我無法確定原因。 我嘗試將浮點對包裝在lexeme指令中,並將+更改為*,但是無論我嘗試如何,盡管編譯沒有問題,該命令仍然無法解析。

我在做什么錯,一旦正確解析,此規則會發出預期的屬性嗎?

我懷疑您的問題實際上與遞歸下降解析器有關。

Cmd_BBNSET = +(qi::float_ >> qi::float_) >> qi::int_ >> qi::int_ >> lit("BBNSET");

讓我們來看看這個:

0.0 80.0 50.0 25.0 100.0 10.0 3 0 BBNSET
^
Matches +(qi::float_ >> qi::float_)

0.0 80.0 50.0 25.0 100.0 10.0 3 0 BBNSET
         ^
         Matches +(qi::float_ >> qi::float_)

0.0 80.0 50.0 25.0 100.0 10.0 3 0 BBNSET
                   ^
                   Matches +(qi::float_ >> qi::float_)

0.0 80.0 50.0 25.0 100.0 10.0 3 0 BBNSET
                              ^
                          !!! Matches +(qi::float_ >> qi::float_) !!!

0.0 80.0 50.0 25.0 100.0 10.0 3 0 BBNSET
                                  ^
                                  Does not match qi::int_.

Sharth很快就注意到了原因。

IMO的解決方案是使用strict_real_policies

在Coliru上實時觀看

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

namespace qi = boost::spirit::qi;

struct FreqLevelPair
{
    float freq;
    float dbLevel;
};

BOOST_FUSION_ADAPT_STRUCT(
    FreqLevelPair,
    (float, freq)
    (float, dbLevel)
)

struct BroadbandCurve
{
    std::vector<FreqLevelPair> freqPairs;
    int numFreqPairs; //Ignored since we can just count the number of pairs outright...
    int curveNum; //ID number
};

BOOST_FUSION_ADAPT_STRUCT(
    BroadbandCurve,
    (std::vector<FreqLevelPair>, freqPairs)
    (int, numFreqPairs)
    (int, curveNum)
)

int main()
{
    typedef std::string::const_iterator Iterator;
    typedef qi::space_type Skipper;

    qi::real_parser<double, qi::strict_real_policies<double> > strict_real_;

    qi::rule<Iterator, BroadbandCurve(), Skipper> Cmd_BBNSET;
    Cmd_BBNSET = +(strict_real_ >> strict_real_) >> qi::int_ >> qi::int_ >> qi::lit("BBNSET");

    std::string const input("0.0 80.0 50.0 25.0 100.0 10.0 3 0 BBNSET");
    auto f(input.begin()), l(input.end());
    bool ok = qi::phrase_parse(f, l, Cmd_BBNSET, qi::space);

    if (ok)
    {
        std::cout << "Parse succeeded\n";
    } else
    {
        std::cout << "Parse failed\n";
    }

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

暫無
暫無

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

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