我正在尝试使用boost :: spirit实现一个简单的解析器,其中(除其他外)接受双引号中的字符串,例如“你好,世界”。这是一个简化程序,说明了我的问题:
#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>
的{{1}}属性缺少所有空格。我希望空格在解析结果中。
string
和unescapedChar
规则声明均未指定跳过类型。我还尝试单独和一起使用string
和lexeme
指令(如上所示)。我试过提升1.49并提升1.55。在每种情况下,输出都没有嵌入空格。
在我的实际解析器中,我确实想要跳过空格,而不是在带引号的字符串中。我做错了什么?
答案 0 :(得分:4)
我认为你的问题是跳过空白的输入流
请参阅http://en.cppreference.com/w/cpp/io/manip/skipws
添加
fs.unsetf(std::ios::skipws);
解决问题