我正在尝试使用 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"
(引号作为字符串的一部分)是 hownowbrowncow
。 std::vector<char>
string
的属性缺少所有空格。我希望解析结果中包含空格。
unescapedChar
都不是也不是 string
规则声明指定跳过类型。我还尝试使用 lexeme
和no_skip
单独和一起指令(如上所示)。我尝试过boost 1.49和boost 1.55。在每种情况下,输出都没有嵌入空格。
在我的实际解析器中,我确实想跳过空格,只是不在带引号的字符串内跳过空格。我做错了什么?
最佳答案
我认为你的问题是输入流跳过空格
参见http://en.cppreference.com/w/cpp/io/manip/skipws
添加
fs.unsetf(std::ios::skipws);
修复问题
关于c++ - 如何抑制 boost::spirit 中的跳过来解析带引号的字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21493338/