为什么这个提升::精神::qi规则没有成功解析?

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

本文关键字:成功 规则 qi 精神 为什么      更新时间:2023-10-16

我有以下提升::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

解析失败。我无法确定原因。我曾尝试将float对封装在lexeme指令中,并将+更改为*,但无论我尝试了什么,该命令仍然无法解析,尽管编译没有问题。

我做错了什么?一旦正确解析,这个规则会像预期的那样发出属性吗?

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 succeededn";
    } else
    {
        std::cout << "Parse failedn";
    }
    if (f!=l)
        std::cout << "Remaining unparsed: '" << std::string(f,l) << "'n";
}

我怀疑您的问题实际上与递归下降分析器有关。

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_.