【问题标题】:Which container types are supported by a boost::spirit parser and boost::fusion?boost::spirit 解析器和 boost::fusion 支持哪些容器类型?
【发布时间】:2015-04-30 14:14:07
【问题描述】:

我想问一个非常笼统的问题:boost::spirit / boost::fusion 对容器类型的支持能达到多远?谁能给我一些关于什么是可能的和什么是不可能的通用指导?

使用“支持”我的意思如下:使用以下解析器定义,我可以直接解析为 std::pair<double,double>

template <typename Iterator>
struct pair_parser
    :     qi::grammar<Iterator, std::pair<double,double>()>
{
    pair_parser() : pair_parser::base_type(start)
    {
         start = pair;
         pair  = qi::double_ >> ":" >> qi::double >> ";"
    }
    qi::rule<Iterator, std::pair<double,double>()> pair;
};

我是否正确理解整个“魔术”是由boost::fusion 完成的?考虑到这一点,让我定义:支持双打

我找到了以下工作示例:

 std::vector<std::string>
 std::map<std::string, std::string>   // the trick is not to forget the pair within
 std::vector<std::vector<int> >
 struct A{int, double, std::string}   // with boost::fusion adaptor

我已经解决了以下问题:

std::map<std::string,  boost::variant<int, double, std::string> >

所以,我进一步说:

  • 字符串向量
  • 简单的名称-值映射
  • POD 类型向量的向量
  • boost::variant
  • 结构

boost::spirit / boost::fusion 支持

但是,它是否也适用于其他 STL 容器?一般都支持还是有一些不起作用? boost::containers 呢?嵌套容器怎么样?它们可以嵌套多深?嵌套结构怎么样?我需要了解什么来确定容器是否可以与 boost::spirit / boost::fusion 一起使用?

背景: 我正在尝试使用 boost::multi_array 和“double 和 struct 映射向量”解析成稍微更复杂的类型,例如 struct table

struct skewFactor{
    double horizontalSkew;
    double verticalSkew;
    double factor;
};
struct table {
    std::vector<std::vector<double> > index;
    boost::multi_array<double,4> baseArray; // yes, this array is 4-dimensional
    std::vector<std::map<double, skewFactor> > effect;
};

目前我只是通过反复试验来解决问题。

【问题讨论】:

  • 目前还不清楚您期望从命名库中获得什么“支持”。我不知道 fusion 是否支持 array&lt;&gt; 以外的任何容器。 Spirit 从来没有嵌套的支持。除非你能澄清你的意思。
  • @sehe,很抱歉不清楚。英语不是我的母语。我会尝试改写它。
  • 英文很好。尝试更具体地说明什么是支持
  • 也许这个问题已经过时了;我正在慢慢理解我提出这个问题的问题。无视 boost::spirit 文档中的建议“本节不适合胆小的人。”(在“深度解析器”一节中)实际上帮助很大。

标签: c++ boost stl boost-spirit boost-fusion


【解决方案1】:

boost::spirit 可以很好地处理任意嵌套,您只受编译器和硬件限制。

您可能需要(非侵入式)调整您的类和结构,以便boost::spirit 可以直接解析到它们。请参阅Employee - Parsing into structs 示例。

【讨论】:

  • 我知道那个例子,我研究过。我的问题是更复杂的类型,比如std::vector&lt;std::map&lt;std::string, std::vector&lt;T&gt;&gt;&gt;。我现在通过std::map&lt;std::string, boost::variant&lt;int, double, std::string&gt; &gt; 取得了轻微的成功。但我需要更进一步。
【解决方案2】:

显然我是唯一有兴趣将boost::multi_arrayboost::spirit 一起使用的人。早在 2010 年,Stephen Torri 就对同样的问题感兴趣。

我在上面的struct table; 方面取得了进展。 boost::fusion 很好地支持嵌套向量、映射和结构。但是,boost::multi_array 仍在等待解决方案。最大的绊脚石之一是臭名昭著的缺乏好的例子。 (稍后我可能会添加一些示例)

嵌套向量和映射的解决方案是由对boost::spirit 文档的“深度解析器”部分的研究引发的。我想在上面的评论中再次强调我之前的声明:忽略boost::spirit documentation 中的建议“此部分不适合胆小的人。”它包含有价值的信息,一旦您离开非常琐碎的示例,就绝对需要这些信息。另一个重要的一点是要了解boost库本身之间的关系:

  • fusion: 用于序列化任何数据类型的库。它用于精神语法中的“自动”数据传播。
  • phoenix:函数式编程库。
  • 精神:解析器库本身。它建立在凤凰之上。函数式编程是理解解析器和语义动作的关键。

对于boost::multi_array,我决定走另一条路:语义动作。尽管它们在boost::spirit 社区中不受欢迎,但我还是决定使用它们,因为我还必须在数组中执行一些转换。使用boost::phoenix,我(几乎)能够在不依赖boost::fusion 的情况下填充数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    • 1970-01-01
    • 2012-01-17
    • 2015-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多