在 boost::spirit::lex 中,第一次解析花费的时间最长,后续解析的时间会短得多

2023-11-30

我将一系列文本输入到我的 sip 解析器中。第一个文本花费的时间最长,无论哪个是第一个。我想知道当spirit::lex 进行第一次解析时是否有任何初始化工作?

template <typename Lexer>
struct sip_token : lex::lexer<Lexer>
{
    sip_token()
    {
        this->self.add_pattern
            ("KSIP", "sip:")
            ("KSIPS", "sips:")
            ("USERINFO", "[0-9a-zA-Z-_.!~*'()]+(:[0-9a-zA-Z-_.!~*'()&=+$,]*)?@")
            ("DOMAINLBL", "([0-9a-zA-Z]|([0-9a-zA-Z][0-9a-zA-Z-]*[0-9a-zA-Z]))")
            ("TOPLBL", "[a-zA-Z]|([a-zA-Z][0-9a-zA-Z-]*[0-9a-zA-Z-])")
            ("INVITE", "INVITE")
            ("ACK", "ACK")
            ("OPTIONS", "OPTIONS")
            ("BYE", "BYE")
            ("CANCEL", "CANCEL")
            ("REGISTER", "REGISTER")
            ("METHOD", "({INVITE}|{ACK}|{OPTIONS}|{BYE}|{CANCEL}|{REGISTER})")
            ("SIPVERSION", "SIP\\/[0-9]\\.[0-9]")
            ("PROTOCOAL", "SIP\\/[^/]+\\/UDP")
            ("IPV4ADDR", "(\\d{1,3}\\.){3}\\d{1,3}")                
            ("HOSTNAME", "[^ \t\r\n]+")            
            ("SIPURL", "{KSIP}{USERINFO}?{HOSTNAME}(:[0-9]+)?")
            ("SIPSURL", "{KSIPS}{USERINFO}?{HOSTNAME}(:[0-9]+)?")
            ("SENTBY", "({HOSTNAME}|{IPV4ADDR})(:[0-9]+)?")
            ("GENPARM", "[^ ;\\n]+=[^ ;\r\\n]+")
            ("TOKEN", "[0-9a-zA-Z-.!%*_+~`']+")
            ("NAMEADDR", "({TOKEN} )?<({SIPURL}|{SIPSURL})>")
            ("STATUSCODE", "\\d{3}")
            ("REASONPHRASE", "[0-9a-zA-Z-_.!~*'()&=+$,]*")
            ("CR", "\\r")
            ("LF", "\\n")
        ;

        this->self.add
            ("{METHOD} {SIPURL} {SIPVERSION}", T_REQ_LINE)
            ("{SIPVERSION} {STATUSCODE} {REASONPHRASE}", T_STAT_LINE)
            ("{CR}?{LF}", T_CRLF)
            ("Via: {PROTOCOAL} {SENTBY}(;{GENPARM})*", T_VIA)
            ("To: {NAMEADDR}(;{GENPARM})*", T_TO)
            ("From: {NAMEADDR}(;{GENPARM})*", T_FROM)
            ("[0-9a-zA-Z -_.!~*'()&=+$,;/?:@]+", T_OTHER)

        ;
    }
};

grammar:

template <typename Iterator>
struct sip_grammar : qi::grammar<Iterator>
{
  template <typename TokenDef>
  sip_grammar(TokenDef const& tok)
    : sip_grammar::base_type(start)     
  {
    using boost::phoenix::ref;
    using boost::phoenix::size;
    using boost::spirit::qi::eol;

    start = request  | response;
    response = stat_line >> *(msg_header) >> qi::token(T_CRLF);
    request = req_line >> *(msg_header) >> qi::token(T_CRLF);
    stat_line = qi::token(T_STAT_LINE) >> qi::token(T_CRLF);
    req_line = qi::token(T_REQ_LINE) >> qi::token(T_CRLF);
    msg_header = (qi::token(T_VIA) | qi::token(T_TO) | qi::token(T_FROM) | qi::token(T_OTHER))
      >> qi::token(T_CRLF);    
  }

  std::size_t c, w, l;
  qi::rule<Iterator> start, response, request, stat_line, req_line, msg_header; 
};

timing:

gettimeofday(&t1, NULL);
bool r = lex::tokenize_and_parse(first, last, siplexer, g);
gettimeofday(&t2, NULL);    

result:

pkt1 time=40945(us)
pkt2 time=140
pkt3 time=60
pkt4 time=74
pkt5 time=58
pkt6 time=51

