我有以下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)
)
正如你所看到的,我试图解析一对或多对浮点数,然后是两个整数,然后是文字“BBNSET”。 所有这些代码都会编译,但是当我尝试解析格式的有效BBNSET命令时:
0.0 80.0 50.0 25.0 100.0 10.0 3 0 BBNSET
解析失败。我无法确定原因。我试图在lexeme指令中包装float对,并将+更改为a *,但无论我尝试了什么,该命令仍然无法解析,尽管编译没有问题。
我做错了什么,一旦正确解析,此规则会按预期发出属性吗?
答案 0 :(得分:3)
我怀疑你的问题实际上与Recursive Descent Parsers有关。
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_.
答案 1 :(得分:3)
Sharth很快就注意到了原因。
解决方案,IMO将使用strict_real_policies
#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";
}