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