简体   繁体   English

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM