boost::spirit 解析器和 boost::fusion 支持哪些容器类型?

Which container types are supported by a boost::spirit parser and boost::fusion?

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

With "support" 我的意思是:使用下面的解析器定义我可以直接解析成 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;
};

整个"magick"是由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> >

所以,我进一步说:

boost::spirit / boost::fusion支持

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

背景: 我正在尝试使用 boost::multi_array 和 "vector of map of double and 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;
};

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

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

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

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

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

嵌套向量和映射的解决方案是由对 boost::spirit 文档的 "Parsers in Depth" 部分的研究激发的。我想在上面的评论中再次强调我之前的声明:忽略 boost::spirit documentation 中的建议"This section is not for the faint of heart." 它包含有价值的信息,一旦您离开非常琐碎的示例,这些信息是绝对需要的。另一个重点是了解boost库本身之间的关系:

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

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

的情况下填充数组