Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

X3: expectation operator ">" with semantic rule "[]" expectation_failure<> uses managled name #777

Open
mechapede opened this issue Nov 23, 2023 · 0 comments

Comments

@mechapede
Copy link

The expectation_failure<> failure in Spirit X3 which() function uses the mangled name when semantic actions are used. The minimal example folows below:

#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>

#include <iostream>
#include <string>


// if add a get_info struct for semantic actions then get expected token
#if 0

namespace boost::spirit::x3 {
    template <typename Derived, typename Action>
    struct get_info<action<Derived, Action>>
    {
        typedef std::string result_type;
        std::string operator()(action<Derived, Action> const& p) const
        {
            return get_info<Derived>()(p.subject);
        }
    };
}

#endif


// Simple program to demonstrate expectation behavior with semantic actions
int main() {
    namespace x3 = boost::spirit::x3;

    using boost::spirit::x3::ascii::space;
    typedef std::string::const_iterator iterator_type;

    // invalid input to cause expect to fail
    std::string input = "aabb";

    // expect alone will print char as expected
    {
        auto iter = input.begin();
        auto const end = input.end();
        try {
            bool r = x3::phrase_parse(iter, end, 
                // begin gramar
                (
                    x3::char_('a') > x3::char_('b')
                )
                ,
                // end gramar
            space);

        } catch (x3::expectation_failure<std::string::iterator> const& x) {
            // catch and print the error object
            std::cout << "Which :" << x.which() << std::endl;
        }
    }

    // expect with semantic action print mangled name
    {
        auto semantic_action = [](auto &ctx) {};
        auto iter = input.begin();
        auto const end = input.end();
        try {
            bool r = x3::phrase_parse(iter, end, 
                // begin gramar
                (
                    x3::char_('a') > x3::char_('b')[semantic_action]
                )
                ,
                // end gramar
            space);

        } catch (x3::expectation_failure<std::string::iterator> const& x) {
            // catch and print the error object
            std::cout << "Which with semantic: " << x.which() << std::endl;
        }
    }

    return 0;
}

Which outputs the following results:

Which :'b'
Which with semantic: N5boost6spirit2x36actionINS1_12literal_charINS0_13char_encoding8standardEcEEZ4mainEUlRT_E_EE

If enable the code block above by chaning to #if 1 to enable:

namespace boost::spirit::x3 {
    template <typename Derived, typename Action>
    struct get_info<action<Derived, Action>>
    {
        typedef std::string result_type;
        std::string operator()(action<Derived, Action> const& p) const
        {
            return get_info<Derived>()(p.subject);
        }
    };
}

It adds get_info for semantic actions that will print the info for underlying action which is what I expected originally:

Which :'b'
Which with semantic: 'b'

I wonder if the X3 library should already include this get_info<> specialization or if this causes issues with other use cases?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant