Re: setting attribute value from on_error handler

Kent Hauser <[email protected]>
Newsgroups gmane.comp.parsers.spirit.general
Message-ID <[email protected]>
Here is an example of what I’m seeing. 

I’m setting an “on_error” handler on the `top` rule. It is only entered when I use the `expectation parser` in the `element` rule.

My naive expectation of `on_error` is that it’s called for the rule it’s attached to. This I expected `x3::_val` to reference the attribute for `top`. I also expected it to be entered for all parse failures, not just `expectation failures`. 

The program output is as follows:

./on_error
expect: 1 2 -1 4
output: 1 2 2 4

Thanks.

=========================================
#include <iostream>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>

namespace x3 = boost::spirit::x3;
using namespace x3;

using var_t = int;
// using var_t = x3::variant<int>;

rule<struct elemnent, var_t> const element_p = "element_p";
rule<struct top, var_t> const top_p = "top_p";

auto const element_p_def = int_ > ',';
auto const top_p_def = element_p;
auto const resync = *(char_ - ',') >> ',';

BOOST_SPIRIT_DEFINE(element_p, top_p)

struct top {
    template <typename Iterator, typename Exception, typename Context>
    auto on_error(Iterator& first , Iterator const& last
                , Exception const& x, Context const& context)
    {
        x3::_val(context) = -1;
        parse(first, last, resync);
        return error_handler_result::accept;
    }
};

int main() {
    std::string input = "1, 2, 3 x, 4, ";


    auto first = input.begin();
    auto last  = input.end();
    var_t  v {};

    std::cout << "expect: 1 2 -1 4 " << std::endl;
    std::cout << "output: ";

    while (first != last) {
        auto before = first;
        if (phrase_parse(first, last, top_p, space, v)) {
            // std::cout << boost::get<int>(v) << " ";
            std::cout << v << " ";
        } else {
            std::cout << "\nParse failed: remaining input = \"" << std::string(first, last) << "\"";
            break;
        }
        if (first == before) {
            std::cout << "\nNo input consumed!";
            break;
        }
    }
    std::cout << std::endl;
}
=========================================

On April 6, 2016 at 7:35:44 PM, Joel de Guzman ([email protected]) wrote:

On 07/04/2016 5:57 AM, Kent Hauser wrote:
> That’s what I tried, but with no luck. I can print my “ast” in the `on_error` handler,
> assign it `x3::_val(context) = ast`, but
> the `ast` from the previous iteration of the `parse_phrase` loop is what I see in the
> application code.
>
> For what it’s worth, I also update `first` with a resync parser & that works great.

Please (minimal) post some code for us to see what's going on.

Regards,
--
Joel de Guzman
http://www.ciere.com
http://boost-spirit.com
http://www.cycfi.com/


------------------------------------------------------------------------------
_______________________________________________
Spirit-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spirit-general

------------------------------------------------------------------------------

_______________________________________________
Spirit-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spirit-general
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.