Если предполагается, что Integer является атрибутом, предоставляемым правилом, его необходимо объявить как:
qi::rule<Iterator, Integer()> integer;
(обратите внимание на круглые скобки).Spirit требует использовать синтаксис объявления функции для описания «интерфейса» правила.Он используется не только в Spirit, но и несколькими другими библиотеками (см. Например, boost :: function).
Основная причина этого заключается в том, что это хороший лаконичный способ указания интерфейса функции.Если вы думаете о том, что такое правило, вы быстро понимаете, что оно похоже на функцию: оно может возвращать значение (анализируемый результат, то есть синтезированный атрибут).Кроме того, может потребоваться один или несколько аргументов (унаследованных атрибутов).
Вторая, но незначительная причина заключается в том, что Spirit должен уметь различать различные параметры шаблона правила.Параметры шаблона могут быть заданы в любом порядке (кроме итератора), поэтому для его определения нужны какие-то средства.Синтаксис объявления функции достаточно отличается от шкипера или кодировки (два других возможных параметра шаблона), чтобы его можно было распознать во время компиляции.
Давайте посмотрим на ваши различные попытки:
Это можно заставить работать, если вы измените определение правила, как описано выше.
integer = qi::int_[qi::_val = qi::_1];
_val
относится к вашему Integer
, а _1
относится к int
.Поэтому вам нужно определить оператор присваивания из int
, чтобы сделать эту работу:
struct Integer {
int value;
Integer& operator=(int) {...}
};
В этом случае вам не нужно адаптировать ваш тип как последовательность Fusion.
Но вы можете написать это еще проще:
integer = qi::int_ >> qi::eps;
, что эквивалентно 100% (eps - это уловка, используемая для преобразования правой части в последовательность синтаксического анализатора, которая позволяет использовать встроенное распространение атрибутовотображение элементов вашей адаптированной последовательности Fusion на атрибуты элементов последовательности).
Это:
integer = qi::int_[qi::_r1 = qi::_1];
не будет работать, так как _r1
ссылается на первый унаследованный атрибутправило.Однако ваше правило не имеет наследуемых атрибутов.
Это будет работать:
integer = qi::int_[phoenix::bind(&Integer::value, qi::_val) = qi::_1];
, но не требует адаптации вашего типа в качестве последовательности Fusion.
И так будетэто:
integer = qi::int_[phoenix::at_c<0>(qi::_val) = qi::_1];