Boost::Spirit - on_error not printing
Asked Answered
P

1

7

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:

Preempt answered 25/3, 2015 at 23:34 Comment(0)
P
4

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

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.

Porcelain answered 26/3, 2015 at 8:5 Comment(2)
(About the debug macros, I have numerous answers in tag boost-spirit that shows how to use it, in case you want samples)Porcelain
The debug macros were more helpful than the error handling. I wish they would put the macros into the tutorial. :-)Preempt

© 2022 - 2024 — McMap. All rights reserved.