c++ - 使用 Boost Spirit X3 解析变体图

标签 c++ boost c++14 boost-spirit boost-spirit-x3

我正在尝试(但失败了)解析 map<int, variant<string, float>>使用 Boost Spirit X3,代码如下:

#include <boost/spirit/home/x3/support/ast/variant.hpp>
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <map>
#include <variant>
#include <string>

using namespace std;

namespace x3 = boost::spirit::x3;

int main() {
    auto variantRule = x3::rule<class VariantClass, x3::variant<std::string, float>>() = (*x3::alnum | x3::float_);

    auto pairRule = x3::rule<class PairClass, pair<int, x3::variant<std::string, float>>>() = x3::int_ >> ":" >> variantRule;

    auto mapRule = x3::rule<class MapClass, map<int, x3::variant<std::string, float>>>() = pairRule >>  * ( "," >> pairRule );

    string input = "1 : 1.0, 2 : hello, 3 : world";

    map<int, x3::variant<std::string, float>> variantMap;

    auto success = x3::phrase_parse(input.begin(), input.end(), mapRule, x3::space, variantMap);

    return 0;
}

出于某种原因,我无法解析 pair<int, variant<string, float>> 的 map .虽然我能够解析变体 vector ,但只有当我尝试解析变体映射时,我的代码才会失败。值得一提的是,我还浏览了 X3 教程。任何帮助将不胜感激。

编辑 1

考虑到@liliscent 的回答和其他一些更改,我终于能够让它工作,这是正确的代码:

#include <boost/spirit/home/x3/support/ast/variant.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <map>
#include <variant>
#include <string>

using namespace std;

namespace x3 = boost::spirit::x3;

int main() {
    auto stringRule = x3::rule<class StringClass, string>() = x3::lexeme[x3::alpha >> *x3::alnum];

    auto variantRule = x3::rule<class VariantClass, x3::variant<std::string, float>>() = (stringRule | x3::float_);

    auto pairRule = x3::rule<class PairClass, pair<int, x3::variant<std::string, float>>>() = x3::int_ >> ':' >> variantRule;

    auto mapRule = x3::rule<class MapClass, map<int, x3::variant<std::string, float>>>() = pairRule % ",";

    string input = "1 : 1.0, 2 : hello, 3 : world";

    map<int, x3::variant<std::string, float>> variantMap;

    auto bg = input.begin(), ed = input.end();

    auto success = x3::phrase_parse(bg, ed, mapRule, x3::space, variantMap) && bg == ed;

    if (!success) cout<<"Parsing not succesfull";

    return 0;
}

最佳答案

如果你想让spirit识别std::pairstd::map,你需要包含的 fusion 适配器>std::pair:

#include <boost/fusion/adapted/std_pair.hpp>

这应该可以修复您的 compilation problem .但是你的代码还有其他问题,这个规则 (*x3::alnum | x3::float_); 不会做你想要的,因为左边部分可以直接匹配空。您需要重新考虑如何定义此标识符。

此外,pairRule % ","pairRule >> * ( ",">> pairRule ); 更好。

并且您应该将输入 begin 作为左值迭代器传递,因为这样它将在解析过程中提前,以便您可以检查解析器是否过早终止。

关于c++ - 使用 Boost Spirit X3 解析变体图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53953642/

相关文章:

c++ - linux c++ 使用现有的浏览器组件?

c++ - 从一个进程到另一个进程的信号 C++

c++ - MPL for_each 使用带有更多参数的仿函数

c++ - 重载函数内部的函数重载

c++ - 如何为视口(viewport)应用程序重新采样图像的子区域?

c++ - 从C++连接MySQL : error LNK2001: unresolved external symbol

C++ BOOST undefined reference `boost::filesystem::detail::copy_file

c++ - 我可以根据其 operator() 的签名专门化可变参数模板参数吗

c++ - 是否可以从父类 "this"指针类型强制转换为子类

c++ - 如何抛出 boost bad 词法转换异常