Created
March 6, 2019 05:53
Revisions
-
cppljevans created this gist
Mar 6, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,124 @@ //Purpose: // Follow Joel's suggestion about changing the // xform_rule attribute to double expressed here: // https://github.com/boostorg/spirit/issues/459#issuecomment-469476231 //Result: // **SAME** result when defined(CALL_RULE_DEFINITION_SPECIALIZATION). // IOW, the wrong value for `attr_rule`. Without this define, // the results are as expected, i.e. `attr_rule` == 1235. // However, that's because, **behind the scenes**, spirit is // making a redundant (i.e. useless) call to the default // transform which is a no-op. The key word here is **useless**. // If something is useless, it should be removed. Of course there is // a use-case where the transform is needed, i.e. when a rule_definition // is the argument to x3::parse; however, that case is handled // by moving the transform from call_rule_definition to rule_definition::parse. // IOW, the same place it occurs in rule::parse. Is there a problem with that move // as implmeneted in PR#479? //======== #include <iostream> #include <boost/spirit/home/x3.hpp> namespace x3=boost::spirit::x3; using xform_attr=double; using parse_attr=int; namespace boost { namespace spirit { namespace x3 { //The end-user **does** expect this to be used //because the call to x3::parse **does** use //Exposed (i.e. parse_attr) as the type of the attr argument. template <> struct transform_attribute < parse_attr//Exposed , xform_attr//Transformed > { typedef parse_attr Exposed; typedef xform_attr Transformed; typedef Transformed type; static type pre(Exposed&exposed) { return 3000; } static void post(Exposed& val, type&& transformed) { val=transformed+1;//non-default transform std::cout<<"<parse_attr,xform_attr>::val="<<val<<"\n"; } }; #define CALL_RULE_DEFINITION_SPECIALIZATION #ifdef CALL_RULE_DEFINITION_SPECIALIZATION //The end-user does **not** expect this to be used //because the call to x3::parse does **not** use //Exposed(i.e. xform_attr) as the type of the attr argument. // //**Yet, with the current develop branch, it **is** used //in call_rule_definition **when** it's called from //rule::parse. // //Let's call this an "ill-use" of transform_attribute. // template <> struct transform_attribute < xform_attr//Exposed , xform_attr//Transformed > { typedef xform_attr Exposed; typedef xform_attr Transformed; typedef xform_attr& type; static type pre(Exposed&exposed) { return exposed; } static void post(Exposed& val, Transformed const& transformed) { val=transformed+1;//non-default transform std::cout<<"<xform_attr,xform_attr>::val="<<val<<"\n"; } }; #endif//CALL_RULE_DEFINITION_SPECIALIZATION }}} auto xform_rule_def=x3::int_; x3::rule<class xform_rule_id,xform_attr> xform_rule="xform_rule"; BOOST_SPIRIT_DEFINE(xform_rule) int main() { std::string input_str="1234"; using iter_t=std::string::iterator; iter_t const first=input_str.begin(); iter_t const last=input_str.end(); //#define USE_DEFN #ifdef USE_DEFN parse_attr attr_defn=1000; bool result_defn= x3::parse ( first , last , xform_rule = xform_rule_def //only 1 transform , attr_defn ); std::cout<<"result_defn="<<result_defn<<":attr_defn="<<attr_defn<<"\n"; #endif #define USE_RULE #ifdef USE_RULE parse_attr attr_rule=2000; bool result_rule= x3::parse ( first , last , xform_rule //2 transforms with develop branch , attr_rule ); //attr_defn should be same as attr_rule: std::cout<<"result_rule="<<result_rule<<":attr_rule="<<attr_rule<<"\n"; #endif return 0; }