【发布时间】:2014-02-01 02:15:01
【问题描述】:
我正在尝试使用 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。 string 的 std::vector<char> 属性缺少所有空格。我希望空格在解析结果中。
unescapedChar 和 string 规则声明均未指定跳过类型。我还尝试单独和一起使用lexeme 和no_skip 指令(如上所示)。我试过 boost 1.49 和 boost 1.55。在每种情况下,输出都没有嵌入空格。
在我的实际解析器中,我确实想跳过空格,而不是在带引号的字符串中。我做错了什么?
【问题讨论】:
-
对不起。我注意到在我投票为重复之后你已经使用了(太多)这些技术。看我的回答。
标签: c++ boost boost-spirit boost-spirit-qi