Грамматический анализ с Духом :: Ци не удается

Я новичок в Spirit :: Qi и пытаюсь написать простой парсер Wavefront Obj. Я следовал инструкциям на сайте документации Boost :: Spirit (ссылка на сайт) и я получил большинство действующих правил. Я начал экспериментировать с грамматиками, но я не могу заставить их работать. Через некоторое время я получил его для компиляции, но синтаксический анализ не удается. Я действительно не знаю, что я делаю неправильно.

Для начала я создал простой текстовый файл, содержащий следующее:

v  -1.5701 33.8087 0.3592
v  -24.0119 0.0050 21.7439
v  20.8717 0.0050 21.7439
v  20.8717 0.0050 -21.0255
v  -24.0119 0.0050 -21.0255
v  -1.5701 0.0050 0.3592

Просто чтобы быть уверенным: чтение входного файла работает нормально.

Я написал небольшую функцию, которая должна анализировать входную строку, но по какой-то причине она не работает:

bool Model::parseObj( std::string &data, std::vector<float> &v )
{
struct objGram : qi::grammar<std::string::const_iterator, float()>
{
objGram() : objGram::base_type(vertex)
{
vertex = 'v' >> qi::float_
>> qi::float_
>> qi::float_;
}

qi::rule<std::string::const_iterator, float()> vertex;
};

objGram grammar;

return qi::phrase_parse( data.cbegin(), data.cend(),
grammar, iso8859::space, v );
}

qi :: фразу_parse продолжает возвращать false, а std :: vector v в конце все еще пусто …

Какие-либо предложения?

РЕДАКТИРОВАТЬ:

После добавления пробелов (это правильное имя?), Только первый ‘v’ добавляется к std :: vector, закодированному как float (118.0f), но фактические числа не добавляются. Я думаю, что мое правило не правильно. Я хочу только добавить цифры и пропустить буквы.

Вот моя измененная функция:

bool Model::parseObj( std::string &data, std::vector<float> &v )
{
struct objGram : qi::grammar<std::string::const_iterator, float(), iso8859::space_type>
{
objGram() : objGram::base_type(vertex)
{
vertex = qi::char_('v') >> qi::float_
>> qi::float_
>> qi::float_;
}

qi::rule<std::string::const_iterator, float(), iso8859::space_type> vertex;
} objGrammar;

return qi::phrase_parse( data.cbegin(), data.cend(),
objGrammar, iso8859::space, v );
}

2

Решение

Ваше правило объявляет неверный выставленный атрибут. Измени это:

qi::rule<std::string::const_iterator, std::vector<float>(), iso8859::space_type> vertex;

Однако, поскольку вы не шаблонируете свою грамматическую структуру ни на чем (например, итератор / шкипер), нет смысла иметь грамматическую структуру. Вместо этого пусть phrase_parse просто выведите типы итератора, шкипера и правила одновременно и напишите:

bool parseObj(std::string const& data, std::vector<float> &v )
{
return qi::phrase_parse(
data.cbegin(), data.cend(),
'v' >> qi::float_ >> qi::float_ >> qi::float_,
qi::space, v);
}

Я думаю, вы согласитесь, что это более важно. И в качестве бонуса, он «просто работает» (ТМ) из-за удивительности, которая автоматическое распространение атрибутов правила.

Однако, увидев свою грамматику, вы наверняка захотите увидеть это:

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]