Ticket #6050: spirit-transform-attribute-post-bool-v2.diff

File spirit-transform-attribute-post-bool-v2.diff, 9.5 KB (added by oakad@…, 11 years ago)

Patch to allow transform_attribute::post to fail the parser; compared to previous version this will set back the input iterator if conversion fails.

  • home/qi/auxiliary/attr_cast.hpp

    diff -ur spirit.orig/home/qi/auxiliary/attr_cast.hpp spirit/home/qi/auxiliary/attr_cast.hpp
    old new  
    9292
    9393            typename transform::type attr_ = transform::pre(attr);
    9494
    95             if (!compile<qi::domain>(subject).
    96                     parse(first, last, context, skipper, attr_))
     95            Iterator i = first;
     96
     97            if (compile<qi::domain>(subject).
     98                    parse(i, last, context, skipper, attr_))
    9799            {
    98                 transform::fail(attr);
    99                 return false;
     100                // do up-stream transformation, this mainly integrates the results
     101                // back into the original attribute value, if appropriate
     102                if (traits::post_transform(attr, attr_)) {
     103                    first = i;
     104                    return true;
     105                }
    100106            }
    101107
    102             // do up-stream transformation, this mainly integrates the results
    103             // back into the original attribute value, if appropriate
    104             traits::post_transform(attr, attr_);
    105             return true;
     108            transform::fail(attr);
     109            return false;
    106110        }
    107111
    108112        template <typename Context>
  • home/qi/detail/attributes.hpp

    diff -ur spirit.orig/home/qi/detail/attributes.hpp spirit/home/qi/detail/attributes.hpp
    old new  
    2222
    2323        static Transformed pre(Exposed&) { return Transformed(); }
    2424
    25         static void post(Exposed& val, Transformed const& attr)
     25        static bool post(Exposed& val, Transformed const& attr)
    2626        {
    2727            traits::assign_to(attr, val);
     28            return true;
    2829        }
    2930
    3031        // fail() will be called by Qi rule's if the rhs failed parsing
     
    3738    {
    3839        typedef Attribute& type;
    3940        static Attribute& pre(Attribute& val) { return val; }
    40         static void post(Attribute&, Attribute const&) {}
     41        static bool post(Attribute&, Attribute const&) { return true; }
    4142        static void fail(Attribute&) {}
    4243    };
    4344
     
    4748        typedef Transformed type;
    4849
    4950        static Transformed pre(Exposed& val) { return Transformed(val); }
    50         static void post(Exposed&, Transformed const&) { /* no-op */ }
     51        static bool post(Exposed&, Transformed const&) { return true; }
    5152
    5253        // fail() will be called by Qi rule's if the rhs failed parsing
    5354        static void fail(Exposed&) {}
     
    5960    {
    6061        typedef Attribute& type;
    6162        static Attribute& pre(Attribute& val) { return val; }
    62         static void post(Attribute&, Attribute const&) {}
     63        static bool post(Attribute&, Attribute const&) { return true; }
    6364        static void fail(Attribute&) {}
    6465    };
    6566
     
    8788                val = Transformed();
    8889            return boost::get<Transformed>(val);
    8990        }
    90         static void post(boost::optional<Exposed>&, Transformed const&) {}
     91        static bool post(boost::optional<Exposed>&, Transformed const&) { return true; }
    9192        static void fail(boost::optional<Exposed>& val)
    9293        {
    9394             val = none_t();    // leave optional uninitialized if rhs failed
     
    100101    {
    101102        typedef Attribute& type;
    102103        static Attribute& pre(Attribute& val) { return val; }
    103         static void post(Attribute&, Attribute const&) {}
     104        static bool post(Attribute&, Attribute const&) { return true; }
    104105        static void fail(Attribute&) {}
    105106    };
    106107
     
    110111    {
    111112        typedef unused_type type;
    112113        static unused_type pre(unused_type) { return unused; }
    113         static void post(unused_type, unused_type) {}
     114        static bool post(unused_type, unused_type) { return true; }
    114115        static void fail(unused_type) {}
    115116    };
    116117
     
    160161
    161162    ///////////////////////////////////////////////////////////////////////////
    162163    template <typename Exposed, typename Transformed>
    163     void post_transform(Exposed& dest, Transformed const& attr)
     164    bool post_transform(Exposed& dest, Transformed const& attr)
    164165    {
    165166        return transform_attribute<Exposed, Transformed, qi::domain>::post(dest, attr);
    166167    }
  • home/qi/nonterminal/rule.hpp

    diff -ur spirit.orig/home/qi/nonterminal/rule.hpp spirit/home/qi/nonterminal/rule.hpp
    old new  
    285285                // attributes, without passing values for them.
    286286                context_type context(attr_);
    287287
     288                Iterator i = first;
     289
    288290                // If you are seeing a compilation error here stating that the
    289291                // fourth parameter can't be converted to a required target type
    290292                // then you are probably trying to use a rule or a grammar with
    291293                // an incompatible skipper type.
    292                 if (f(first, last, context, skipper))
     294                if (f(i, last, context, skipper))
    293295                {
    294296                    // do up-stream transformation, this integrates the results
    295297                    // back into the original attribute value, if appropriate
    296                     traits::post_transform(attr, attr_);
    297                     return true;
     298                    if (traits::post_transform(attr, attr_)) {
     299                        first = i;
     300                        return true;
     301                    }
    298302                }
    299303
    300304                // inform attribute transformation of failed rhs
     
    331335                // attributes, passing values of incompatible types for them.
    332336                context_type context(attr_, params, caller_context);
    333337
     338                Iterator i = first;
     339
    334340                // If you are seeing a compilation error here stating that the
    335341                // fourth parameter can't be converted to a required target type
    336342                // then you are probably trying to use a rule or a grammar with
    337343                // an incompatible skipper type.
    338                 if (f(first, last, context, skipper))
     344                if (f(i, last, context, skipper))
    339345                {
    340346                    // do up-stream transformation, this integrates the results
    341347                    // back into the original attribute value, if appropriate
    342                     traits::post_transform(attr, attr_);
    343                     return true;
     348                    if (traits::post_transform(attr, attr_)) {
     349                        first = i;
     350                        return true;
     351                    }
    344352                }
    345353
    346354                // inform attribute transformation of failed rhs
  • home/support/adapt_adt_attributes.hpp

    diff -ur spirit.orig/home/support/adapt_adt_attributes.hpp spirit/home/support/adapt_adt_attributes.hpp
    old new  
    257257        {
    258258            return val;
    259259        }
    260         static void
     260        static bool
    261261        post(
    262262            fusion::extension::adt_attribute_proxy<T, N, false>& val
    263263          , Attribute const& attr)
    264264        {
    265265            val = attr;
     266            return true;
    266267        }
    267268        static void
    268269        fail(fusion::extension::adt_attribute_proxy<T, N, false>&)
     
    289290        {
    290291            return val;
    291292        }
    292         static void
     293        static bool
    293294        post(
    294295            fusion::extension::adt_attribute_proxy<T, N, Const>&
    295296          , Attribute const&)
    296297        {
     298            return true;
    297299        }
    298300        static void
    299301        fail(fusion::extension::adt_attribute_proxy<T, N, Const>&)
  • repository/home/qi/nonterminal/subrule.hpp

    diff -ur spirit.orig/repository/home/qi/nonterminal/subrule.hpp spirit/repository/home/qi/nonterminal/subrule.hpp
    old new  
    213213            // without passing values for them.
    214214            context_type context(*this, attr_);
    215215
    216             if (def.binder(first, last, context, skipper))
     216            Iterator i = first;
     217
     218            if (def.binder(i, last, context, skipper))
    217219            {
    218220                // do up-stream transformation, this integrates the results
    219221                // back into the original attribute value, if appropriate
    220                 traits::post_transform(attr, attr_);
    221                 return true;
     222                if (traits::post_transform(attr, attr_)) {
     223                    first = i;
     224                    return true;
     225                }
    222226            }
    223227
    224228            // inform attribute transformation of failed rhs
     
    267271            // passing values of incompatible types for them.
    268272            context_type context(*this, attr_, params, caller_context);
    269273
    270             if (def.binder(first, last, context, skipper))
     274            Iterator i = first;
     275
     276            if (def.binder(i, last, context, skipper))
    271277            {
    272278                // do up-stream transformation, this integrates the results
    273279                // back into the original attribute value, if appropriate
    274                 traits::post_transform(attr, attr_);
    275                 return true;
     280                if (traits::post_transform(attr, attr_)) {
     281                    first = i;
     282                    return true;
     283                }
    276284            }
    277285
    278286            // inform attribute transformation of failed rhs