Spirit X3:替代解析器的属性,不是`char`,而是`variant<char, char>`
Posted
技术标签:
【中文标题】Spirit X3:替代解析器的属性,不是`char`,而是`variant<char, 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 --> (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<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...>
在pre-C++ 11 次的解决方法。
那么代码有什么问题,应该是vector<char>
,而不是vector<variant>
?顺便说一句,我可以自己自定义属性折叠规则吗?
【问题讨论】:
附带说明:我将std::variant
称为一种解决方法,因为它的功能远不如boost::variant
:)
至于你的问题,我猜你没有观察到崩溃,因为语义动作抑制了属性传播。尝试将所有这些解析为std::string
,而不是语义操作。
@IgorR。感谢您的评论,我现在知道为什么了,但我确实需要将其解析为 unique_ptr作为@IgorR。评论中提到,语义动作抑制属性传播,我忽略了这一点。所以问题解决了,我可能需要把它解析成 std::string。
出于某种原因,我需要将其解析为 unique_ptr 对象,因此我需要将解析器分为 rule<StringContent, std::string>
和 rule<StringLiteral, std::unique_ptr<ast::StringLiteral>, true>
,问题已解决
【讨论】:
以上是关于Spirit X3:替代解析器的属性,不是`char`,而是`variant<char, char>`的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 Boost Spirit X3 解析空的 C++ 结构
使用 boost::spirit::x3 解析成向量<boost::string_view>