Вы видели, что<double_
>парсер имеет атрибут<double
>. Все парсеры имеют атрибут, даже сложные парсеры. Те, которые составлены из примитивов, использующих операторы, такие как парсер списка, также имеют атрибут. Бывает так, что атрибут списка парсер:
p % d
<std::vector
>является одним из атрибутов<p
>. Итак, для нашего парсера:
double_ % ','
У нас будет атрибут:
std::vector<double>
So, what does this give us? Well, we can simply pass in a std::vector<double>
to our number list parser and it will happily churn out our result in our
vector. For that to happen, we'll use a variation of the phrase_parse
with an additional argument:
the parser's attribute. With the following arguments passed to phrase_parse
- Итератор, указывающий на начало ввода
- Итератор, указывающий на один прошедший конец входа
- Объект парсера
- Еще один парсер называется скип парсер
- Атрибут парсера
Теперь наш парсер упрощен до:
template <typename Iterator>
bool parse_numbers(Iterator first, Iterator last, std::vector<double>& v)
{
using qi::double_;
using qi::phrase_parse;
using qi::_1;
using ascii::space;
bool r = phrase_parse(first, last,
(
double_ % ','
)
,
space, v);
if (first != last)
return false;
return r;
}
The full cpp file for this example can be found here: ../../example/qi/num_list4.cpp
Эй, больше никаких действий!!!Теперь мы входим в область грамматики атрибутов. Круто, да?