我想编写一个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 boost spirit上的示例,但输出为“失败”。我怎样才能让它发挥作用?
答案 0 :(得分:2)
因为我精神上有一段时间,但我认为你的一条规则是错误的方式。
尝试:
content = +(escChar | ~char_('"'))
而不是:
content = +(~char_('"') | escChar)
它使用\
与您的~char('"')
匹配,因此永远无法检查escChar
是否匹配。然后它读取下一个"
作为字符串的结尾并停止解析。