解析为带有 qi 和替代部分的结构

Parsing into structs with qi and alternative parts

本文关键字:代部 结构 qi      更新时间:2023-10-16

我使用精神解析器已经很长时间了,但现在我有一个我不太明白的问题。 我想将a,b->c,d或a,b->d之类的东西解析为结构。如果输入为 a,b->c,d(规则的左侧部分(,则以下代码将执行此操作。但是,如果输入是a,b->d(交替部分(,则产生aa,bb,,d。因此,替代解析器似乎不会清除已解析的部分。

struct Test
{
std::string a;
std::string b;
std::string c;
std::string d;
};
BOOST_FUSION_ADAPT_STRUCT(Test,
(std::string, a)
(std::string, b)
(std::string, c)
(std::string, d))
using namespace boost::spirit::qi;
using std::string;
using std::pair;
rule<const char *, Test()> r = (+alnum >> ',' >> +alnum >> "->" >> +alnum >> ',' >> +alnum) | (+alnum >> ',' >> +alnum >> "->" >> attr(string()) >> +alnum);
Test result;
//const char* s = "a,b->c,d"; //produces a Result with a,b,c,d
const char* s = "a,b->d"; // procudes a Result with aa,bb,,d
parse(s, s + strlen(s), r, result);

将其制作成一个独立的复制品:

活在魔杖盒上

#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted.hpp>
#include <iomanip>
#include <iostream>
namespace qi = boost::spirit::qi;
struct Test { std::string a, b, c, d; };
BOOST_FUSION_ADAPT_STRUCT(Test, a,b,c,d)
int main() {
qi::rule<const char *, Test()> static const r 
= (+qi::alnum >> ',' >> +qi::alnum >> "->" >> +qi::alnum >> ',' >> +qi::alnum)
| (+qi::alnum >> ',' >> +qi::alnum >> "->" >> qi::attr(std::string()) >> +qi::alnum);
for (auto input : {
"a,b->c,d",
"a,b->d"
}) {
Test result;
qi::parse(input, input + strlen(input), r, result);
for (auto const& part: { result.a, result.b, result.c, result.d })
std::cout << " " << std::quoted(part);
std::cout << "n";
}
}

印刷

"a" "b" "c" "d"
"aa" "bb" "" "d"

因此,您的问题类似于:

  • 了解 Boost.spirit 的字符串解析器
  • 在灵气中使用可选的解析器
  • 回滚气灵中替代解析器的变化

常见的解决方案是qi::hold[]它有一些开销,但通常有效:

qi::rule<const char *, Test()> static const r 
= qi::hold [+qi::alnum >> ',' >> +qi::alnum >> "->" >> +qi::alnum >> ',' >> +qi::alnum]
| (+qi::alnum >> ',' >> +qi::alnum >> "->" >> qi::attr(std::string()) >> +qi::alnum);

哪些打印在魔杖盒上直播

"a" "b" "c" "d"
"a" "b" "" "d"