1

这是我在这里提到的问题的延续

提升业力中不一致的生成器指令列行为

我想将该规则包装到另一个规则中,这样做时,将列指令传递给子规则,但我无法弄清楚这样做的正确方法是什么。

这是下面的代码

#include <boost/spirit/include/karma.hpp>
#include <boost/fusion/include/struct.hpp>
#include <boost/fusion/include/nview.hpp>

///////////////////////////////////////////////////////////////////////////////
namespace client
{


struct BoxData
{
    int num;
    std::string datatype;
    std::string dataname;
    std::string inputicon;
};

struct Box
{
    std::vector<BoxData> box_data;
};

typedef std::back_insert_iterator<std::string> iterator_type;
}

BOOST_FUSION_ADAPT_STRUCT(
        client::BoxData,
//      (int, num)
        (std::string, datatype)
        (std::string, dataname)
        (std::string, inputicon)
)

BOOST_FUSION_ADAPT_STRUCT(
        client::Box,
        (std::vector<client::BoxData>, box_data)
)


///////////////////////////////////////////////////////////////////////////////
int main()
{
    // some employees
    std::vector<client::BoxData> const employees{
            {25, "int",    "sra_command", "fa fa-wrench"},
            {26, "float",  "swt_command", "fa fa-wrench"},
            {27, "double", "msc_command", "fa fa-mobile"},
            {28, "int",    "sra_command", "fa fa-wrench"},
            {29, "float",  "swt_command", "fa fa-wrench"},
            {30, "double", "msc_command", "fa fa-mobile"},
            {31, "int",    "sra_command", "fa fa-wrench"},
            {32, "float",  "swt_command", "fa fa-wrench"},
            {33, "double", "msc_command", "fa fa-mobile"},
    };

    client::Box box;
    ///TODO prevent copying of the vector
    box.box_data = employees;

    // now print them all
    std::string generated;
    {
        using namespace boost::spirit::karma;

        using Sink = client::iterator_type;
        using BoxDataAttr = client::BoxData;
        using BoxAttr = client::Box;

        rule<Sink, BoxDataAttr(),space_type> small_box = "<B>" << string << "<1>" << string << "<2>" << string << "<3>";

        rule<Sink , BoxAttr()> big_box = "<Start>" << *small_box << "<End>" ;

        generate(Sink(generated),[big_box],box);
    }

    std::cout << generated << std::endl;
}

在行

rule<Sink , BoxAttr()> big_box = "<Start>" << *small_box << "<End>" ;

我想通过

columns(2, "delimiter\n")[small_box]

分隔符,以便将列分隔符应用于small_box rule.

所以预期的输出变成

<Start><B>int<1>sra_command<2>fa fa-wrench<3><B>float<1>swt_command<2>fa fa-wrench<3>delimiter
<B>double<1>msc_command<2>fa fa-mobile<3><B>int<1>sra_command<2>fa fa-wrench<3>delimiter
<B>float<1>swt_command<2>fa fa-wrench<3><B>double<1>msc_command<2>fa fa-mobile<3>delimiter
<B>int<1>sra_command<2>fa fa-wrench<3><B>float<1>swt_command<2>fa fa-wrench<3>delimiter
<B>double<1>msc_command<2>fa fa-mobile<3>delimiter<End>

最终因为会有一个向量将另一个自定义分隔符传递给big_box规则。

背景

我打算编写一个诊断接口作为学习各种 C++ 概念的练习,其中涉及以下内容。

1.从 IDL 文件中解析数据。我还没有定义确切的格式,但看起来与此类似

struct Data1
{
int command_one output "fa fa-wrench";
float commmand_two output "fa fa-sensor";
}

struct Data2
{
bool a input switch;
int b input progress_bar {0,100} ;
}
  1. 从 IDL 文件生成 HTML 元素。每个结构都包装在一个盒子中,该盒子包含它们内部的各个元素,这些元素包含在带有图标/可选部分的较小盒子中。第 n 个分隔符对于生成引导网格以将这些框放置在屏幕上很有用。

  2. 使用 websocket 实现完成 HTML 页面,该实现会在收到包含 DOM 元素名称-值对的 JSON 数据时自动更新 DOM 元素。类似地,对于每个输入,执行一个发送命令以将其包装在 JSON 中并发送到 Web 服务器。

  3. 为网络服务器自动生成代码,以便唯一需要实现的代码是从外部源接收/传输数据,并生成所有与 JSON 的转换。

以下用例提示我寻找解析器/生成器解决方案。

4

1 回答 1

2

我不太确定您提出问题的原因,但在我看来,昨天的解决方案是:

Live On Coliru

    rule<Sink, BoxDataAttr()> small_box = "<B>" << string << "<1>" << string << "<2>" << string << "<3>";

    rule<Sink, BoxAttr()> big_box = "<Start>" << columns(4, "delimiter\n") [small_box % eol] << "<End>" ;

    generate(Sink(generated), big_box, employees);

印刷

<Start><B>int<1>sra_command<2>fa fa-wrench<3>
<B>float<1>swt_command<2>fa fa-wrench<3>
delimiter
<B>double<1>msc_command<2>fa fa-mobile<3>
<B>int<1>sra_command<2>fa fa-wrench<3>
delimiter
<B>float<1>swt_command<2>fa fa-wrench<3>
<B>double<1>msc_command<2>fa fa-mobile<3>
delimiter
<B>int<1>sra_command<2>fa fa-wrench<3>
<B>float<1>swt_command<2>fa fa-wrench<3>
delimiter
<B>double<1>msc_command<2>fa fa-mobile<3>delimiter
<End>

凭直觉,您可能错过了, space_type作为规则分隔符的事实small_box

最终因为会有向量将另一个自定义分隔符传递给 big_box 规则。

在这一点上,我质疑您选择的工具。为什么不在这里推出自己的精美印刷品。我希望它会简单得多。另请阅读https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem

奖金:

这里避免复制向量:

client::Box const employees { {
        {25, "int",    "sra_command", "fa fa-wrench"},
        {26, "float",  "swt_command", "fa fa-wrench"},
        {27, "double", "msc_command", "fa fa-mobile"},
        {28, "int",    "sra_command", "fa fa-wrench"},
        {29, "float",  "swt_command", "fa fa-wrench"},
        {30, "double", "msc_command", "fa fa-mobile"},
        {31, "int",    "sra_command", "fa fa-wrench"},
        {32, "float",  "swt_command", "fa fa-wrench"},
        {33, "double", "msc_command", "fa fa-mobile"},
} };

更一般地说,移动语义可以服务于:

box.box_data = std::move(employees);
于 2017-05-02T09:02:02.417 回答