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

时间:2015-04-30 14:14:08

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

我想在一个非常通用的层面上提出这个问题: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::spirit / boost::fusion支持

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

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

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;
};

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

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

显然,我是唯一有兴趣将boost::multi_arrayboost::spirit一起使用的人。 Stephen Torri在2010年对同一问题产生了一些兴趣。

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

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

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

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