首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Boost Spirit X3解析变体图

用Boost Spirit X3解析变体图
EN

Stack Overflow用户
提问于 2018-12-28 04:20:28
回答 1查看 308关注 0票数 0

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

代码语言:javascript
复制
#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>>的映射。不过,我能够解析变体向量,只有当我试图解析变体映射时,我的代码才失败。值得一提的是,我还阅读了X3教程。任何帮助都将不胜感激。

编辑1

考虑到@liliscent的答案,以及其他一些更改,我终于能够让它正常工作了,下面是正确的代码:

代码语言:javascript
复制
#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;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-28 06:20:38

如果希望spirit识别std::pairstd::map,则需要包含std::pair的融合适配器。

代码语言:javascript
复制
#include <boost/fusion/adapted/std_pair.hpp>

这将修复您的编译问题。但是在您的代码中还有其他问题,这个规则(*x3::alnum | x3::float_);不能做您想做的事情,因为左边的部分可以直接匹配为空。您需要重新考虑如何定义此标识符。

而且,编写pairRule % ","比编写pairRule >> * ( "," >> pairRule );更好。

您应该将输入开始作为一个lvalue迭代器传递,因为在解析过程中它将被高级化,这样您就可以检查解析器是否过早终止。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53953642

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档