c++ - Spirit X3 : attribute of alternative parser, 不是 `char` ,而是 `variant<char, char>`

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

根据 spirit x3 属性 fold 规则,具有 2 的替代解析器的属性 具有相同属性的交替,应该 fold ,即 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

以及链接过期时的原始代码

#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 ,拆解后为vector<variant<over_sequence<...>>>variant<over_sequence<>基本上是 variant<T...> 的解决方法在 C++ 之前 11 次。

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

最佳答案

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

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

关于c++ - Spirit X3 : attribute of alternative parser, 不是 `char` ,而是 `variant<char, char>`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57643493/

相关文章:

c# - SWIG 更改 C# 特定类型字段的类型

c++ - 在 C/C++ 中不可能否定 -2147483648?

c++ - 强制 QLineEdit 成为 double 值的集合

boost-spirit - 从 boostspirit 语法获取结果(phoenixpush_back 导致编译错误)

c++ - 使用已删除的函数 CONSTRUCTOR,没有匹配的调用函数

C++ - 使用引用计数的基本垃圾收集器

C++ 模板,在不初始化的情况下声明对象

c++ - 定义我的二维数组以支持 [] 和 () 访问操作

c++ - boost 记录器,多个日志文件和记录器

c++ - .访问违规读取位置