显然,确实如此:)

Lex 可能会生成一个 DFA(也许每个 Lexer 状态一个)。这很可能是最耗时的事情。使用分析器来确定:/

现在你可以

  • 确保表在首次使用前已初始化,或者
  • use the 静态词法分析器模型以防止启动成本

这意味着你要写一个“额外”main将 DFA 生成为 C++ 代码:

#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/lex_generate_static_lexertl.hpp>

#include <fstream>

#include "sip_token.hpp"

using namespace boost::spirit;

int main(int argc, char* argv[])
{
    // create the lexer object instance needed to invoke the generator
    sip_token<lex::lexertl::lexer<> > my_lexer; // the token definition

    std::ofstream out(argc < 2 ? "sip_token_static.hpp" : argv[1]);

    // invoke the generator, passing the token definition, the output stream 
    // and the name suffix of the tables and functions to be generated
    //
    // The suffix "sip" used below results in a type lexertl::static_::lexer_sip
    // to be generated, which needs to be passed as a template parameter to the 
    // lexertl::static_lexer template (see word_count_static.cpp).
    return lex::lexertl::generate_static_dfa(my_lexer, out, "sip") ? 0 : -1;
}

生成的代码示例如下(在教程中的字数统计示例中):http://www.boost.org/doc/libs/1_54_0/libs/spirit/example/lex/static_lexer/word_count_static.hpp

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 boost::spirit::lex 中,第一次解析花费的时间最长,后续解析的时间会短得多 的相关文章

  • 在 CPP 类中将 C 函数声明为友元

    我需要在 C 函数中使用类的私有变量 我正在做这样的事情 class Helper private std string name public std getName return name friend extern C void in
  • 将类对象放置在向量中?

    我注意到我可以将一个类放置在一个向量中 这是我的程序 我收到以下错误 out blackjack exe blackjack obj blackjack obj error LNK2019 unresolved external symbo
  • 现代 C++ 编译器是否能够在某些情况下避免调用 const 函数两次?

    例如 如果我有以下代码 class SomeDataProcessor public bool calc const SomeData d1 const SomeData d2 const private Some non mutable
  • 从复选框列表中选择循环生成的复选框中的一个复选框

    抱歉我的英语不好 在我的 ASP NET 网站上 我从 SQL 表导入软件列表 看起来像这样 但实际上要长得多 Microsoft Application Error Reporting br br Microsoft Applicatio
  • 无法注册时间触发的后台任务

    对于 Windows 8 应用程序 在 C Xaml 中 我尝试注册后台任务 很难说 但我想我的后台任务已正确注册 但是当我单击调试位置工具栏上的后台任务名称时 我的应用程序停止工作 没有任何消息 我查看了事件查看器上的日志 得到 具有入口
  • extern 声明和函数定义都在同一文件中

    我只是浏览了一下gcc源文件 在gcc c 我发现了类似的东西 extern int main int char int main int argc char argv 现在我的疑问是extern是告诉编译器特定的函数不在这个文件中 但可以
  • 处理右值时的 insert 与 emplace

    std string myString std unordered set
  • 强制初始化模板类的静态数据成员

    关于模板类的静态数据成员未初始化存在一些问题 不幸的是 这些都没有能够帮助我解决我的具体问题的答案 我有一个模板类 它有一个静态数据成员 必须为特定类型显式实例化 即必须专门化 如果不是这种情况 使用不同的模板函数应该会导致链接器错误 这是
  • RestSharp获取序列化输出

    我正在寻找一种方法来访问 AddBody 调用的序列化结果 我正在使用内置的 RestSharp 序列化器 例子 class Foo public string FooField void SendRecord var f new Foo
  • 语音识别编程问题入门

    所以 你们可能都看过 钢铁侠 其中托尼与一个名为贾维斯的人工智能系统进行交互 演示剪辑here http www youtube com watch v Go8zsh1Ev6Y 抱歉 这是广告 我非常熟悉 C C 和 Visual Basi
  • 如何在 C# Designer.cs 代码中使用常量字符串?

    如何在 designer cs 文件中引用常量字符串 一个直接的答案是在我的 cs 文件中创建一个私有字符串变量 然后编辑 Designer cs 文件以使用此变量 而不是对字符串进行硬编码 但设计者不喜欢这样抛出错误 我明白为什么这行不通
  • 什么是空终止字符串?

    它与什么不同标准 字符串 http www cplusplus com reference string string 字符串 实际上只是一个数组chars 空终止字符串是指其中包含空字符的字符串 0 标记字符串的结尾 不一定是数组的结尾
  • C++中判断unicode字符是全角还是半角

    我正在编写一个终端 控制台 应用程序 该应用程序应该包装任意 unicode 文本 终端通常使用等宽 固定宽度 字体 因此要换行文本 只需计算字符数并观察单词是否适合一行并采取相应的操作 问题是 Unicode 表中的全角字符在终端中占用了
  • 如何将AVFrame转换为glTexImage2D使用的纹理?

    如您所知 AVFrame 有 2 个属性 pFrame gt data pFrame gt linesize 当我从视频 sdcard test mp4 android平台 读取帧后 并将其转换为RGB AVFrame副 img conve
  • 从网页运行 ClickOnce 应用程序,无需用户操作

    我们有一个基于 Java 的 Web 应用程序以及用 C 编写的相同应用程序 如果 java 检查器发现客户端计算机上没有安装 Java 则应该运行该应用程序 这个想法是运行 C 单击一次 http en wikipedia org wik
  • 在 C 中使用枚举而不是 #defines 作为编译时常量是否合理?

    在 C 工作了一段时间后 我将回到 C 开发领域 我已经意识到 在不必要的时候应该避免使用宏 以便让编译器在编译时为您做更多的工作 因此 对于常量值 在 C 中我将使用静态 const 变量或 C 11 枚举类来实现良好的作用域 在 C 中
  • 比较:接口方法、虚方法、抽象方法

    它们各自的优点和缺点是什么 接口方法 虚拟方法 抽象方法 什么时候应该选择什么 做出这一决定时应牢记哪些要点 虚拟和抽象几乎是一样的 虚方法在基类中有一个实现 可以选择重写 而抽象方法则没有 并且must在子类中被覆盖 否则它们是相同的 在
  • Visual Studio 2015 - Web 项目上缺少共享项目参考选项卡

    我从 MSDN 订阅升级到 Visual Studio 2015 因为我非常兴奋地阅读有关共享项目的信息 当我们想要做的只是重用代码时 不再需要在依赖项中管理 21382 个 nuget 包 所以我构建了一个测试共享项目 其中包含一些代码
  • 没有“对 *this”功能的右值引用的解决方法

    我有一个围绕可移动对象的代理容器类 并希望代理能够隐式生成对底层对象的右值引用 但仅当代理本身被移动时 我相信我将能够按照提案 n2439 实施此行为 将移动语义扩展到 this http www open std org jtc1 sc2
  • MySqlConnectionStringBuilder - 使用证书连接

    我正在尝试连接到 Google Cloud Sql 这是一个 MySql 解决方案 我能够使用 MySql Workbench 进行连接 我如何使用 C 连接MySqlConnectionStringBuilder 我找不到提供这三个证书的

