Rui*_*hou 4 c++ boost boost-spirit boost-spirit-qi
我用boost :: spirit :: qi :: rule写了一些语法来解析互联网数据包.语法是这样的:
qi::rule<Iterator> start, request, response, status, query ;
start = (request | response | status | query) >> lit("\r\n");
Run Code Online (Sandbox Code Playgroud)
为了提高性能,用户可能希望跳过运行时中的一些规则,例如忽略"响应","状态","查询"并且只尝试匹配请求,因此规则将更改为:
start = (request ) >> lit("\r\n");
Run Code Online (Sandbox Code Playgroud)
有可能这样做吗?例如,是否有一个像"禁用()"这样的功能来禁用规则"响应","状态"和"查询"?
最自然的方法是在你受限制的场合使用不同的解析器.
此外,如果性能如此重要,您甚至无法进行3或4个额外的字符比较
也就是说,这里有一些选择:
qi::lazy#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
int main()
{
typedef std::string::const_iterator It;
qi::rule<It>
request = "request",
response = "response",
status = "status",
query = "query",
//
allowed;
static qi::rule<It> const start = qi::lazy(phx::ref(allowed)) >> qi::lit("\r\n");
static const auto test = [](std::string const& input) { return qi::parse(begin(input), end(input), start); };
for (int i=0; i<10; ++i)
{
switch(rand()%3)
{
case 0: allowed = request; break;
case 1: allowed = request | response | query; break;
case 2: allowed = request | response | status | query; break;
}
std::cout << "status: " << test("status\r\n") << "\t"
<< "response: " << test("response\r\n") << "\t"
<< "request: " << test("request\r\n") << "\n";
}
}
Run Code Online (Sandbox Code Playgroud)
就像迈克提到的那样,这也用在了Nabialek技巧中,虽然它qi::lazy是这里必不可少的成分.
这打印,例如:
status: 0 response: 1 request: 1
status: 0 response: 1 request: 1
status: 0 response: 0 request: 1
status: 0 response: 1 request: 1
status: 1 response: 1 request: 1
status: 0 response: 1 request: 1
status: 0 response: 1 request: 1
status: 0 response: 0 request: 1
status: 0 response: 0 request: 1
status: 0 response: 1 request: 1
Run Code Online (Sandbox Code Playgroud)
qi::lazy与上面的内容非常类似,您可以将'subrules'作为继承属性传递.我不确定我会推荐这个,因为我在过去的例子中看到了未定义的行为,见例如
qi::lazy本身不支持继承属性在我看来,这是最自然的:
std::function<bool(string)> test;
switch(rand()%3)
{
case 0: test = [&](std::string const& input) { return qi::parse(begin(input), end(input), request); }; break;
case 1: test = [&](std::string const& input) { return qi::parse(begin(input), end(input), request | response | query); }; break;
case 2: test = [&](std::string const& input) { return qi::parse(begin(input), end(input), request | response | status | query); }; break;
}
Run Code Online (Sandbox Code Playgroud)
查看完整示例:http://coliru.stacked-crooked.com/a/603f093add6b9799