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

Posted

技术标签:

【中文标题】Spirit X3:替代解析器的属性,不是`char`,而是`variant<ch​​ar, char>`【英文标题】:Spirit X3: attribute of alternative parser, not `char`, but `variant<char, char>` 【发布时间】:2019-08-25 05:28:13 【问题描述】:

根据spirit x3属性折叠规则,anternative parser的属性为2 具有相同属性的交替,应该崩溃,即a: A, b: A --&gt; (a | b): A,但下面的代码显示它不是,是错误还是我的错?

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

我有一个代码 sn-p 来重现这个问题

这里是代码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);

Bascally,代码解析一个字符串文字,其中包含许多字符(*),它要么是除'"'之外的字符(x3::print-'"'),要么是表示字符@987654329的转义序列"\\\"" @(x3::symbol&lt;char&gt;...),两者都有char的属性,char | char应该是char,而不是variant&lt;char, char&gt;

代码的cout 部分显示类似St6vectorIN5boost7variantINS0_6detail7variant13over_sequenceINS0_3mpl6l_itemIN4mpl_5long_ILl2EEEcNS6_INS8_ILl1EEEcNS5_5l_endEEEEEEEJEEESaISF_EE 的结果,解构后为vector&lt;variant&lt;over_sequence&lt;...&gt;&gt;&gt;variant&lt;over_sequence&lt;&gt; 基本上是variant&lt;T...&gt; 在pre-C++ 11 次的解决方法。

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

【问题讨论】:

附带说明:我将std::variant 称为一种解决方法,因为它的功能远不如boost::variant :) 至于你的问题,我猜你没有观察到崩溃,因为语义动作抑制了属性传播。尝试将所有这些解析为std::string,而不是语义操作。 @IgorR。感谢您的评论,我现在知道为什么了,但我确实需要将其解析为 unique_ptr 以保持代码的一致性 【参考方案1】:

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

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

【讨论】:

以上是关于Spirit X3:替代解析器的属性,不是`char`,而是`variant<ch​​ar, char>`的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Boost Spirit X3 解析空的 C++ 结构

使用 boost::spirit::x3 解析成向量<boost::string_view>

Boost Spirit x3 -- 使用其他解析器参数化解析器

Boost Spirit X3:跳过啥都不做的解析器

boost::spirit 解析器的编译错误

Boost Spirit X3的上下文是啥?