我想解析以下文本:
group RGB
group RRGB
group GBBB
group RRGGG
结果AST将是一个表示每个字符计数的结构:
struct group
{
int r;
int g;
int b;
};
对于上面的输入,应该是
1,1,1
,2,1,1
,0,1,3
和2,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{};
}}}
Running on Wandbox
关于c++ - Boost Spirit:如何计算某些字符的出现次数,然后将结果放入AST?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54128284/