C++ Boost Spirit语法检测登录失败
我编写了以下简单语法来检测服务器返回的字符串是否是失败的登录。我在C++ Boost Spirit语法检测登录失败,c++,parsing,boost,boost-spirit,boost-spirit-qi,C++,Parsing,Boost,Boost Spirit,Boost Spirit Qi,我编写了以下简单语法来检测服务器返回的字符串是否是失败的登录。我在phrase\u parse函数中内联使用它,但是由于代码会定期被调用,我想创建一个语法的静态实例。我使用的是: bool loginFailed() { namespace qi = boost::spirit::qi; namespace ascii = boost::spirit::ascii; // current data is an re2 stringpiece. so .data ret
phrase\u parse
函数中内联使用它,但是由于代码会定期被调用,我想创建一个语法的静态实例。我使用的是:
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);
}
这很有效。然而,当我把它翻译成以下内容时,语法似乎总是失败。我想做的是在我的cpp文件中:
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;
}
我试图识别的字符串如下所示:
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);
}
0002 NO FAILED LOGIN
其中数字是可选的。我知道用re2实现这一点的其他方法,但是,我正在寻找一种精神实现
是否有人对此有任何建议或潜在原因
编辑:
我发现我的语法有很多问题,只是随便用调试器。首先,我意识到要解析一个像0002这样的数字,我应该写
*(qi::int \)
。另外,我去掉了ascii::space
,取而代之的是ascii::blank
您的第一个版本使用了一个skipper
你的第二个没有。您可以修复它:
>P/>“我意识到解析一个数字,如0002我应该写*(Q::ItIn)”-如果数字不是可选的,也可以使用<代码> Qu::uTung<<代码>或<代码> +Q::数字< /代码>或者甚至<代码>重复(4)[数字] < /代码>空白上的好思考。我差点就要提出来了,但我对你的“语法”一无所知,也不想给你一个非常详细的答案!谢谢
struct FailedGrammar : qi::grammar<const char*, qi::space_type>
{
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*, qi::space_type> m_start;
};
#include <boost/spirit/include/qi.hpp>
#include <boost/utility/string_ref.hpp>
namespace login_detection {
using namespace boost::spirit::qi;
static const rule<const char*> s_failed = skip(space) [ no_case [ -int_ >> lit("no") | "bad" ] ];
}
bool loginFailed2(boost::string_ref response) {
return parse(response.begin(), response.end(), login_detection::s_failed);
}
int main() {
return loginFailed2("0002 NO FAILED LOGIN")? 1 : 2;
}
bool loginFailed2(boost::string_ref response) {
using namespace boost::spirit::qi;
static const rule<const char*> s_failed = skip(space) [ no_case [ -int_ >> lit("no") | "bad" ] ];
return parse(response.begin(), response.end(), s_failed);
}
bool loginFailed2(boost::string_ref response) {
using namespace boost::spirit::qi;
return phrase_parse(response.begin(), response.end(), no_case [ -int_ >> lit("no") | "bad" ], space);
}