以下是示例代码
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <iostream>
#include <string>
namespace qi = boost::spirit::qi;
template <typename Iterator>
struct input : qi::grammar<Iterator, unsigned()>
{
input() : input::base_type(start)
{
using qi::lit;
using qi::double_;
start = lit("ADD")
>> +(
+lit(" ")
>> double_
>> +lit(" ")
>> double_
);
}
qi::rule<Iterator, unsigned()> start;
};
int main()
{
input<std::string::const_iterator> input_parser; // Our grammar
std::string str = "ADD 1132.324 2342.234";
unsigned result;
std::string::const_iterator iter = str.begin();
std::string::const_iterator end = str.end();
bool r = qi::parse(iter, end, input_parser, result);
}
我收到以下错误。
/usr/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:201: 实例化 â€~boost ::精神::齐::规则和放大器; boost :: spirit :: qi :: rule :: operator =(const Expr&amp;) [与Expr = 提高::原:: exprns _ :: EXPR&安培;, 常量 升压::原:: exprns _ :: EXPR&安培;&gt;中 1l&gt;&amp;,const 升压::精神::终端&安培;&gt;中 2l&gt;&amp;,const 升压::原:: exprns _ :: EXPR&安培;&gt;中 1l&gt;&amp;&gt;,2&gt;&amp;,const 升压::精神::终端&安培;&gt;中 2l&gt;&amp;&gt;,1l&gt;&amp;&gt;,2l&gt;,Iterator = __gnu_cxx :: __ normal_iterator, std :: allocator&gt; &gt;,T1 = unsigned int()(),T2 = boost :: fusion :: unused_type,T3 = boost :: fusion :: unused_type,T4 = 提高::融合:: unused_type]答€™ mini.c ++:34:实例化 â€〜input :: input()[with 迭代器= __gnu_cxx :: __ normal_iterator, std :: allocator&gt; &GT;]’ mini.c ++:49:从这里实例化 /usr/local/include/boost/spirit/home/qi/operator/plus.hpp:62: 错误:没有名为“type”的类型 â€~struct 升压::精神::性状::container_valueâ€
奇怪的部分是,如果我使用减号( - )操作,即
start = lit("ADD")
>> -(
+lit(" ")
>> double_
>> +lit(" ")
>> double_
);
......编译得非常好!
在gcc 4.3.4上编译。
答案 0 :(得分:2)
启动规则公开的属性为unsigned
,而加解析器公开包含包装元素属性的容器类型。以下是docs:
a: A --> +a: vector<A>
(即,如果解析器a
公开类型为A
的属性,则解析器+a
将公开一个(标准)容器,其中包含A
个实例,例如{ {1}})。
在您的情况下,嵌入式解析器会公开std::vector<A>
。因此,您需要更改代码才能按预期工作:
double
但不幸的是,事情并不像看起来那么容易。当前版本的Spirit有一个错误阻止代码工作(即使很快发布的Boost V1.46仍然会有这个错误,但它已在SVN中继中修复)。问题是,plus不会将嵌入的元素“展平”到提供的容器中,从而导致上面代码解析的每两秒都丢失。
解决方法是避免序列在plus中暴露多个属性:
template <typename Iterator>
struct input : qi::grammar<Iterator, std::vector<double>()>
{
input() : input::base_type(start)
{
using qi::lit;
using qi::double_;
start = lit("ADD") >> +(+lit(" ") >> double_ >> +lit(" ") >> double_);
}
qi::rule<Iterator, std::vector<double>()> start;
};
int main()
{
input<std::string::const_iterator> input_parser; // Our grammar
std::string str = "ADD 1132.324 2342.234";
std::vector<double> result;
std::string::const_iterator iter = str.begin();
std::string::const_iterator end = str.end();
bool r = qi::parse(iter, end, input_parser, result);
}
之后验证解析的元素数是偶数。
旁注:您似乎想跳过输入中元素之间的空格。使用跳过解析器可以更容易地实现这一点:
start = lit("ADD") >> +(+lit(" ") >> double_);
同时规避了上述问题。