我无法使用语法,因此我将其简化为只解析整数。仍然无法让它发挥作用。它是以下语法:
template<typename Iterator>
struct rangeGrammar : qi::grammar<Iterator, int()>
{
rangeGrammar() :
rangeGrammar::base_type(number)
{
using qi::int_;
using qi::_1;
using qi::_val;
number = int_[_val = _1];
}
qi::rule<Iterator, int()> number;
};
它应该只解析一个整数(我知道我可以告诉解析函数使用int_作为语法,但我不知道这个例子中有什么问题)。
我的解析功能是:
/* n is a std::string provided by the user */
rangeGrammar<std::string::const_iterator> grammar;
int num = 0;
qi::phrase_parse(n.start(), n.end(), grammar, num);
std::cout << "Number: " << num << std::endl;
我收到以下编译错误:
/boost/spirit/home/qi/reference.hpp:在成员函数'bool boost :: spirit :: qi :: reference :: parse(Iterator&amp;,const Iterator&amp;,Context&amp;,const Skipper&amp;,Attribute&amp; amp ;)const [与Iterator = __gnu_cxx :: __ normal_iterator&gt;,Context = boost :: spirit :: context,boost :: spirit :: locals&lt;&gt; &gt;,Skipper = boost :: spirit :: unused_type,Attribute = int,Subject = const boost :: spirit :: qi :: rule&lt; __ gnu_cxx :: __ normal_iterator&gt;,int(),boost :: spirit :: unused_type, boost :: spirit :: unused_type,boost :: spirit :: unused_type&gt;]': /boost/spirit/home/qi/parse.hpp:89:82:从'bool boost :: spirit :: qi :: parse(Iterator&amp;,Iterator,const Expr&amp;,Attr&amp;)实例化[与Iterator = __gnu_cxx: :__ normal_iterator&gt;,Expr = rangeGrammar&lt; __ gnu_cxx :: __ normal_iterator&gt; &gt;,Attr = int]' ../parameter_parser.h:95:46:从这里实例化 boost / spirit / home / qi / reference.hpp:43:71:错误:调用'boost :: spirit :: qi :: rule&lt; __ gnu_cxx :: __ normal_iterator&gt;,int(),boost ::没有匹配函数spirit :: unused_type,boost :: spirit :: unused_type,boost :: spirit :: unused_type&gt; :: parse(__ gnu_cxx :: __ normal_iterator&gt;&amp;,const __gnu_cxx :: __ normal_iterator&gt;&amp;,boost :: spirit :: context,boost :: spirit :: locals&lt;&gt;&gt;&amp;,const boost :: spirit :: unused_type&amp;,int&amp;)const' cc1plus:警告被视为错误 /boost/spirit/home/qi/reference.hpp:44:9:错误:控件到达非void函数结束 *退出状态1 *
无法弄清问题是什么。任何帮助将不胜感激。
答案 0 :(得分:11)
答:语法中没有没有 错误,但你使用qi::phrase_parse
需要一个队长。使用qi::parse
,问题就会消失。
注1:使用[_val=_1]
完全是多余的;没有语义属性的规则享受自动属性传播。
注2:您可能希望使用qi :: match进行这样的解析:
#include <boost/spirit/include/qi_match.hpp>
const std::string input = "1234";
std::istringstream iss(input);
iss >> qi::match(qi::int_ [ std::cout << qi::_1 ]);
最后为了您的兴趣,这里有一个骨架'doParse'函数,运行测试显示了更好的Qi练习元素:
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
template<typename Iterator>
struct rangeGrammar : qi::grammar<Iterator, int()>
{
rangeGrammar() : rangeGrammar::base_type(number)
{
number = qi::int_;
}
qi::rule<Iterator, int()> number;
};
bool doParse(const std::string& input)
{
typedef std::string::const_iterator It;
It f(begin(input)), l(end(input));
try
{
rangeGrammar<It> p;
int data;
bool ok = qi::parse(f,l,p,data);
if (ok)
{
std::cout << "parse success\n";
std::cout << "data: " << data << "\n";
}
else std::cerr << "parse failed: '" << std::string(f,l) << "'\n";
if (f!=l) std::cerr << "trailing unparsed: '" << std::string(f,l) << "'\n";
return ok;
} catch(const qi::expectation_failure<It>& e)
{
std::string frag(e.first, e.last);
std::cerr << e.what() << "'" << frag << "'\n";
}
return false;
}
int main()
{
bool ok = doParse("1234");
return ok? 0 : 255;
}