I have written the following simple grammar to detect if a string returned by a server is a failed login. I was using it inlined in the phrase_parse function, but since the code gets called regularly, I wanted to make a static instance of the grammar. What I was using was this:
bool loginFailed()
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
// current data is an re2 stringpiece. so .data returns char*
const char* front = currentData.data();
const char* back = currentData.end();
return qi::phrase_parse(front, back, -qi::int_ >> (ascii::no_case[qi::lit("no")] | ascii::no_case[qi::lit("bad")]), qi::space);
}
Which works. However, when I translated this to the following, the grammar seems to always fail. What I would like to do is in my cpp file:
namespace {
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
struct FailedGrammar : qi::grammar<const char*>
{
FailedGrammar() :
FailedGrammar::base_type(m_start),
m_start()
{
m_start = -qi::int_ >> (ascii::no_case[qi::lit("no")] | ascii::no_case[qi::lit("bad")]);
}
qi::rule<const char*> m_start;
};
const FailedGrammar s_failedInstance;
}
and then call like this:
bool loginFailed()
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
// current data is an re2 stringpiece. so .data returns char*
const char* front = currentData.data();
const char* back = currentData.end();
return qi::phrase_parse(front, back, s_failedInstance, qi::space);
}
The string I am trying to recognize is something like this:
0002 NO FAILED LOGIN
where the numbers are optional. I am aware of other ways to do this with re2, however, I am looking for a spirit implementation.
Does anyone have any pointers or potential reasons this fails?
Edit:
I found quite a few issues with my grammar just poking around with the debugger. First, I realized to parse a number such as 0002 I should have wrote *(qi::int_). Also, I got rid of the ascii::space in favor of the ascii::blank