boost::spirit 字符/字符串混合

发布于 2024-11-29 21:48:35 字数 1841 浏览 2 评论 0原文

我正在尝试使用 boost::spirit 来解析字符标记,但遇到了很大的困难。这是我正在处理的示例代码:

#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <string>

using namespace std;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

template <typename Iterator>
struct tok_parser : qi::grammar<Iterator, string(), ascii::space_type>
{
  tok_parser() : tok_parser::base_type(start)
  {
    tok1   = qi::char_("AB");
    tok2   = qi::char_("12");
    mytoks = (qi::lit("A1") | qi::lit("A2") | qi::lit("B1") | qi::lit("B2"));
    start  = mytoks;
    //start  = tok1 >> tok2;  // error 1
    //start  = +mytoks;       // error 2
  }
  qi::rule<Iterator, string(), ascii::space_type> start;
  qi::rule<Iterator, string(), ascii::space_type> mytoks;
  qi::rule<Iterator, char, ascii::space_type> tok1;
  qi::rule<Iterator, char, ascii::space_type> tok2;
};

int main(int argc, char** argv)
{
  tok_parser<string::const_iterator> g; // Our grammar
  string str = argv[1];
  string::const_iterator iter = str.begin();
  string::const_iterator end = str.end();
  bool r = phrase_parse(iter, end, g, boost::spirit::ascii::space, str);

  if (r && iter == end)
      cout << "Parsing succeeded\n";
  else
      cout << "Parsing failed\n";

  return 0;
}

错误 1:

我想做的是创建两个标记规则,使我能够解析所有 A1、A2、B1、B2,而不必列出所有文字排列。正如代码所示,它会编译并识别目标标记。但是,如果我尝试根据 tok1 和 tok2 规则构建解析器,它不会编译并生成有关类型不匹配的错误:

error: invalid static_cast from type âboost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >â to type âcharâ

我认为这与尝试用字符创建字符串有关。我尝试过多种类型猜测的排列,但都失败了。

错误 2:

此外,我想允许解析任意数量的标记,不幸的是,前面加上 + 运算符也无法按预期工作。

有什么建议吗?

I'm trying to get a handle on using boost::spirit to parse character tokens, and am having great difficulty. Here is the sample code I'm working on:

#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <string>

using namespace std;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

template <typename Iterator>
struct tok_parser : qi::grammar<Iterator, string(), ascii::space_type>
{
  tok_parser() : tok_parser::base_type(start)
  {
    tok1   = qi::char_("AB");
    tok2   = qi::char_("12");
    mytoks = (qi::lit("A1") | qi::lit("A2") | qi::lit("B1") | qi::lit("B2"));
    start  = mytoks;
    //start  = tok1 >> tok2;  // error 1
    //start  = +mytoks;       // error 2
  }
  qi::rule<Iterator, string(), ascii::space_type> start;
  qi::rule<Iterator, string(), ascii::space_type> mytoks;
  qi::rule<Iterator, char, ascii::space_type> tok1;
  qi::rule<Iterator, char, ascii::space_type> tok2;
};

int main(int argc, char** argv)
{
  tok_parser<string::const_iterator> g; // Our grammar
  string str = argv[1];
  string::const_iterator iter = str.begin();
  string::const_iterator end = str.end();
  bool r = phrase_parse(iter, end, g, boost::spirit::ascii::space, str);

  if (r && iter == end)
      cout << "Parsing succeeded\n";
  else
      cout << "Parsing failed\n";

  return 0;
}

ERROR 1:

What I'd like to do is to create two token rules that allow me to parse all of A1,A2,B1,B2 instead of having to list out all literal permutations. As the code is, it compiles and recognizes the target tokens. But if I try to build my parser out of the tok1 and tok2 rules, it does not compile generating an error about type mismatches:

error: invalid static_cast from type âboost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >â to type âcharâ

I assume this has to do with trying to create strings out of chars. I've played with any number of permutations of type guessing but have failed.

ERROR 2:

Additionally, I'd like to allow an arbitrary number of tokens to be parsed, unfortunately, prepending with the + operator does not work as expected either.

Any tips?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

阪姬 2024-12-06 21:48:35

对于规则,属性始终需要使用函数声明语法来指定:

qi::rule<Iterator, char(), ascii::space_type> tok1;  
qi::rule<Iterator, char(), ascii::space_type> tok2;

这应该可以解决您的编译器问题。

关于你的排列问题:我建议这样做:

rule<Iterator, string(), ascii::space_type> r = char_("AB") >> char_("12");

它将匹配“A1”、“A2”、“B1”或“B2”。

创建另一个规则允许所需的重复:

rule<Iterator, vector<string>(), ascii::space_type> rs = +r;

For rules, attribute always need to be specified using the function declaration syntax:

qi::rule<Iterator, char(), ascii::space_type> tok1;  
qi::rule<Iterator, char(), ascii::space_type> tok2;

which should solve your compiler problems.

Wrt your permutation problem: I'd suggest to do something like:

rule<Iterator, string(), ascii::space_type> r = char_("AB") >> char_("12");

which will match 'A1', 'A2', 'B1', or 'B2'.

Creating another rule allows for the required repetition:

rule<Iterator, vector<string>(), ascii::space_type> rs = +r;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文