boost :: spirit stream_parser потребляет слишком много? - PullRequest
4 голосов
/ 24 марта 2011

У меня возникли проблемы при интеграции класса с поддержкой синтаксического анализа iostream в анализатор духа.Пример ниже (модифицированный из примеров Spirit) демонстрирует проблему.Если я попытаюсь проанализировать ТОЛЬКО пользовательский класс, он завершится успешно, как показано первым анализом и вызовом assert.Если я попытаюсь проанализировать пользовательский класс, а также (в данном случае) запятую и число с плавающей точкой, синтаксический анализатор завершится ошибкой.

Может ли кто-нибудь пролить свет на то, почему это будет?Если я использую анализаторы спирта вместо потокового парсера, я могу заставить работать второй пример, но это отрицает цель использования stream_parser.

Я включил отладку правил в моем локальном примере, и это показывает, чтопользовательский анализатор потребляет все содержимое строки - однако код показывает, что этого делать не следует ...

Любая помощь приветствуется!

Boost 1.44.0, gcc 4.1.1

#include <boost/spirit/include/qi.hpp>

struct complex
{
  complex (double a = 0.0, double b = 0.0) : a(a), b(b) {}
  double a,b;
};

std::istream& operator>> (std::istream& is, complex& z)
{
  char lbrace = '\0', comma = '\0', rbrace = '\0';
  is >> lbrace >> z.a >> comma >> z.b >> rbrace;
  if (lbrace != '{' || comma != ',' || rbrace != '}')
      is.setstate(std::ios_base::failbit);
  return is;
}

int main( int argc, char**argv)
{
  using namespace boost::spirit;
  complex parsedComplex;
  float   parsedFloat;
  bool result;

  std::string str = "{1.0,2.5}";
  std::string::iterator first = str.begin();
  result = qi::phrase_parse(first,str.end(),
    qi::stream_parser<char,complex>(), ascii::blank,parsedComplex);
  assert(result && first==str.end()); // OK

  str = "{1.0,2.5},123.456";
  first = str.begin();
  result = qi::phrase_parse(first,str.end(),
     qi::stream_parser<char,complex>() >> qi::lit(',') >> qi::float_,
     ascii::blank,parsedComplex,parsedFloat);
  assert(result && first==str.end());  // FAILS
}

1 Ответ

5 голосов
/ 26 марта 2011

Это оказалось ошибкой в ​​компоненте потокового парсера. Это не учитывало тот факт, что основной поток std буферизовал входные данные. Проблема исправлена ​​в SVN, и исправление будет частью Boost V1.47. Я добавил новый тест в набор регрессионных тестов Spirit на основе вашего кода - надеюсь, вы не против. Спасибо за сообщение!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...