在boost ::精神::补气,是它可以动态修改运行规则定义 [英] in boost::spirit::qi, is it possible to dynamically modify rule definition in runtime

查看:142
本文介绍了在boost ::精神::补气,是它可以动态修改运行规则定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一些与语法的boost ::精神::气::规则来分析网络数据包。语法是这样的:

I wrote some grammar with boost::spirit::qi::rule to parse the internet packet. the grammar is something like:

qi::rule<Iterator> start, request, response, status, query ;
start = (request | response | status | query) >> lit("\r\n");

要提高性能,用户可能想跳过在运行时的一些规则,例如忽略了回应,状态,查询,只有尝试匹配的要求,因此该规则将改变为:

to improve the performance, user maybe want to skip some rules in the runtime, e.g. ignore "response","status","query" and only try to match request, so the rule will change to:

start = (request ) >> lit("\r\n"); 

是有可能做到这一点?例如,有没有像函数禁用()只是禁用规则回应,身份和查询?

is it possible to do that? e.g, is there a function like "disable()" to just disable the rule "response", "status" and "query"?

推荐答案

最自然的方法是只使用一个不同的解析器为您的更多的限制的场合。

The most natural approach would be to just use a different parser for your more constrained occasions.

此外,如果的性能是非常重要的,你甚至不能备用3个或4个额外的字符比较

Also, if performance is so important that you can't even spare 3 or 4 extra character comparisons


  • 您或许应该做一个手写的解析器(一般来说,圣灵的自动特性处理并不总是最优的)或

  • 考虑静态优化扫描(所以升压点¯xpressive或精神莱克斯)

  • 您也许可以做一些错误的(如果你有一个次优的语法,你能有多大的回溯杀性能 - 就像退化普通防爆pressions(的https://www.owasp.org/index.php/Regular_ex$p$pssion_Denial_of_Service_-_ReDoS))

  • you should probably do a handwritten parser (in general, Spirit's automatic attribute handling isn't always optimal) or
  • consider statically optimized scanning (so Boost Xpressive or Spirit Lex)
  • you might perhaps be doing something wrong (if you have a suboptimal grammar you can have much backtracking kill the performance - much like degenerate Regular Expressions (https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS))

这是说,这里有一些选择:

That said, here are some options:

#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";
    }
}

像迈克提到,这也是用在Nabialek把戏,虽然气懒:: 是这里的重要组成部分。

Like Mike mentions, this is also used in the Nabialek trick, although qi::lazy is the essential ingredient here.

这版画,例如:

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。使用继承属性与气懒::

pretty类似于上述,可以通过子规则'作为继承的属性。我不知道我会建议这一点,因为我在过去的实例可以看出未定义行为突然出现,参见例如

2. Use inherited attributes with qi::lazy

Pretty similar to the above, you could pass 'subrules' as inherited attributes. I'm not sure I'd recommend this, as I've seen Undefined Behaviour crop up in past examples, see e.g.


  • Factoring出的精神规则公用部分(阅读评论!)

  • 也<一个href=\"http://stackoverflow.com/questions/17405500/c-boost-qi-recursive-rule-construction/17408206#17408206\">C++提高对如何气懒:: 本身不支持继承属性
  • 齐递归规则建设
  • Factoring out common parts of Spirit rules (read the comments!)
  • also C++ Boost qi recursive rule construction on how qi::lazy itself doesn't support inherited attributes

这是最自然的,在我看来:

This is most natural, in my opinion:

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

这篇关于在boost ::精神::补气,是它可以动态修改运行规则定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