Повышение духа istream итератор дает ложные срабатывания

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

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

#include "StdAfx.h"
#include "Interpreter.h"
#include "Rosters_Grammar.h"
#include <boost\spirit\include\qi.hpp>
#include <fstream>

bool Interpreter::invoke(std::string path)
{
  //Define our parser type and iterator types.
  typedef boost::spirit::istream_iterator iter_type;
  typedef Rosters_Grammar<iter_type> parser_type;

  //Create an instance of our grammar parser and pass it an appropriate project.
  parser_type grammar_parser(project);

  //Open the target file and wrap ifstream into the iterator.
  std::ifstream in = std::ifstream(path);
  if(in.is_open()){

    //Disable Whitespace Skipping
    in.unsetf(std::ios::skipws);

    iter_type begin(in);
    iter_type end;

    //Phrase parse the grammar
    return boost::spirit::qi::phrase_parse(begin,
                                             end, 
                                       qi::int_ , 
                                       boost::spirit::qi::space);
  }
  else{
    return false;
  }
}

Проблема, которая возникает, состоит в том, что мой анализ ВСЕГДА удался по какой-то причине. Учитывая реестр грамматики, я могу сказать, что он читает часть ввода, потому что он выполняет соответствующие действия и работает точно так, как ожидается для правильного ввода. Однако синтаксический анализатор не дает сбоя при неправильном вводе, он просто останавливает часть файла и возвращает true.

Мое текущее содержимое файла является повторением целых и строк, так что

45 бри 23 масляных скотча

Должно быть прочитано хорошо и принято. Строки, как

"45 яблоко яблоко яблоко"

не должно быть. Однако, учитывая это укус, парсер должен потерпеть неудачу. Вместо этого он выполняет действия для "45 Apple", а затем возвращает истину для разбора. Я думаю, что-то с моими итераторами, но я не уверен. В приведенном выше коде я использую qi:: int_ в качестве парсера, и он всегда успешно выполняется независимо от моих входных данных. Поэтому я не верю, что мой файл грамматики не должен относиться к проблеме здесь. До сих пор я получал сбой данных только с помощью! Qi:: eps в качестве ввода моего парсера.

Спасибо за любую помощь, кто-нибудь может мне дать!

РЕДАКТИРОВАТЬ: После более подробного изучения я думаю, что мой шкипер по какой-то причине является проблемой. Насколько я понимаю, в фразу_parse передаются 2 итератора, какая-то грамматика и анализатор пропуска. Он токенизирует входные данные, основанные на парсере пропуска, и использует эти токены в грамматике.

Без отключения пропуска пробелов для типа итератора, мой результат анализирует "45 appleappleapple", и с ним это удается только с "45 apple".

1 ответ

Решение

Мы не видим грамматику, потому что вы ее не опубликовали.

Я вижу, что вы не проверяете, был ли вход полностью израсходован:

    return boost::spirit::qi::phrase_parse(
           begin, end,
           grammar_parser ,
           qi::space);

Вы можете исправить это, либо потребовав qi::eoi:

    return boost::spirit::qi::phrase_parse(
           begin, end,
           grammar_parser >> qi::eoi,
           qi::space);

Или вы можете проверить итераторы:

    bool ok = boost::spirit::qi::phrase_parse(
           begin, end,
           grammar_parser ,
           qi::space);

    if (begin != end)
        std::cerr << "Remaining unparsed: '" << std::string(begin, end) << "'\n";

    return ok && (begin == end);

Наконец, обратите внимание, что побочные эффекты семантических действий никогда не могут быть отменены в случае возврата. Смотрите также:

Другие вопросы по тегам