最自然的方法是在更受限制的情况下使用不同的解析器。
此外,如果性能如此重要以至于您甚至无法进行 3 或 4 个额外的字符比较
也就是说,这里有一些选项:
1.使用可变规则通过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";
}
}
就像迈克提到的那样,这也用于纳比亚莱克技巧,尽管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
2.使用继承的属性qi::lazy
与上面非常相似,您可以将“子规则”作为继承属性传递。我不确定我是否会推荐这个,因为我在过去的示例中看到了未定义的行为,请参见例如
3. 使用单独的规则
在我看来,这是最自然的:
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;
}
查看完整示例:http ://coliru.stacked-crooked.com/a/603f093add6b9799