Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost::Spirit - on_error not printing

I'm trying to use the on_error mechanism of Boost::Spirit::qi to find out why the parsing failed.

I've set a breakpoint at the on_error function and the function is being called, but no output (nada, nothing, void, ...).

The simple on_error:

on_error<fail>(level1,
    boost::phoenix::ref(std::cout) << "I've failed.\n"
    );

The complex on_error (from various sites):

on_error<fail>
(
    start,
    boost::phoenix::ref(std::cout)
        << val("Error! Expecting ")
        << _4
        << val(" here: \"")
        << construct<std::string>(qi::_3, qi::_2)
        << val("\"")
        << std::endl
    );

Here is my class containing the simple on_error:

template <typename Iterator, typename Skipper>
struct Event_Compound
    : qi::grammar<Iterator, Skipper>
{
    Event_Compound () 
        : Event_Compound::base_type(start, "Compound-Event")
        {
            using qi::lexeme;
            using qi::lit;
            using namespace qi;
            using boost::spirit::ascii::char_;

            relational_operator =
                lit("&&")[Matched_Relational_AND]
                || lit("||")[Matched_Relational_OR]
                ;

            compound =
                level1[Matched_Nested_Level1_Begin] >> relational_operator[Matched_Relational_Operator] >> level1[Matched_Nested_Level1_End]
                ;

            compare_or_compound =
                compound[Matched_Compound] | grammar_comparison_event[Matched_Comparison_Event]
                ;

            level1 =
                grammar_boolean_event[Matched_Boolean_Event]
                | ( char_('(')[Matched_Open_Paren] >> compare_or_compound[Matched_Compare_Or] >> char_(')')[Matched_Close_Paren]  )
                ;

            start =
                level1[Matched_Level1_Begin] >> relational_operator[Matched_Relational_Operator] >> level1[Matched_Level1_End]
                ;
            on_error<fail>(level1,
                boost::phoenix::ref(std::cout) << "I've failed.\n"
                );
        }

    Event_Boolean<Iterator, Skipper>        grammar_boolean_event;
    Event_Comparison<Iterator, Skipper>     grammar_comparison_event;
    qi::rule<Iterator, Skipper>             level1;
    qi::rule<Iterator, Skipper>             compound;
    qi::rule<Iterator, Skipper>             compare_or_compound;
    qi::rule<Iterator, Skipper>             relational_operator;
    qi::rule<Iterator, Skipper>             start;
};

Is there a simple method to trace the behavior or thinking pattern of the parser? (Such as setting a preprocessor macro or some flag variable)

Why isn't there any output from the on_error?

Also, what do _1, _2, _3 and _4 reference?

I'm trying to debug a grammar and I have output as to the rules that have been matched, but when a rule isn't matched, I want to know which rule and why.

I'm using:

  • Boost 1.57.0
  • Visual Studio 2010
  • Windows 7

Researched:

like image 274
Thomas Matthews Avatar asked Mar 25 '15 23:03

Thomas Matthews


1 Answers

Error handling only relates to expectation points. You don't seem to have any of those.

  • http://www.boost.org/doc/libs/1_57_0/libs/spirit/doc/html/spirit/qi/reference/operator/expect.html

To debug the grammar use

  • #define BOOST_SPIRIT_DEBUG before any boost includes
  • BOOST_SPIRIT_DEBUG_NODE(node) or BOOST_SPIRIT_DEBUG_NODES((node1)(node2)...) to select nodes for debug

This will show you the backtracking (if any) and attribute propagation in action. If you use them, locals and inherited attributes will also be shown.

Note your rule's attributes need to be fusion-adapted/streamable for debug to work.

like image 62
sehe Avatar answered Sep 25 '22 09:09

sehe