Повышение духа 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);
Наконец, обратите внимание, что побочные эффекты семантических действий никогда не могут быть отменены в случае возврата. Смотрите также: