Spirit X3:替代解析器的属性,不是`char`,而是`variant<char, char>`

Spirit X3: attribute of alternative parser, not `char`, but `variant<char, char>`

根据spirit x3 attribute collapsing rule,替代解析器的属性为2 具有相同属性的交替,应该崩溃,即 a: A, b: A --> (a | b): A,但下面的代码显示它不是,这是错误还是我的错?

这是复合属性规则的spirit x3文档https://www.boost.org/doc/libs/develop/libs/spirit/doc/x3/html/spirit_x3/quick_reference/compound_attribute_rules.html

我有一个代码片段可以重现这个问题

这是代码https://wandbox.org/permlink/7MvN03yiX7ir3esE

和原始代码以防 link 过期

#include <boost/spirit/home/x3.hpp>
#include <iostream>

namespace x3 = boost::spirit::x3;
namespace fusion = boost::fusion;

using x3::_val;
using x3::_attr;
using x3::_where;
using fusion::at_c;

auto const string_def = x3::lexeme["\"" >> *(x3::symbols<char>({ {"\\"", '"'} }) | (x3::print - '\"')) > "\""][([](auto& ctx) {
    std::cout << typeid(_attr(ctx)).name();
    //should _attr(ctx) be a vector<char>, according to attribute collapsing rule?
})];

int main() {
    std::string input = R"__("hello\"world")__";
    x3::parse(input.begin(), input.end(), string_def);
}

基本上,代码解析了一个字符串文字,其中包含许多字符 (*),它可以是除 '"' 之外的字符 (x3::print-'"'),也可以是转义序列"\\""表示字符'"'x3::symbol<char>...),两者都有char的属性,而char | char应该是char,而不是variant<char, char>.

代码的 cout 部分显示的结果类似于 St6vectorIN5boost7variantINS0_6detail7variant13over_sequenceINS0_3mpl6l_itemIN4mpl_5long_ILl2EEEcNS6_INS8_ILl1EEEcNS5_5l_endEEEEEEEJEEESaISF_EE,在 demangling 之后,它是 vector<variant<over_sequence<...>>>variant<over_sequence<> 基本上是 variant<T...> 的解决方法在 C++ 之前 11 次。

那么代码有什么问题,应该是vector<char>,而不是vector<variant>?顺便说一句,我可以自己自定义属性折叠规则吗?

作为@IgorR。评论中提到,语义动作抑制属性传播,我忽略了这一点。所以问题解决了,我可能只需要将其解析为 std::string.

出于某种原因,我需要将其解析为 unique_ptr 对象,因此我需要将解析器分为 rule<StringContent, std::string>rule<StringLiteral, std::unique_ptr<ast::StringLiteral>, true>,问题已解决