[boost/spirit] numeric policy
I've had the case where I needed to retain formatting information for a number (general, fixed, scientific) and was nicely accomplished by extending the policy, but needed to have a begin_parse() and end_parse() for the policy to be complete. It seems that it makes some sense or is this accomplished another way? Maybe something to consider for policies in general? Index: qi/numeric/real_policies.hpp =================================================================== --- qi/numeric/real_policies.hpp (revision 85166) +++ qi/numeric/real_policies.hpp (working copy) @@ -28,6 +28,18 @@ static bool const allow_trailing_dot = true; static bool const expect_dot = false; + template <typename Attribute> + static void + begin_parse(Attribute& attr_) + { + } + + template <typename Attribute> + static void + end_parse(Attribute& attr_,bool /* result */) + { + } + template <typename Iterator> static bool parse_sign(Iterator& /*first*/, Iterator const& /*last*/) Index: qi/numeric/detail/real_impl.hpp =================================================================== --- qi/numeric/detail/real_impl.hpp (revision 85166) +++ qi/numeric/detail/real_impl.hpp (working copy) @@ -133,6 +133,7 @@ parse(Iterator& first, Iterator const& last, Attribute& attr, RealPolicies const& p) { + p.begin_parse(attr); if (first == last) return false; Iterator save = first; @@ -257,6 +258,7 @@ // If we got a negative sign, negate the number traits::assign_to(traits::negate(neg, n), attr); + p.end_parse(attr, true); // maybe this should return a bool and be the return value? // Success!!! return true; }
On 31/07/2013 01:37 p.m., Brian Schrom wrote:
I've had the case where I needed to retain formatting information for a number (general, fixed, scientific) and was nicely accomplished by extending the policy, but needed to have a begin_parse() and end_parse() for the policy to be complete. It seems that it makes some sense or is this accomplished another way? Maybe something to consider for policies in general?
I am currently reviewing the policies design for Spirit X3, and I'm tempted to add a `parse` entry-point that drives the entire parsing operation. I have found that sometimes you need this, as otherwise one has to jump through hoops in a not so clean way. In this scenario, the parsing operation could be wrapped in pre/post calls and then forward to the default implementation. For Spirit V2, policies are not required to inherit from the default ones, so any change to them is potentially a breaking change. Although I have yet to see a case where this would happen. If you think this approach would work for your use case and you want to try and make the necessary source and documentation changes, I will be happy to help you through the process. Regards, -- Agustín K-ballo Bergé.- http://talesofcpp.fusionfenix.com
On 07/31/2013 10:03 PM, Agustín K-ballo Bergé wrote:
... For Spirit V2, policies are not required to inherit from the default ones, so any change to them is potentially a breaking change. Although I have yet to see a case where this would happen. If you think this approach would work for your use case and you want to try and make the necessary source and documentation changes, I will be happy to help you through the process.
Thank you. The patch (against svn trunk as of 2013-08-01) I have so far is quite small, so I in-lined it below. Without knowing a whole lot more about Spirit, this is my best guess for the files that would need changing. I built the resultant quickbook and ran the spirit unit tests, though some are failing trunk on my gcc version 4.7.3 setup, but appear to be unrelated to this change. I'm still not 100% sure that this is a proper approach to the problem. For instance, maybe the policy should be initializing the value, and that is incorporated into the begin/init or separate. If you feel that this approach is appropriate, I can do some small additional changes to conform to the code base properly if I know what they are. If there is substantial effort to get where it needs to be, it is probably not worth your time right now and the patch can be archived in the mailing list if it's useful for a later time. Regards, Brian Index: libs/spirit/doc/qi/numeric.qbk =================================================================== --- libs/spirit/doc/qi/numeric.qbk (revision 85183) +++ libs/spirit/doc/qi/numeric.qbk (working copy) @@ -765,6 +765,7 @@ [table [[Expression] [Semantics]] + [[`RP::begin(n)`] [Allows the policy to initialize]] [[`RP::allow_leading_dot`] [Allow leading dot.]] [[`RP::allow_trailing_dot`] [Allow trailing dot.]] [[`RP::expect_dot`] [Require a dot.]] @@ -789,6 +790,8 @@ [[`RP::parse_inf(f, l, n)`] [Parse an Inf. Return `true` if successful, otherwise `false`. If successful, place the result into `n`.]] + [[`RP::end(n,b)`] [Allows the policy to finalize, b is result of parsing. + Return `true` if successful, otherwise `false`.]] ] The `parse_nan` and `parse_inf` functions get called whenever: Index: boost/spirit/home/qi/numeric/detail/real_impl.hpp =================================================================== --- boost/spirit/home/qi/numeric/detail/real_impl.hpp (revision 85183) +++ boost/spirit/home/qi/numeric/detail/real_impl.hpp (working copy) @@ -133,6 +133,7 @@ parse(Iterator& first, Iterator const& last, Attribute& attr, RealPolicies const& p) { + p.begin(attr); if (first == last) return false; Iterator save = first; @@ -258,7 +259,7 @@ traits::assign_to(traits::negate(neg, n), attr); // Success!!! - return true; + return p.end(attr, true); } }; Index: boost/spirit/home/qi/numeric/real_policies.hpp =================================================================== --- boost/spirit/home/qi/numeric/real_policies.hpp (revision 85183) +++ boost/spirit/home/qi/numeric/real_policies.hpp (working copy) @@ -28,6 +28,13 @@ static bool const allow_trailing_dot = true; static bool const expect_dot = false; + // Do any initialization of attr that is needed + template <typename Attribute> + static void + begin(Attribute& attr_) + { + } + template <typename Iterator> static bool parse_sign(Iterator& /*first*/, Iterator const& /*last*/) @@ -154,6 +161,14 @@ } return false; } + + // Do any finalization of attr that is needed + template <typename Attribute> + static bool + end(Attribute& attr_,bool result) + { + return result; + } }; ///////////////////////////////////////////////////////////////////////////
[Please do not mail me a copy of your followup] boost@lists.boost.org spake the secret code <51FAD2C7.5060609@pnnl.gov> thusly:
Thank you. The patch (against svn trunk as of 2013-08-01) I have so far is quite small, so I in-lined it below. Without knowing a whole lot more about Spirit, this is my best guess for the files that would need changing.
Brian, whatever you're using to nicely right-justify your messages as above is reformatting your patch which makes it rather useless:
If successful, place the result into `n`.]] + [[`RP::end(n,b)`] [Allows the policy to finalize, b is result of parsing. + Return `true` if successful, otherwise `false`.]] ]
etc. FYI. -- "The Direct3D Graphics Pipeline" free book http://tinyurl.com/d3d-pipeline The Computer Graphics Museum http://computergraphicsmuseum.org The Terminals Wiki http://terminals.classiccmp.org Legalize Adulthood! (my blog) http://legalizeadulthood.wordpress.com
On 08/07/2013 11:28 AM, Richard wrote:
Brian, whatever you're using to nicely right-justify your messages as above is reformatting your patch which makes it rather useless:
Thank you for letting me know. Patch attached. The same caveats as I had before: Thank you. The patch (against svn trunk as of 2013-08-01) I have so far is quite small, so I in-lined it below. Without knowing a whole lot more about Spirit, this is my best guess for the files that would need changing. I built the resultant quickbook and ran the spirit unit tests, though some are failing trunk on my gcc version 4.7.3 setup, but appear to be unrelated to this change. I'm still not 100% sure that this is a proper approach to the problem. For instance, maybe the policy should be initializing the value, and that is incorporated into the begin/init or separate. If you feel that this approach is appropriate, I can do some small additional changes to conform to the code base properly if I know what they are. If there is substantial effort to get where it needs to be, it is probably not worth your time right now and the patch can be archived in the mailing list if it's useful for a later time. Brian
On 07/08/2013 04:23 p.m., Brian Schrom wrote:
On 08/07/2013 11:28 AM, Richard wrote:
Brian, whatever you're using to nicely right-justify your messages as above is reformatting your patch which makes it rather useless:
Thank you for letting me know. Patch attached.
If you feel that this approach is appropriate, I can do some small additional changes to conform to the code base properly if I know what they are. If there is substantial effort to get where it needs to be, it is probably not worth your time right now and the patch can be archived in the mailing list if it's useful for a later time.
I'm thinking there should be a parse_fail customization point as well, or otherwise a way to react when parsing fails. It would help to know what your specific use case for this extensions is. Regards, -- Agustín K-ballo Bergé.- http://talesofcpp.fusionfenix.com
On 08/07/2013 02:52 PM, Agustín K-ballo Bergé wrote:
I'm thinking there should be a parse_fail customization point as well, or otherwise a way to react when parsing fails. It would help to know what your specific use case for this extensions is. Regards,
My use case is that I convert a .csv file to an Excel file and need to set the cell number format to that found in the .csv file, namely, FIXED, SCIENTIFIC, or GENERAL. There is a FormatNumber class that contains a number with formatting meta data. The contents of the meta data depend upon what part of the number parsing succeeds or fails. I.e., if there is an 'e' or 'E', then it's SCIENTIFIC. If there is a '.', then it may be in fixed format, etc.
On 07/08/2013 04:23 p.m., Brian Schrom wrote:
On 08/07/2013 11:28 AM, Richard wrote:
Brian, whatever you're using to nicely right-justify your messages as above is reformatting your patch which makes it rather useless:
Thank you for letting me know. Patch attached.
If you feel that this approach is appropriate, I can do some small additional changes to conform to the code base properly if I know what they are. If there is substantial effort to get where it needs to be, it is probably not worth your time right now and the patch can be archived in the mailing list if it's useful for a later time.
I'm thinking there should be a parse_fail customization point as well, or otherwise a way to react when parsing fails. It would help to know what your specific use case for this extensions is.
FWIW, there is already a customization point used by rules and attr_cast, not sure if it's usable in this case, though. Regards Hartmut --------------- http://boost-spirit.com http://stellar.cct.lsu.edu
participants (4)
-
Agustín K-ballo Bergé
-
Brian Schrom
-
Hartmut Kaiser
-
legalize+jeeves@mail.xmission.com