c++ - 如何抑制 boost::spirit 中的跳过来解析带引号的字符串?

标签 c++ boost boost-spirit boost-spirit-qi

我正在尝试使用 boost::spirit 实现一个简单的解析器,它(除其他外)接受双引号中的字符串,例如“ Hello World ”。这是一个说明我的问题的精简程序:

#include <iostream>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>

namespace qi = boost::spirit::qi;

static void print(const std::vector<char>& v) {
   std::cout << std::string(v.begin(), v.end()) << '\n';
}

template<typename Iterator>
class Grammar : public qi::grammar<Iterator, boost::spirit::ascii::space_type> {
   typedef boost::spirit::ascii::space_type space_type;
   qi::rule<Iterator, space_type> start;
   qi::rule<Iterator, std::vector<char>()> string;
   qi::rule<Iterator, char()> unescapedChar;

public:
   Grammar() : Grammar::base_type(start) {
      start = string[&print];
      string %= qi::lexeme['"' >> qi::no_skip[*unescapedChar] >> '"'];
      unescapedChar %= qi::char_ - qi::lit('"');
   }
};

int main() {
   const std::string s("\"how now brown cow\"");
   boost::iostreams::filtering_istream fs(boost::make_iterator_range(s.begin(), s.end()));;

   typedef boost::spirit::istream_iterator iterator;
   qi::phrase_parse(
      iterator(fs), iterator(),
      Grammar<iterator>(),
      boost::spirit::ascii::space);

   return 0;
}

在此程序中 unescapedChar规则定义字符串中允许的字符(双引号除外)和 string规则是 unescapedChar 的 Kleene 星在双引号内。

通过时该程序的输出 "how now brown cow" (引号作为字符串的一部分)是 hownowbrowncowstd::vector<char> string 的属性缺少所有空格。我希望解析结果中包含空格。

unescapedChar 都不是也不是 string规则声明指定跳过类型。我还尝试使用 lexemeno_skip单独和一起指令(如上所示)。我尝试过boost 1.49和boost 1.55。在每种情况下,输出都没有嵌入空格。

在我的实际解析器中,我确实想跳过空格,只是不在带引号的字符串内跳过空格。我做错了什么?

最佳答案

我认为你的问题是输入流跳过空格

参见http://en.cppreference.com/w/cpp/io/manip/skipws

添加

fs.unsetf(std::ios::skipws);

修复问题

查看 Live on Coliru

关于c++ - 如何抑制 boost::spirit 中的跳过来解析带引号的字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21493338/

相关文章:

c++ - 如果规则和解析器的属性类型不匹配,如何访问 spirit 规则的属性?

c++ - Boost Spirit Qi 验证输入解析器

java - 当无法通过 JNI 加载 JVM 时如何获得错误消息?

c++ - ostream 引用运算符 <<

c++ - Spirit X3,这种错误处理方式有用吗?

c++ - Cpp/Cli 项目中的 Boost::Log 错误

c++ - 将 boost 编译为通用库(Intel 和 Apple Silicon 架构)

c++ - C++将字符串转换为int

c++ - 将内存块复制到内存的另一部分

c++ - 如何在不删除元素并将其重新插入到 boost::multi_index_container 的情况下移动元素?