Атрибут, предоставляемый вашим правилом запуска, - unsigned
, тогда как анализатор плюсов предоставляет тип контейнера, содержащий атрибуты обернутых элементов.Вот правила распространения атрибутов из документов :
a: A --> +a: vector<A>
(т. Е. Если синтаксический анализатор a
предоставляет атрибут типа A
, анализатор +a
предоставит(стандартный) контейнер, содержащий экземпляры A
, например std::vector<A>
).
В вашем случае встроенный анализатор предоставляет double
.По этой причине вам нужно изменить код, чтобы он работал должным образом:
template <typename Iterator>
struct input : qi::grammar<Iterator, std::vector<double>()>
{
input() : input::base_type(start)
{
using qi::lit;
using qi::double_;
start = lit("ADD") >> +(+lit(" ") >> double_ >> +lit(" ") >> double_);
}
qi::rule<Iterator, std::vector<double>()> start;
};
int main()
{
input<std::string::const_iterator> input_parser; // Our grammar
std::string str = "ADD 1132.324 2342.234";
std::vector<double> result;
std::string::const_iterator iter = str.begin();
std::string::const_iterator end = str.end();
bool r = qi::parse(iter, end, input_parser, result);
}
Но, к сожалению, все не так просто, как кажется.В текущей версии Spirit есть ошибка, препятствующая работе кода (даже в скором выпуске Boost V1.46 эта ошибка все еще будет присутствовать, но она исправлена в соединительной линии SVN).Проблема заключается в том, что plus не «сглаживает» встроенные элементы в предоставленном контейнере, что приводит к потере каждой второй двойной переменной, проанализированной приведенным выше кодом.
Обходной путь - избегать последовательностей, раскрывающих более одного атрибутаinside plus:
start = lit("ADD") >> +(+lit(" ") >> double_);
проверка впоследствии того, что количество проанализированных элементов было четным.
Примечание: вы, кажется, хотите пропустить пробелы между элементами на входе.Этого можно добиться проще, используя парсер пропуска:
template <typename Iterator>
struct input : qi::grammar<Iterator, std::vector<double>(), qi::space_type>
{
input() : input::base_type(start)
{
using qi::lit;
using qi::double_;
start = lit("ADD") >> +double_;
}
qi::rule<Iterator, std::vector<double>(), qi::space_type> start;
};
int main()
{
input<std::string::const_iterator> input_parser; // Our grammar
std::string str = "ADD 1132.324 2342.234";
std::vector<double> result;
std::string::const_iterator iter = str.begin();
std::string::const_iterator end = str.end();
bool r = qi::phrase_parse(iter, end, input_parser, qi::space, result);
}
, который в то же время обходит проблему, описанную выше.