根据 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/