使用 Boost::Spirit 解析转义字符串

发布于 2024-12-08 03:40:50 字数 1360 浏览 2 评论 0原文

我想编写一个 boost::spirit 解析器,它解析使用转义双引号的双引号中的简单字符串,例如 "a \"b\" c"

这是我尝试过的:

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>

#include <iostream>
#include <string>

namespace client
{
  namespace qi = boost::spirit::qi;
  namespace ascii = boost::spirit::ascii;

  template <typename Iterator>
  bool parse(Iterator first, Iterator last)
  { 
    using qi::char_;

    qi::rule< Iterator, std::string(), ascii::space_type > text;
    qi::rule< Iterator, std::string() > content;
    qi::rule< Iterator, char() > escChar;

    text = '"' >> content >> '"';
    content = +(~char_('"') | escChar);
    escChar = '\\' >> char_("\"");

    bool r = qi::phrase_parse(first, last, text, ascii::space);
    if (first != last) // fail if we did not get a full match
      return false;
    return r;
  }
}

int main() {
  std::string str = "\"a \\\"b\\\" c\"";
  if (client::parse(str.begin(), str.end()))
    std::cout << str << " Parses OK: " << std::endl;
  else
    std::cout << "Fail\n";
  return 0;
}

它遵循 Parsing escaped strings with boostspirit,但输出是“失败”。我怎样才能让它发挥作用?

I would like to write a boost::spirit parser that parses a simple string in double quotes that uses escaped double quotes, e.g. "a \"b\" c".

Here is what I tried:

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>

#include <iostream>
#include <string>

namespace client
{
  namespace qi = boost::spirit::qi;
  namespace ascii = boost::spirit::ascii;

  template <typename Iterator>
  bool parse(Iterator first, Iterator last)
  { 
    using qi::char_;

    qi::rule< Iterator, std::string(), ascii::space_type > text;
    qi::rule< Iterator, std::string() > content;
    qi::rule< Iterator, char() > escChar;

    text = '"' >> content >> '"';
    content = +(~char_('"') | escChar);
    escChar = '\\' >> char_("\"");

    bool r = qi::phrase_parse(first, last, text, ascii::space);
    if (first != last) // fail if we did not get a full match
      return false;
    return r;
  }
}

int main() {
  std::string str = "\"a \\\"b\\\" c\"";
  if (client::parse(str.begin(), str.end()))
    std::cout << str << " Parses OK: " << std::endl;
  else
    std::cout << "Fail\n";
  return 0;
}

It follows the example on Parsing escaped strings with boost spirit, but the output is "Fail". How can I get it to work?

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

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

发布评论

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

评论(1

嘿哥们儿 2024-12-15 03:40:50

我已经有一段时间没有尝试过精神了,但我认为你的规则之一是错误的。

尝试:

content = +(escChar | ~char_('"'))

而不是:

content = +(~char_('"') | escChar)

它使用 ~char('"') 匹配您的 \ ,因此永远不会检查 escChar 是否匹配。然后它读取下一个 " 作为字符串的末尾并停止解析。

Been a while since I had a go at spirit, but I think one of your rules is the wrong way round.

Try:

content = +(escChar | ~char_('"'))

instead of:

content = +(~char_('"') | escChar)

It is matching your \ using ~char('"') and therefore never gets round to checking if escChar matches. It then reads the next " as the end of the string and stops parsing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文