BOOST_FUSION_ADAPT_STRUCT使用带有 std::vector<self_type> 成员的递归结构

BOOST_FUSION_ADAPT_STRUCT using a recursive struct with a std::vector<self_type> member

提问人:WaterFox 提问时间:11/21/2022 最后编辑:seheWaterFox 更新时间:11/22/2022 访问量:114

问:

我正在尝试为精神 x3 解析器声明递归 AST。解析器语法正在工作,并且由于建议避免语义操作,因此我正在尝试调整 Rexpr 官方文档示例

在主文档中,解析的结构可以由映射表示,其中键是字符串,值是字符串或其他映射。

就我而言,正在解析的结构是一个简单的 n 元树,我希望我可以通过递归结构和:forward_ast

#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>

#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>

namespace ast
{
  struct node
  {
    std::string name;
    double length;
    std::vector<boost::spirit::x3::forward_ast<node>> children;
  };
}  
BOOST_FUSION_ADAPT_STRUCT(ast::node, name, length, children)

但是我没有成功进行此编译 - boost fusion 告诉我

error: explicit specialization of undeclared template struct 'tag_of'
BOOST_FUSION_ADAPT_STRUCT(ast::node, name, length, children)

所以我想我也没有理解:

  • 递归AST的逻辑,
  • 用什么语法来告诉 Boost Fusion 这种嵌套类型?
  • 还是两者兼而有之?
C++ 解析 boost-spirit boost-fusion

评论


答:

1赞 sehe 11/21/2022 #1

我不确定我是否遵循了这个问题,但也许这会有所帮助:

Live On 编译器资源管理器

#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>

#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
#include <iostream>

namespace ast {
    using boost::spirit::x3::forward_ast;
    struct node {
        std::string                    name;
        double                         length;
        std::vector<forward_ast<node>> children;
    };

} // namespace ast

BOOST_FUSION_ADAPT_STRUCT(ast::node, name, length, children)

namespace ast {
    using boost::fusion::operator<<;
    static inline std::ostream& operator<<(std::ostream& os, std::vector<forward_ast<node>> const& nn) {
        os << "[";
        auto sep = "";
        for (auto& n : nn)
            os << std::exchange(sep, ", ") << n.get();
        return os << "]";
    }
} // namespace ast

int main() {
    ast::node n{
        "demo",
        42,
        {
            ast::node{"nested1", 43, {}},
            ast::node{"nested4",
                      47,
                      {
                          ast::node{"nested2", 45, {}},
                          ast::node{"nested3", 46, {}},
                      }},
            ast::node{"nested5", 48, {}},
        },
    };

    std::cout << "No problem: " << n << "\n";
}

指纹

No problem: (demo 42 [(nested1 43 []), (nested4 47 [(nested2 45 []), (nested3 46 [])]), (nested5 48 [])])

评论

1赞 sehe 11/21/2022
请注意,从 c++17 开始,你可以不使用 : godbolt.org/z/87MEWPEfr,否则,Boost Container 支持不完整的类型。forward_ast
0赞 WaterFox 11/21/2022
谢谢,是的,知道我使用的语法是正确的,这很有帮助,所以我发现了错误:一个大括号丢失了:/由于我现在知道这个 ast 在编译方面是正确的,它还帮助我弄清楚下一步,即如何将其提供给语法,因为似乎没有解决问题!宝贝向前迈步哈哈!x3::rule<class tree, ast::node> const tree{"tree"};