Created
March 6, 2019 05:53
-
-
Save cppljevans/e1fa1f6a0ebfda6bea8ae0ec1c823e41 to your computer and use it in GitHub Desktop.
Joel's suggested changes (and a little more)
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 characters
//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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment