gpt4 book ai didi

c++ - boost.spirit x3 move_to 并列出 ast 成员

转载 作者:太空宇宙 更新时间:2023-11-04 13:02:58 26 4
gpt4 key购买 nike

我实现的 BNF 有一个有趣的规则,其中,根据运算符,术语可以链接或事件不在此生产规则。因此,我使用相同的 AST 数据结构,因为只有枚举发生变化:

#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/adapt_struct.hpp>

#include <iostream>
#include <string>
#include <list>


namespace ast
{
struct identifer {
int name;
};
struct expression {
struct chunk {
char operator_;
ast::identifer identifer;
};
ast::identifer identifer;
std::list<chunk> chunk_list;
};
}

BOOST_FUSION_ADAPT_STRUCT(ast::identifer,
name
)

BOOST_FUSION_ADAPT_STRUCT(ast::expression::chunk,
operator_, identifer
)

BOOST_FUSION_ADAPT_STRUCT(ast::expression,
identifer, chunk_list
)


namespace boost { namespace spirit { namespace x3 { namespace traits {


void move_to(ast::expression::chunk&& chunk, std::list<ast::expression::chunk>& chunk_list,
mpl::identity<container_attribute>)
{
chunk_list.emplace(chunk_list.end(), std::move(chunk));
}

} } } }


namespace parser
{
namespace x3 = boost::spirit::x3;

auto const identifier = x3::rule<struct _, int> { "identifier" } =
x3::int_;

auto const operator_1 = x3::rule<struct _, char> { "operator" } =
x3::char_("ABC");
auto const operator_2 = x3::rule<struct _, char> { "operator" } =
x3::char_("XYZ");

auto const expression_chunk_1 = x3::rule<struct _, ast::expression::chunk> { "expression" } =
operator_1 > identifier
;
auto const expression_chunk_2 = x3::rule<struct _, ast::expression::chunk> { "expression" } =
operator_2 > identifier
;
auto const expression = x3::rule<struct _, ast::expression> { "expression" } =
identifier >> *expression_chunk_1 // foo { and foo }
// rule below fails to compile
| identifier >> expression_chunk_2 // foo [ nand foo ]
;
}


struct visitor {
visitor(std::ostream& os) : os{ os } { }
void operator()(ast::expression const& node) {
os << "(";
(*this)(node.identifer);
for(auto const& chunk : node.chunk_list) {
os << "(" << chunk.operator_ << " ";
(*this)(chunk.identifer);
os << ")";
}
os << ")\n";
}
void operator()(ast::identifer const& node) {
os << "(" << node.name << ")";
}
std::ostream& os;
};


int main()
{
namespace x3 = boost::spirit::x3;

for(std::string const str: {
"1 X 2",
"3 A 4 A 5"
}) {
auto iter = str.begin(), end = str.end();

ast::expression attr;
bool r = x3::phrase_parse(iter, end, parser::expression, x3::space, attr);

std::cout << "parse '" << str << "': ";
if (r && iter == end) {
std::cout << "succeeded:\n";
visitor(std::cout)(attr);

} else {
std::cout << "*** failed ***\n";
}
}

return 0;
}

这就是想法 - 运算符 X,Y,Z 只将一个 block 添加到列表中。在编译器错误之后,我必须专门化 x3::traits::move_to,但我没有找到任何解决方案来编译它。怎么办? list::emplace() 和 std::move() 在这里安全吗?

最佳答案

我宁愿没有这个特质。相反,使语法结果成为 vector<T>人为使用repeat :

auto const expression = x3::rule<struct _, ast::expression> { "expression" } =
identifier >> *expression_chunk_1 // foo { and foo }
| identifier >> x3::repeat(1) [ expression_chunk_2 ] // foo [ nand foo ]
;

关于c++ - boost.spirit x3 move_to 并列出 ast 成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43457070/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com