Given semantic actor
template<typename ValueType>
class divide
{
public:
divide(ValueType value) : divisor{value} {}
template<typename ContextType>
void operator()(ContextType& context) const
{
_val(context) /= divisor;
}
private:
const ValueType divisor;
};
it seems I'm hitting the fact that the presence of semantic actions inhibit attribute synthesis (or propagation?), i.e.
const auto norm = x3::rule<struct _, double>{"norm"}
= x3::double_[normalize{100.}];
gives me the value 0.
So I tried forcing attribute propagation by using %=
const auto norm_rule = x3::rule<struct _, double>{"norm"}
%= x3::double_[normalize{100.}];
This gives me the expected parsed value divided by 100.
Then I discovered x3::rule
has a third template argument, bool force_attribute
, and noticed that
const auto norm_rule = x3::rule<struct _, double, true>{"norm"}
= x3::double_[divide{100.}];
Has the wanted result of the value divided by 100.
Experimenting further, I also discovered I could instead define divide::operator()
as follows:
void operator()(ContextType& context)
{
_attr(context) = _val(context) / divisor;
}
This last one seems to strongly couple/condemn the semantic actor to a rule's top level, as it acts on the attribute _attr
of the first rule instead of the value _val
of a parser to which it is attached.
Am I correct in my deduction that
%=
is the same as setting the thirdx3::rule
template parameterforce_attribute
to true?- This type of value-processing semantic actions should exclusively work on
_val
so they work on the attached parser instead of the firstrule
encountered in the hierarchy?
I understand these may seem lie unrelated questions, but they really are connected as I'm trying to process a parsed number (float) and transform it into an uint8 in several ways. To be totally complete: I have working code (numeric stuff here and the actual thing I'm constructing/parsing here), but it seems needlessly complex (due to the above it seems I need a rule per type/value transformation, which seems silly.