[英]Spirit X3: attribute of alternative parser, not `char`, but `variant<char, char>`
According to spirit x3 attribute collapsing rule, the attribute of an anternative parser with 2 alternation having same attribute, should collapse, ie a: A, b: A --> (a | b): A
, but the code below shows its not, is it a bug or my fault?根据 Spirit x3 属性折叠规则,具有相同属性的 2 个交替的替代解析器的属性应该折叠,即
a: A, b: A --> (a | b): A
,但下面的代码显示它不是,是bug还是我的错?
Here is the spirit x3 documentation of compound attribute rules https://www.boost.org/doc/libs/develop/libs/spirit/doc/x3/html/spirit_x3/quick_reference/compound_attribute_rules.html这是复合属性规则的精神 x3 文档https://www.boost.org/doc/libs/develop/libs/spirit/doc/x3/html/spirit_x3/quick_reference/compound_attribute_rules.html
I've got a code snippet to reproduce this question我有一个代码片段来重现这个问题
Here is the code https://wandbox.org/permlink/7MvN03yiX7ir3esE
这是代码
https://wandbox.org/permlink/7MvN03yiX7ir3esE
And the original code in case the link expired以及链接过期时的原始代码
#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);
}
Bascally, the code parse a string literal, which contains a number of chars ( *
), which is either a character except '"'
( x3::print-'"')
, or a escape sequence "\\\\\\""
representing the character '"'
( x3::symbol<char>...
), both of them has a attribute of char
, and char | char
基本上,代码解析一个字符串字面量,其中包含多个字符 (
*
),它可以是除'"'
( x3::print-'"')
之外的字符,或者是一个转义序列"\\\\\\""
表示字符'"'
( x3::symbol<char>...
),它们都具有char
属性,而char | char
char | char
should be char
, not variant<char, char>
. char | char
应该是char
,而不是variant<char, char>
。
the cout
part of the code shows result like St6vectorIN5boost7variantINS0_6detail7variant13over_sequenceINS0_3mpl6l_itemIN4mpl_5long_ILl2EEEcNS6_INS8_ILl1EEEcNS5_5l_endEEEEEEEJEEESaISF_EE
, after demangling, it is vector<variant<over_sequence<...>>>
and variant<over_sequence<>
is basically a workaround of variant<T...>
in pre-C++11 times.的
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 次。
So what's wrong with the code, should it be vector<char>
, not vector<variant>
?那么代码有什么问题,它应该是
vector<char>
,而不是vector<variant>
吗? And BTW, can I customize attribute collapsing rule myself?顺便说一句,我可以自己自定义属性折叠规则吗?
As @IgorR.作为@IgorR。 mentioned in comment, semantic action suppresses attribute propagation, I ignored that point.
在评论中提到,语义动作抑制了属性传播,我忽略了这一点。 So problem solved, I might need just parse this into std::string.
所以问题解决了,我可能只需要将其解析为 std::string。
For some reason I need parsing this into a unique_ptr object, so I need separate the parser into a rule<StringContent, std::string>
and a rule<StringLiteral, std::unique_ptr<ast::StringLiteral>, true>
, problem solved出于某种原因,我需要将它解析为一个 unique_ptr 对象,所以我需要将解析器分成一个
rule<StringContent, std::string>
和一个rule<StringLiteral, std::unique_ptr<ast::StringLiteral>, true>
,问题解决了
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.