使用spirit::karma从元组向量中重新排序元组

发布于 2024-12-27 01:56:07 字数 1448 浏览 3 评论 0原文

#include <tuple>
#include <vector>
#include <string>
#include <iostream>
//-------------------------------------------------------------------------
#include <boost/spirit/include/karma.hpp>
#include <boost/fusion/adapted/std_tuple.hpp>
//-------------------------------------------------------------------------
namespace ph = boost::phoenix;
namespace karma = boost::spirit::karma;
typedef std::back_insert_iterator<std::string> Sink;
typedef std::tuple<double,int> Data;
typedef std::vector<Data> Container;
struct Generator : karma::grammar<Sink,Container()>
{
  Generator(void) : Generator::base_type(start,"Generator")
  {
    start = data % karma::eol;
    //data = karma::delimit[???];
    return;
  }
  karma::rule<Sink,Container()> start;
  karma::rule<Sink,Data()> data;
};
//-------------------------------------------------------------------------
int main(int argc,char** argv)
{
  Generator generator;
  Container container;
  container.push_back(Data(3.1415,100500));
  container.push_back(Data(2.7183,9000));
  std::string result;
  Sink sink(result);
  bool b = boost::spirit::karma::generate(sink,generator,container);
  std::cerr << (b == true ? result : std::string("Error!")) << std::endl;
  return 0;
}

在规则 data 中(例如),我需要在 double 之前生成 int 并用它进行算术运算。如何在 data 规则的语义操作中访问合成属性(元组)的元素?

#include <tuple>
#include <vector>
#include <string>
#include <iostream>
//-------------------------------------------------------------------------
#include <boost/spirit/include/karma.hpp>
#include <boost/fusion/adapted/std_tuple.hpp>
//-------------------------------------------------------------------------
namespace ph = boost::phoenix;
namespace karma = boost::spirit::karma;
typedef std::back_insert_iterator<std::string> Sink;
typedef std::tuple<double,int> Data;
typedef std::vector<Data> Container;
struct Generator : karma::grammar<Sink,Container()>
{
  Generator(void) : Generator::base_type(start,"Generator")
  {
    start = data % karma::eol;
    //data = karma::delimit[???];
    return;
  }
  karma::rule<Sink,Container()> start;
  karma::rule<Sink,Data()> data;
};
//-------------------------------------------------------------------------
int main(int argc,char** argv)
{
  Generator generator;
  Container container;
  container.push_back(Data(3.1415,100500));
  container.push_back(Data(2.7183,9000));
  std::string result;
  Sink sink(result);
  bool b = boost::spirit::karma::generate(sink,generator,container);
  std::cerr << (b == true ? result : std::string("Error!")) << std::endl;
  return 0;
}

in rule data (as example) I need generate int before double and make with it arithmetical operation. How can I get access to elements of synthesized attribute (tuple) in semantic actions of data rule?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

掩于岁月 2025-01-03 01:56:07

我现在能想到的最快解决方案很简单:

data = delimit [ int_ [ _1 = at_c<1>(_val) ] << double_ [ _1 = at_c<0>(_val) ] ];

因此,完整的示例如下所示:

#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>

#include <boost/fusion/adapted.hpp>
#include <boost/tuple/tuple.hpp>
//-------------------------------------------------------------------------
namespace ph = boost::phoenix;
namespace karma = boost::spirit::karma;
typedef std::back_insert_iterator<std::string> Sink;
typedef boost::tuple<double,int> Data;
typedef std::vector<Data> Container;
struct Generator : karma::grammar<Sink,Container()>
{
    Generator(void) : Generator::base_type(start,"Generator")
    {
        using namespace karma;
        using namespace ph;
        data = delimit [ int_ [ _1 = at_c<1>(_val) ] << double_ [ _1 = at_c<0>(_val) ] ];
        start = data % eol;
        return;
    }
    karma::rule<Sink,Container()> start;
    karma::rule<Sink,Data()> data;
};
//-------------------------------------------------------------------------
int main(int argc,char** argv)
{
    Generator generator;
    Container container;
    container.push_back(Data(3.1415,100500));
    container.push_back(Data(2.7183,9000));
    std::string result;
    Sink sink(result);
    bool b = boost::spirit::karma::generate(sink,generator,container);
    std::cerr << (b == true ? result : std::string("Error!")) << std::endl;
    return 0;
}

输出:

100500 3.142
9000 2.718

The quickest solution I can come up with at this instant is simply:

data = delimit [ int_ [ _1 = at_c<1>(_val) ] << double_ [ _1 = at_c<0>(_val) ] ];

So, a full sample would look like:

#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>

#include <boost/fusion/adapted.hpp>
#include <boost/tuple/tuple.hpp>
//-------------------------------------------------------------------------
namespace ph = boost::phoenix;
namespace karma = boost::spirit::karma;
typedef std::back_insert_iterator<std::string> Sink;
typedef boost::tuple<double,int> Data;
typedef std::vector<Data> Container;
struct Generator : karma::grammar<Sink,Container()>
{
    Generator(void) : Generator::base_type(start,"Generator")
    {
        using namespace karma;
        using namespace ph;
        data = delimit [ int_ [ _1 = at_c<1>(_val) ] << double_ [ _1 = at_c<0>(_val) ] ];
        start = data % eol;
        return;
    }
    karma::rule<Sink,Container()> start;
    karma::rule<Sink,Data()> data;
};
//-------------------------------------------------------------------------
int main(int argc,char** argv)
{
    Generator generator;
    Container container;
    container.push_back(Data(3.1415,100500));
    container.push_back(Data(2.7183,9000));
    std::string result;
    Sink sink(result);
    bool b = boost::spirit::karma::generate(sink,generator,container);
    std::cerr << (b == true ? result : std::string("Error!")) << std::endl;
    return 0;
}

Output:

100500 3.142
9000 2.718
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文