Boost Spirit:如何计算某些角色的出现次数,然后将结果放入AST

Boost Spirit: how to count occurences of certain characters and then put the result in AST?

本文关键字:然后 AST 结果 角色 何计算 Spirit 计算 Boost      更新时间:2023-10-16

我想解析以下文本:

group RGB
group RRGB
group GBBB
group RRGGG

结果AST将是一个表示每个字符计数的结构:

struct group
{
int r;
int g;
int b;
};

对于上面的输入,它将是1,1,12,1,10,1,32,3,0

我没有任何语法可以方便地计算字符并强制执行它们的顺序(GBR应该无法解析)。

https://www.boost.org/doc/libs/develop/libs/spirit/doc/x3/html/spirit_x3/quick_reference/directive.html

x3::repeat解析器,但只包含一定数量的字符,它的属性是一个容器。

x3::matches[a]bool属性,但我不知道一个字符会出现多少次

并没有一个解析器可以统计出现次数和返回的匹配次数。我想要像x3::lit("group") >> count['R'] >> count['G'] >> count['B']这样的语法,但不知道应该如何定义count

现在,我能想到的唯一可行的解决方案是x3::lit("group") >> (*x3::char_['R'] >> *x3::char_['G'] >> *x3::char_['B'])[func],它调用func,只对字符串进行操作。IMO这不是一个干净的解决方案,它需要语义操作并创建不必要的字符串。

稍微修改一下"x3/directive/matches.hpp",你就可以得到这样的东西:

#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
namespace not_boost { namespace not_spirit { namespace not_x3
{
template <typename Subject>
struct count_directive : boost::spirit::x3::unary_parser<Subject, count_directive<Subject>>
{
using base_type = boost::spirit::x3::unary_parser<Subject, count_directive<Subject>>;
static bool const has_attribute = true;
using attribute_type = int;
count_directive(Subject const& subject) : base_type(subject) {}
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
int count=0;
while(this->subject.parse(first, last, context, rcontext, boost::spirit::x3::unused))
{
count++;
}
boost::spirit::x3::traits::move_to(count, attr);
return true;
}
};
struct count_gen
{
template <typename Subject>
count_directive<typename boost::spirit::x3::extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return { boost::spirit::x3::as_parser(subject) };
}
};
auto const count = count_gen{};
}}}

在Wandbox 上运行