Разбор экранированных строк с использованием Boost :: Spirit - PullRequest
2 голосов
/ 04 октября 2011

Я хотел бы написать парсер 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;
}

Это соответствует примеру на Разбор экранированных строк с буст-спиритом , но вывод «Fail».Как я могу заставить его работать?

1 Ответ

2 голосов
/ 04 октября 2011

Прошло некоторое время с тех пор, как я начал заниматься духом, но я думаю, что одно из ваших правил - неправильное.

Попробуйте:

content = +(escChar | ~char_('"'))

вместо:

content = +(~char_('"') | escChar)

Он соответствует вашему \ с использованием ~char('"') и, следовательно, никогда не проверяет, соответствует ли escChar.Затем он читает следующий " как конец строки и прекращает синтаксический анализ.

...