gpt4 book ai didi

c++ - 提升精神选择无与伦比的结果

转载 作者:太空宇宙 更新时间:2023-11-04 11:33:00 26 4
gpt4 key购买 nike

我有一个格式如下的文件

metal 1 1.2 2.2
wire 1.1 2.3
metal 2 3.2 12.2
...

这是一种非常简单的格式。 “金属”和“电线”是关键字。 “metal”后面跟着 1 个 uint 和 2 个 double,而“wire”后面跟着 2 个 double。我尝试使用 Boost::Qi 来解析它,但结果很奇怪,我无法弄清楚为什么。

#include <iostream>
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_bind.hpp>
#include <boost/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
using std::cout;
using std::endl;
using std::string;

using namespace boost::spirit;

namespace client
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace spirit = boost::spirit;
namespace phoenix = boost::phoenix;

// grammar
template <typename Iterator>
struct TimingLibGrammar :
qi::grammar<Iterator, ascii::space_type>
{
qi::rule<Iterator, ascii::space_type> expression;

TimingLibGrammar() : TimingLibGrammar::base_type(expression)
{
using qi::uint_;
using qi::int_;
using qi::double_;
using qi::char_;
using qi::_1;
using qi::_2;
using qi::_3;
using qi::_val;
using qi::lexeme;
using qi::lit;

expression =
+(
((
"metal"
>> uint_
>> double_
>> double_)[cout << "metal" << " "<< _1 << " " << _2 << " " << _3 << endl])
|
((
"wire"
>> double_
>> double_)[cout << "wire" << " "<< _1 << " " << _2 << endl])
);

}
};
}


int main()
{
using boost::spirit::ascii::space;
using namespace client;
string str = "metal 3 1.0 2.0";
TimingLibGrammar<string::const_iterator> tlg;
string::const_iterator iter = str.begin();
string::const_iterator end = str.end();

client::qi::phrase_parse(iter, end, tlg, space);

return 0;
}

代码的主要部分其实很短。请忽略那些无用的包含。

当我尝试解析一行时

metal 3 1.0 2.0,

解析器给我的结果如下:

wire metal 3 1 2

这个结果是不正确的。它应该输出“金属 3 1 2”,但我不知道这条“电线”是从哪里来的。我还尝试遵循 boost 库中的几个示例代码。但它仍然未能正确处理。代码使用带有 -std=c++11 标志的 g++ 4.7.2 编译。

任何建议都会有所帮助。我是提振精神的新手,所以我希望能学到一些东西。提前致谢。

最佳答案

罪魁祸首是这样的行:

cout << "metal" << " "<< _1 << " " << _2 << " " << _3 << endl

cout << "wire" << " "<< _1 << " " << _2 << endl

请记住,Boost 中的 lambda(Boost.Phoenix 和 Boost.Lambda 变体)是运算符重载的结果。 cout << _1 (相当于 operator<<(cout, _1) )创建一个 lambda,因为 _1由 Phoenix 定义(并导入到 Spirit.Qi 的命名空间中)。 cout << "wire" << _1 , 然而, 是 operator<<(operator<<(cout, "wire"), _1) .它会立即打印出“wire”,并使用operator<<(cout, "wire")的返回值。 - cout - 构造 lambda。内层operator<<是标准库函数。

为了解决这个问题,将它们包裹在phoenix::val中:

cout << phoenix::val("metal") << " "<< _1 << " " << _2 << " " << _3 << endl

cout << phoenix::val("wire") << " "<< _1 << " " << _2 << endl

关于c++ - 提升精神选择无与伦比的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23900618/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com