随机推荐

  • Django:无法导入模块

    我正在尝试在我的views py 中导入一个模块 from django shortcuts import render Create your views here from viewcreator import Builder impo
  • iPhone - UILocalNotification 作为警报

    即使我的 iPhone 应用程序处于后台 我如何使用 UILocalNotification 每天晚上 8 点显示我的闹钟 Set the fireDate到晚上 8 点并设置repeatInterval to NSDayCalendarU
  • 将 N 列的数据框转换为两个“堆叠”列的数据框

    你好堆栈社区 我正在从事网络分析工作 并且有一个数据重塑问题 我的原始数据以一系列列的形式出现 每列都是 源 和 目标 对 最终的数据框需要由 源 和 目标 两列组成 请注意 这些对是交错的 因为它们的源和目标像在有向网络中一样链接 请参阅
  • 使用 vbscript 更改控制台标题

    有没有办法改变cmd标题 我写了一个vbs程序 但dos标题很糟糕 名称为 c windows system32 cscript exe 我尝试一下 标题 the name 和 标题 姓名 但两者都不起作用 感谢帮助 AlexK您指向的链接
  • 如何覆盖循环内的可变字符串?

    我的示例稍作修改The Rust Book 中的猜谜游戏教程 第一次迭代后 循环似乎无法正确读取用户对可变字符串的输入 您能找出以下代码中关于以下内容的问题吗 mut input text extern crate rand use ran
  • 通道发送是否是 goroutine 调度的抢占点?

    从我对Go调度器的理解来看 Go调度算法是部分先发制人 当 goroutine 调用函数或阻塞 I O 时 会发生 goroutine 切换 向通道发送消息时是否会发生 goroutine 切换 goroutine A ch lt mess
  • PHP 正则表达式,忽略交替语句中的第一个分组

    我试图弄清楚如何使用 preg match 捕获一条语句 如果另一条语句不存在 示例文本 div h1 strong Citing Your Sources strong h1 div 因为 pagetitle
  • 如何将应用程序路径传递给Azure批处理中的任务

    我正在使用 Azure 批处理 我有一个需要在计算节点上执行的exe 我在任务窗口的天蓝色门户中使用此路径 cmd c AZ BATCH APP PACKAGE MyAppCreateRG CreateRG exe args HelloRG
  • 什么是 -D 编译器标志 C++(clang、GNU、MSVC)

    好吧 我假设 D前缀表示 define无论它后面跟着什么变量名 但是我找不到任何有关编译器标志的 makefile 功能的文档 CXX clang DTHISISPREPROCESSORVARIABLE So DTHISISPREPROCE
  • 剧作家使用 JavaScript (Node) 将变量传递给 eval

    注意 这是针对 Playwright 浏览器 API 如 puppeteer 我试图找到页面上的所有元素 然后想将这些元素过滤为值 这些值具有特定的选择器 css 类等 我遇到的问题是我无法将外部变量传递到 eval 函数中 以便我的 CS
  • 如何调整 OpenEars 错误识别

    我在我的应用程序中使用了 OpenEars 只需识别字母表中的 a 到 z 即可 但它在识别字母方面的识别能力比识别单词的能力差 那么 我如何使用我的声音模型来提高 OpenEars 的识别度 以及如何使用 OpenEars 来识别一些特殊
  • 根据时间序列中的条件对行进行分组并忽略错误值

    我有一组具有不同采样间隔的动物位置 我想要做的是对采样间隔符合特定条件 例如低于特定值 的序列进行分组和标记 这是一个修订版这个问题被标记为重复项this one 这个修订后的问题的不同之处在于 所有不符合标准的值都应该被忽略 而不是被标记
  • Bing 搜索 API - 如何本地化结果?

    默认情况下如何使用斯洛文尼亚语搜索结果 我们的服务器有德国 IP Bing API 首先自动显示德国结果 我已经尝试了文档中描述的一些参数 但到目前为止它们都不起作用 Thanks 您是否尝试过设置市场选项 根据这个示例页面 你应该尝试这样
  • boost karma 中的生成器指令列行为不一致

    我正在编写一个 karma 生成器来生成 HTML 页面 并且在使用列指令时遇到不一致的行为 这很可能是我对其工作原理的理解 基本上我正在生成一个网格 它要求我在数据每出现两次后插入一些分隔符 以下是我用来进行测试运行的基本程序 inclu
  • Perl - 包含相对路径中的包,其中包含相对路径中的另一个包?

    我有三个文件 multiFindBinTest pl use FindBin use lib FindBin Bin mod2 use pack2 mod1 pack1 pm package pack1 1 mod2 pack2 pm us
  • Typescript:如何创建一个类型,它是界面的键,但只有字符串的键

    假设我有这个界面 interface MyInterface val1 string val2 string val3 number val4 string val5 Date 我想创建一个类型 它是 MyInterface 的键 但只有字
  • 使用 FFMPEG 从 IP 摄像机读取 RTCP 数据包

    我正在使用 ffmpeg C 库 我需要拦截来自摄像头的 RTCP 数据包 以便从发送者报告中获取时间戳 ffmpeg 中是否有任何方法或结构可以为我提供此信息 我完全陷入困境 但我无法解决这个问题 任何帮助将不胜感激 提前致谢 最后我不得
  • 如何根据用户登录隐藏某些功能? [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 我们想在 Tomcat 中隐藏一些基于用户登录的代码功能 我们正在使用基本身份验证 有什么建议么 IF你的意思只是隐藏一些资源 具体取决于用户是否登录那么这只是限制对某些页面的访
  • .mp3 文件类型上传

    我正在开发一个 PHP 上传脚本 它允许 mp3 文件上传等 我创建了一个数组 指定允许的文件类型 包括 mp3 并将最大上传限制设置为 500MB define a constant for the maximum upload size
  • 在 boost::spirit::lex 中,第一次解析花费的时间最长,后续解析的时间会短得多

    我将一系列文本输入到我的 sip 解析器中 第一个文本花费的时间最长 无论哪个是第一个 我想知道当spirit lex 进行第一次解析时是否有任何初始化工作 template