CN110413284A - 词法分析方法、装置、计算机设备和存储介质 - Google Patents
词法分析方法、装置、计算机设备和存储介质 Download PDFInfo
- Publication number
- CN110413284A CN110413284A CN201910720528.9A CN201910720528A CN110413284A CN 110413284 A CN110413284 A CN 110413284A CN 201910720528 A CN201910720528 A CN 201910720528A CN 110413284 A CN110413284 A CN 110413284A
- Authority
- CN
- China
- Prior art keywords
- function
- code
- variable
- character sequence
- hash mapping
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Granted
Links
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/41—Compilation
- G06F8/42—Syntactic analysis
- G06F8/425—Lexical analysis
-
- Y—GENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
- Y02—TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
- Y02D—CLIMATE CHANGE MITIGATION TECHNOLOGIES IN INFORMATION AND COMMUNICATION TECHNOLOGIES [ICT], I.E. INFORMATION AND COMMUNICATION TECHNOLOGIES AIMING AT THE REDUCTION OF THEIR OWN ENERGY USE
- Y02D10/00—Energy efficient computing, e.g. low power processors, power management or thermal management
Landscapes
- Engineering & Computer Science (AREA)
- General Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Software Systems (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Stored Programmes (AREA)
Abstract
本申请涉及一种词法分析方法、装置、计算机设备和存储介质。所述方法包括:获取代码文件并确定代码文件的入口函数,读取入口函数的代码字符序列;根据预先构建的反向变量哈希映射,将入口函数的代码字符序列中的自定义变量替换为原子级变量,得到变量归一化后的代码字符序列;获取变量归一化后的代码字符序列中的函数调用代码,根据预先构建的函数体哈希映射将函数调用代码替换为被调用函数的函数体,得到过程式函数代码;对过程式函数代码进行词法分析,得到代码文件对应的单词序列。采用本方法能够实现将具有复杂层级结构的代码文件进行函数递归展开为过程式函数代码,有效解决具有复杂层级结构代码的词法分析问题。
Description
技术领域
本申请涉及数据处理技术领域,特别是涉及一种词法分析方法、装置、计算机设备和存储介质。
背景技术
词法分析(lexical analysis)是计算机科学中将字符序列转换为单词(Token)序列的过程。通过词法分析将代码转为单词序列,再通过word embedding转换成数字向量,是进行代码检查、代码深度学习等技术的重要基础。
但是,随着软件工程项目的代码文件日趋复杂,越来越多的代码文件采用面向对象设计的复杂层级结构来组织代码逻辑,以提高代码的可扩展性,而传统的词法分析技术只能转换简单的单行或多行代码文本,难以对复杂层级结构的代码文件进行词法分析。
发明内容
基于此,有必要针对传统的词法分析技术难以对复杂层级结构的代码文件进行词法分析的技术问题,提供一种词法分析方法、装置、计算机设备和存储介质。
一种词法分析方法,所述方法包括:
获取代码文件并确定所述代码文件的入口函数,读取所述入口函数的代码字符序列;
根据预先构建的反向变量哈希映射,将所述入口函数的代码字符序列中的自定义变量替换为原子级变量,得到变量归一化后的代码字符序列;
获取所述变量归一化后的代码字符序列中的函数调用代码,根据预先构建的函数体哈希映射将所述函数调用代码替换为被调用函数的函数体,得到过程式函数代码;
对所述过程式函数代码进行词法分析,得到所述代码文件对应的单词序列。
一种词法分析装置,所述装置包括:
入口函数获取模块,用于获取代码文件并确定所述代码文件的入口函数,读取所述入口函数的代码字符序列;
变量归一模块,用于根据预先构建的反向变量哈希映射,将所述入口函数的代码字符序列中的自定义变量替换为原子级变量,得到变量归一化后的代码字符序列;
函数展开模块,用于获取所述变量归一化后的代码字符序列中的函数调用代码,根据预先构建的函数体哈希映射将所述函数调用代码替换为被调用函数的函数体,得到过程式函数代码;
词法分析模块,用于对所述过程式函数代码进行词法分析,得到所述代码文件对应的单词序列。
一种计算机设备,包括存储器和处理器,所述存储器存储有计算机程序,所述处理器执行所述计算机程序时实现以下步骤:
获取代码文件并确定所述代码文件的入口函数,读取所述入口函数的代码字符序列;
根据预先构建的反向变量哈希映射,将所述入口函数的代码字符序列中的自定义变量替换为原子级变量,得到变量归一化后的代码字符序列;
获取所述变量归一化后的代码字符序列中的函数调用代码,根据预先构建的函数体哈希映射将所述函数调用代码替换为被调用函数的函数体,得到过程式函数代码;
对所述过程式函数代码进行词法分析,得到所述代码文件对应的单词序列。
一种计算机可读存储介质,其上存储有计算机程序,所述计算机程序被处理器执行时实现以下步骤:
获取代码文件并确定所述代码文件的入口函数,读取所述入口函数的代码字符序列;
根据预先构建的反向变量哈希映射,将所述入口函数的代码字符序列中的自定义变量替换为原子级变量,得到变量归一化后的代码字符序列;
获取所述变量归一化后的代码字符序列中的函数调用代码,根据预先构建的函数体哈希映射将所述函数调用代码替换为被调用函数的函数体,得到过程式函数代码;
对所述过程式函数代码进行词法分析,得到所述代码文件对应的单词序列。
上述词法分析方法、装置、计算机设备和存储介质,通过获取代码文件的入口函数的代码字符序列,利用预先构建的反向变量哈希映射,将入口函数的代码字符序列中的自定义变量替换为归一化的原子级变量,以获取变量归一化后的代码字符序列,并根据预先构建的函数体哈希映射,将变量归一化后的代码字符序列中的函数调用代码替换为被调用函数的函数体,得到过程式函数代码,从而对过程式函数代码进行词法分析,获得代码文件对应的单词序列,极大降低了由于代码层级和用户自定义标识符的复杂性和多样性带给词法分析的干扰,实现将具有复杂层级结构的代码文件进行函数递归展开为过程式函数代码,有效解决具有复杂层级结构代码的词法分析问题。
附图说明
图1为一个实施例中词法分析方法的应用环境图;
图2为一个实施例中计算机设备的结构框图;
图3为一个实施例中词法分析方法的流程示意图;
图4为一个实施例中将入口函数的代码字符序列转换为过程式函数代码的流程示意图;
图5为另一个实施例中将入口函数的代码字符序列转换为过程式函数代码的流程示意图;
图6为一个实施例中构建反向变量哈希映射的流程示意图;
图7为另一个实施例中构建反向变量哈希映射的流程示意图;
图8为一个实施例中构建函数体哈希映射的流程示意图;
图9为一个实施例中词法分析方法的流程示意图;
图10为一个实施例中词法分析装置的结构框图。
具体实施方式
为了使本申请的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本申请进行进一步详细说明。应当理解,此处描述的具体实施例仅仅用以解释本申请,并不用于限定本申请。
图1为一个实施例中词法分析方法的应用环境图。该词法分析方法应用于一种计算机设备。该计算机设备可以是服务器或终端。如图1所示,以该计算机设备是服务器102为例,服务器102获取代码文件并确定代码文件的入口函数后,读取入口函数的代码字符序列,并根据预先构建的反向变量哈希映射,将入口函数的代码字符序列中的自定义变量替换为原子级变量,得到变量归一化后的代码字符序列;获取变量归一化后的代码字符序列中的函数调用代码,根据预先构建的函数体哈希映射将函数调用代码替换为被调用函数的函数体,得到过程式函数代码;对过程式函数代码进行词法分析,得到代码文件对应的单词序列,以便后续对代码文件进行代码检查、代码深度学习等操作。
本领域技术人员可以理解。图1中示出的应用环境,仅仅与本申请方案相关的部分场景,并不构成对本申请应用环境的限定,
图2示出了一个实施例中计算机设备的内部结构图。该计算机设备具体可以是图1中的服务器102。如图2所示,该计算机设备包括该计算机设备包括通过系统总线连接的处理器、存储器、网络接口、输入装置和显示屏。其中,存储器包括非易失性存储介质和内存储器。该计算机设备的非易失性存储介质存储有操作系统,还可存储有计算机程序,该计算机程序被处理器执行时,可使得处理器实现词法分析方法。该内存储器中也可储存有计算机程序,该计算机程序被处理器执行时,可使得处理器执行词法分析方法。计算机设备的显示屏可以是液晶显示屏或者电子墨水显示屏,计算机设备的输入装置可以是显示屏上覆盖的触摸层,也可以是计算机设备外壳上设置的按键、轨迹球或触控板,还可以是外接的键盘、触控板或鼠标等。
本领域技术人员可以理解,图2中示出的结构,仅仅是与本申请方案相关的部分结构的框图,并不构成对本申请方案所应用于其上的计算机设备的限定,具体的计算机设备可以包括比图中所示更多或更少的部件,或者组合某些部件,或者具有不同的部件布置。
如图3所示,在一个实施例中,提供了一种词法分析方法。本实施例主要以该方法应用于上述图1中的服务器102来举例说明。参照图3,该词法分析方法具体包括如下步骤:
步骤202,获取代码文件并确定代码文件的入口函数,读取入口函数的代码字符序列。
代码文件是指完成一定功能的、使用编程语言编写的代码文件,代码字符序列是指代码文件中的程序代码对应的字符序列;入口函数是指负责控制代码整体逻辑流程的函数代码,是整个代码的逻辑主干,比如,以编程语言为C语言编码的代码文件为例,入口函数可以是main函数。
在实际应用中,代码文件的数量可以是多个的,入口函数的数量可以是多个的。例如,在软件工程项目中往往包括多个代码文件,而项目的业务逻辑不同,不同代码文件间的层级结构是不同的,软件工程项目中往往具有一个或多个入口函数负责控制代码整体的逻辑流程,服务器在对软件工程项目的代码文件进行词法分析时,获取项目对应的代码文件,并确定项目的入口函数,将项目的入口函数作为词法分析方法的切入点。
步骤204,根据预先构建的反向变量哈希映射,将入口函数的代码字符序列中的自定义变量替换为原子级变量,得到变量归一化后的代码字符序列。
变量用于存储值,比如数字、文本字符串或数组,其中,自定义变量是指代码开发人员声明的自定义的标识符,例如,在PHP编程语言中自定义变量是以符号“$”开头的;原子级变量是与自定义变量对应的;反向变量哈希映射预先保存了代码文件中自定义变量及其对应的原子级变量间的映射关系。
在代码文件中的程序代码,由于自定义变量的复杂性,完成相同业务功能的程序代码的写法是多种多样的,转换后得到的token序列的差异较大,对于利用token序列进行后续分析是极为不利的。具体地,服务器在获取到入口函数的代码字符序列后,读取预先构建的反向变量哈希映射,并根据反向变量哈希映射将入口函数中的自定义变量替换为对应的归一化的原子级变量,其中反向变量哈希映射记载着在代码文件中第n行的自定义变量被替换的原子级变量的信息,有效降低用户自定义标识的变量的多样性,以及降低词法分析的变量噪声,有效提高此行分析的准确性。
例如,以编程语言为PHP语言编码的test.php代码文件为例,test.php代码文件里定义了:
1$a=new Lib\Redis::init();
2$a->incr();
而预先构建的反向变量哈希映射包括:
RVM={'test.php':{'$a':[('new Lib\Redis::init()',2)]}}
该反向变量哈希映射表示在“test.php”代码文件中,对于自定义变量“$a”,在第2行替换为“new Lib\Redis::init()”。
服务器在读取入口函数的代码字符序列时,获取到第2行的自定义变量“$a”,服务器根据预先构建的反向变量哈希映射,将自定义变量“$a”替换为对应的原子级的原子级变量,即“new Lib\Redis::init()”,得到变量归一化后的代码字符序列为:
“$a=new Lib\Redis::init();
(new Lib\Redis::init())->incr();”
步骤206,获取变量归一化后的代码字符序列中的函数调用代码,根据预先构建的函数体哈希映射将函数调用代码替换为被调用函数的函数体,得到过程式函数代码。
本步骤中,函数调用代码是指引用本代码文件或另外一个代码文件中所提供的自定义函数的代码字符序列;函数体是指编程语言中定义一个函数功能的所有代码字符序列。
函数体哈希映射预先保存用户自定义函数的函数名以及函数名对应的函数体间的映射关系;过程式代码是指面对过程编程(Procedure Oriented Programing,POP)所得到的代码,特点是一步一步完成目标的顺序式步骤执行代码。
现有的软件工程项目大多使用面向对象编程,其程序执行过程中,由入口函数进入,通过定义类,在项目执行过程中根据需要执行类的成员函数,面向对象编程的代码文件往往层级结构复杂,导致词法分析的复杂性大大增加。具体地,服务器读取入口函数变量归一化后各行代码的代码字符序列,并确定入口函数中的函数调用代码,从函数调用代码中提取所调用函数的函数名,在确定到函数名后,从函数体哈希映射中获取与函数名对应的函数体,将该函数体替换入口函数中的函数调用代码,通过将函数调用代码展开为对应的函数体,实现将具有复杂层级结构的代码转换为词法分析可处理的过程式代码,同时降低用户自定义函数名的多样性带给词法分析的干扰。
步骤208,对过程式函数代码进行词法分析,得到代码文件对应的单词序列。
本步骤中,单词序列是指token序列,是编程语言中的最小元素;对过程式函数代码进行词法分析,可以利用Python开源库pygments实现将过程式函数代码中的代码字符序列转换为单词(token)序列。代码文件中通常包括程序代码相关的代码字符序列和对代码字符序列的注释,具体地,服务器在对变量归一化后的过程式函数代码进行词法分析时,可以将代码文件中的注释移除,保留代码字符序列,然后根据构词规则识别标记,得到代码文件的单词序列。
上述词法分析方法中,通过获取代码文件的入口函数的代码字符序列,利用预先构建的反向变量哈希映射,将入口函数的代码字符序列中的自定义变量替换为归一化的原子级变量,以获取变量归一化后的代码字符序列,并根据预先构建的函数体哈希映射,将变量归一化后的代码字符序列中的函数调用代码替换为被调用函数的函数体,得到过程式函数代码,从而对过程式函数代码进行词法分析,获得代码文件对应的单词序列,极大降低了由于代码层级和用户自定义标识符的复杂性和多样性带给词法分析的干扰,实现将具有复杂层级结构的代码文件进行函数递归展开为过程式函数代码,有效解决具有复杂层级结构代码的词法分析问题。
参见图4,图4为一个实施例中将入口函数的代码字符序列转换为过程式函数代码的流程示意图。在本实施例中,根据预先构建的函数体哈希映射将函数调用代码替换为被调用函数的函数体的步骤,包括:
步骤302,逐行扫描变量归一化后的代码字符序列;
步骤304,当代码字符序列为函数调用代码时,从函数调用代码中获取被调用函数的函数名;
步骤306,根据被调用函数的函数名,从函数体哈希映射中获取与被调用函数的函数体,将代码字符序列中的函数调用代码替换为被调用函数的函数体。
具体地,在获取到变量归一化后的入口文件的代码字符序列后,以行为单位读取出代码字符序列,服务器可以利用正则表达式去匹配检测该行代码字符序列是否为函数调用代码,若当前的代码字符序列为函数调用代码,服务器从该行函数调用代码中确定被调用函数的函数名,从而根据函数名从函数体哈希映射中获取与该函数名对应的函数体,并将代码字符序列中的函数调用代码替换为被调用函数的函数体中的代码字符序列,实现将入口函数平铺展开为过程式代码段。
比如,以编程语言为PHP语言编码的test.php代码文件为例,test.php代码文件里第20行至第26行定义了:
而在test.php代码文件里第30、31行的入口函数定义了:
30$a=new A();
31$a->f();
而服务器在读取入口函数的代码字符序列时,获取函数调用代码“$a->f()”,并从中获取函数调用代码的被调用函数的函数名f(),从而将入口函数中的函数调用代码替换为函数f()对应的函数体,替换后得到的过程式函数代码:
“$a=new A();
echo“hello world\n;”
在一个实施例中,将代码字符序列中的函数调用代码替换为被调用函数的函数体的步骤之后,还包括:逐行扫描被调用函数的函数体中的代码字符序列;当所述被调用函数的函数体中的代码字符序列为函数调用代码时,跳转至从函数调用代码中获取被调用函数的函数名的步骤。
在对入口函数进行函数展开时,往往会遇到函数调用链的情况,例如,入口函数包含函数func1的调用,而在函数func1的函数体中包含另一个函数func2的调用,服务器在入口函数的代码字符序列检测到函数func1的函数调用代码,并将函数func1的函数调用代码替换为函数func1的函数体后,可以从函数func1的函数体中以行为单位读取出代码字符序列,并利用正则表达式去匹配检测该行代码字符序列是否为函数调用代码,若当前的代码字符序列为函数func2的函数调用代码,服务器从获取该函数调用代码中确定被调用函数的函数名“func2”,从而根据函数名“func2”从函数体哈希映射中获取函数func2的函数体,将在函数func1函数体中的函数func2的函数调用代码替换为函数func2的函数体,实现对入口函数的完整展开。
进一步的,若函数func2的函数体中包含另一个函数func3的函数调用代码,此时服务器可以从函数体哈希映射中获取函数func3的函数体,将函数func3的函数调用代码替换为函数func3的函数体,实现函数展开;依次类推,当代码文件中包含有函数调用链时,服务器可以利用函数体哈希映射对函数调用链实现完全展开,使得代码字符序列中的函数调用代码替换为与之对应的函数体,实现将入口函数平铺展开为过程式代码段,有效降低代码文件层级结构的复杂性,降低词法分析的难度。
参见图5,图5为另一个实施例中将入口函数的代码字符序列转换为过程式函数代码的流程示意图。在本实施例中,根据预先构建的函数体哈希映射将函数调用代码替换为被调用函数的函数体,得到过程式函数代码的步骤,包括:
步骤402,逐行扫描变量归一化后的入口函数的代码字符序列;
步骤404,检测代码字符序列是否存在函数调用代码,若是,执行步骤406,若否,则结束;
步骤406,函数调用代码中获取被调用函数的函数名,根据被调用函数的函数名,从函数体哈希映射中获取与被调用函数的函数体,将代码字符序列中的函数调用代码替换为被调用函数的函数体。
步骤408,逐行扫描被调用函数的函数体中的代码字符序列;
步骤410,检测被调用函数的函数体中的代码字符序列是否存在函数调用代码,若是跳转至步骤406,若否,则结束。
本实施例中,服务器对入口函数中的函数调用链实现递归展开,使得入口函数的代码字符序列中的函数调用代码替换为被调用函数的函数体中的代码字符序列,实现将入口函数平铺展开为过程式代码段,有效降低代码文件层级结构的复杂性,降低词法分析的难度。应该说明的是,对于原子级函数的调用是不用展开的,仅仅展开非原子级函数的调用是需要展开的,其中,原子级函数是指函数库中定义的函数,非原子级函数是指用户自定义函数。
在代码文件中的程序代码,由于自定义变量的复杂性,完成相同业务功能的程序代码的写法是多种多样的,如表1所示,以编程语言为PHP语言编码为例,表1中示出了完成创建一个redis实例并调用其incr方法的程序代码的不同写法。
表1
对上述四种示例中,最后调用其incr方法的代码字符序列进行词法分析后,得到的token序列差距较大,具体如下所示(其中省略了token类型):
[‘Lib\Redis’,‘::’,‘init’,‘->’,‘incr’]
[‘$a’,‘->’,‘incr’]
[‘$b’,’->’,‘incr’]
[‘$this’,‘->’,‘redis’,‘->’,‘incr’]
因此,服务器可以预先根据自定义变量与原子级变量构建反向变量哈希映射,例如,服务器可将上述示例中的“$a”、“$b”以及“$this->redis”,与原子级变量“Lib\Redis::init()”构建反向变量哈希映射,后续在对代码文件进行词法分析前,可以根据反向变量哈希映射,将“$a->incr”、“$b->incr”、“$this->redis->incr”以及“Redis::init()->incr”都归一化为“Lib\Redis::init()->incr”,后续对变量归一化后的代码字符序列进行词法分析,即可得到相同的单词序列,从而提高转换后的单词序列的数据质量。
参见图6,图6为一个实施例中构建反向变量哈希映射的流程示意图。在本实施例中,根据预先构建的反向变量哈希映射,将入口函数的代码字符序列中的自定义变量替换为原子级变量的步骤之前,还包括:
步骤502,获取预设的第一正则表达式,根据第一正则表达式提取代码文件中的变量赋值表达式。
其中,第一正则表达式包括用于提取变量定义的正则表达式、变量赋值的正则表达式,可以由开发人员根据代码编程的规则设置。
例如,以编程语言为PHP语言编码为例,用于提取变量定义的正则表达可以如下:
“/(?:Logic|Ctrl)/(\w*.php):\s*(\$[^\s]*)\s*=\s*((?:new|)\s*Lib\\\\.*\([^\(\)]*\))”;
用于提取变量赋值的正则表达式可以如下:
“'\s*(\$[^\s]*)\s*=\s*((?:new|)\s*Lib\\\\.*\([^\(\)]*\))'”。
具体地,开发人员可以预先设置好第一正则表达式,服务器在获取到代码文件后,根据预设的第一正则表达式提取代码文件中所有的变量赋值表达式。
步骤504,从变量赋值表达式中提取自定义变量以及自定义变量对应的原子级变量,根据自定义变量以及原子级变量构建反向变量哈希映射。
其中,变量赋值表达式是指通过复制运算符将变量与表达式相连接,将赋值运算符右侧表达式或变量的值赋给左侧的变量的表达式。
具体地,服务器将变量赋值表达式中赋值运算符左侧的包含有符号“$”的变量确定为自定义变量,将变量赋值表达式中赋值运算符右侧的表达式或原子操作确定为自定义变量对应的原子级变量,从而根据自定义变量以及对应的原子级变量生成反向变量哈希映射。
例如,以编程语言为PHP语言编码的一段代码为例,代码如下式:
$a=Lib\Redis::init();
$a->incr();
上述代码字符序列中“$a=Lib\Redis::init()”即为变量赋值表达式,实现表示将redis实例赋值给本地自定义变量$a的操作,后续本地自定义变量$a调用incr方法,实现创建一个redis实例并调用其incr方法。
其中,服务器将赋值运算符“=”的左侧自定义变量“$a”确定为自定义变量,将赋值运算符“=”的右侧表示式“Lib\Redis::init()”确定为该自定义变量的原子级变量,并构建自定义变量“$a”以及表示式“Lib\Redis::init()”间的哈希映射作为反向变量哈希映射。
在一个实施例中,在从变量赋值表达式中提取自定义变量以及自定义变量对应的原子级变量的步骤之前,服务器可以将声明使用命名空间的自定义变量对应原子级变量的简写展开为原子级变量的全称,后续根据自定义变量以及原子级变量的全程构建为反向变量哈希映射。
以编程语言为PHP语言编码的一段代码为例,代码如下式:
use Lib;
…
$b=Redis::init();
$b->incr();
上述代码实现在文件头声明使用命名空间Lib,并将redis实例赋值给本地自定义变量$b,后续本地自定义变量$b调用incr方法,实现创建一个redis实例并调用其incr方法;代码中的“$b=Redis::init()”即为变量赋值表达式,其中由于使用了命名空间Lib,服务器可以将原子级变量的简称“Redis::init()”展开为原子级变量的全称“Lib\Redis::init()”,使得完成同一功能的代码转化为相同的字符序列,大大降低用户自定义标识符的复杂性和多样性。
参见图7,图7为另一个实施例中构建反向变量哈希映射的流程示意图。在本实施例中,根据自定义变量以及原子级变量构建反向变量哈希映射的步骤,包括:
步骤602,获取变量赋值表达式所在的代码文件的类信息以及位置信息;
步骤604,根据自定义变量、对应的原子级变量、类信息以及位置信息生成变量哈希映射;
步骤606,根据类信息以及代码文件的类继承关系,将变量哈希映射转换为反向变量哈希映射。
其中,类信息是变量赋值表达式中自定义变量所属的类信息,可以用变量赋值表达式所在的代码文件的文件信息进行表示;位置信息是指变量赋值表达式所在代码文件的行信息。
具体的,变量哈希映射(Variable Map,VM)的表达式可以如下式所示:
VM={Ki:[(Vj,Fj,Lj)]},1≤i≤n,1≤j≤mi
其中,VM表示变量哈希映射,n表示代码文件中自定义变量的总数量;Ki表示第i个自定义变量,Ki在项目代码里可以有mi种方式被替换,每一种替换方式由元组(Vj,Fj,Lj)表示:Vj表示与自定义变量对应原子级变量,Fj表示自定义变量所属的类信息,Lj表示自定义变量所在代码文件内的位置信息。
由于父类的数据成员会被子类继承,服务器可以根据父类与子类间的继承关系扩展变量哈希映射。假设自定义变量Ki是父类F1定义的数据成员,在变量哈希映射里存在映射关系Ki:[(V1,F1,L1)],在父类与子类的继承关系中父类对象F1具有子类对象F2,那么在子类对象F2中的自定义变量Ki也被替换为原子级变量V1,即变量哈希映射的表达式为“Ki:[(V1,F1,L1),(V1,F2,L2)]”。
服务器在获取到根据类继承关系扩展的变量哈希映射后,将变量哈希映射进一步转换为反向变量哈希映射(Reversed Variable Map,RVM),反向变量哈希映射的表达式可以为:
RVM={Fi:{Ki:[(Vj,Lj)]}},1≤i≤n,1≤j≤mi
其中,RVM表示反向变量哈希映射,n表示代码文件中自定义变量的总数量;Ki表示第i个自定义变量:Vj表示与自定义变量对应原子级变量,Fi表示自定义变量的文件信息;Lj表示自定义变量所在代码文件内的位置信息。该表达式表示在文件Fi中第Lj行的变量Ki会被替换为Vj。
进一步的,在一个实施例中,根据类信息以及代码文件的类继承关系,将变量哈希映射转换为反向变量哈希映射的步骤,可以包括:以继承关系表达式作为关键字,提取代码文件中的类继承关系;根据类继承关系生成父类哈希映射;利用父类哈希映射扩展变量哈希映射,得到反向变量哈希映射。
现代复杂软件工程项目的代码文件大多使用面向对象编程范型,围绕类和对象来做设计、利用继承以达到代码重用和可扩展性。服务器可以将继承关系表达式作为关键字,从代码文件中提取类继承关系,用于后续辅助提取变量映射和提取函数定义体。
例如,以PHP编程语言为例,在PHP编程语言中继承关系的代码语句为:
“class B extends A”
其中“extends”是继承关系表达式,即B是A的子类。此外,python、c++、java等编程语言均有相应的继承关系表达式。
服务器根据继承关系表达式从代码文件查找到继承关系的代码语句后,可以从该代码语句获取子类名B和父类名A,并生成父类名A与子类名B继承关系。
服务器可以将类继承关系存储到父类哈希映射(Parent Map,PM),父类哈希映射的表达式可以:
PM={Pi:[Cj]},1≤i≤n,1≤j≤mi
其中,n表示父类数目,mi表示第i个父类可以对应mi个子类,Pi为父类名,Cj为子类名。
服务器在获得父类哈希映射后,利用父类哈希映射扩展变量哈希映射,从而根据各个变量的类信息将变量哈希映射转换成反向变量哈希映射。
参见图8,图8为一个实施例中构建函数体哈希映射的流程示意图。在本实施中,根据预先构建的函数体哈希映射将函数调用代码替换为被调用函数的函数体,得到过程式函数代码的步骤之前,还包括:
步骤702,获取预设的第二正则表达式,根据第二正则表达式提取代码文件中的函数定义式并获取函数定义式中的函数名。
其中,第二正则表达式包括用于提取函数定义的正则表达式,可以由开发人员根据代码编程的规则设置。例如,以编程语言为PHP语言编码为例,用于提取函数定义的正则表达可以如下:
“(?:Logic|Ctrl)/(\w*.php):\s*(?:static|)\s*[public|private|protected]*\s*(?:static|)\s*function\s+(\w*)\([^\)]*\)\s*\{?”。
具体地,开发人员可以预先设置好第二正则表达式,服务器在获取到代码文件后,根据预设的第二正则表达式提取代码文件中所有的函数定义式,并从函数定义式中读取函数名。
步骤704,从函数定义式所在代码行起,对代码文件的代码字符序列行进行扫描,获取函数定义式对应的函数体。
具体地,服务器在代码文件里读到函数定义式的位置,从函数定义式所在行开始,逐行扫描,提取得到函数定义式中对应的函数体,其中,函数体可以用Bj表示:
Bj=[(Line,Num),…]
其中,Line表示单行的代码字符序列,Num表示代码字符序列在代码文件中的行号。
步骤706,根据函数定义式的函数名以及函数体,构建函数体哈希映射。
具体地,服务器获取到函数体Bj后,根据函数定义式的函数名以及对应的函数体,构建函数体哈希映射。
例如,函数体哈希映射(Function Body Map,FBM)的表达式可以如下:
FBM={Func i:[(Fj,Bj)]},1≤i≤n,1≤j≤mi
其中,n表示自定义函数的数量,Func i是第i个自定义函数对应的函数名,同一个函数名可以在不同作用域被重用以及在同一个作用域被重载,因此Func i对应一个列表,列表长度为mi,列表中每一项由元组(Fj,Bj)表示,Fj表示自定义函数所属的类信息。
进一步的,由于父类中的成员方法会被子类继承,在一个实施例中,服务器可根据类信息以及代码文件的类继承关系,扩展函数体哈希映射。假设自定义函数Func i是父类F1中定义的函数,在函数体哈希映射里存在映射关系Func i:[(F1,Bj)],在父类与子类的继承关系中,父类对象F1具有子类对象F2,那么在子类对象F2中的自定义函数Func i也被替换为函数体Bj,即函数体哈希映射的表达式为Func i:[(F1,Bj),(F2,Bj)]。
在一个实施例中,对过程式函数代码进行词法分析,得到代码文件对应的单词序列的步骤,包括:根据预设构词规则,对过程式函数代码进行分词处理;根据分词处理结果获取代码文件的单词序列。
其中,预设构词规则可以根据实际的代码设置,使得分词处理可以将涉及业务逻辑的标识符组合切分为同一分词,实现提升单词序列对对业务逻辑相关标识符的表达能力。
具体地,服务器可以通过继承机制扩展pygments词法分析器,使得pygments词法分析器实现表达跟业务逻辑相关的单词序列,比如“$redis”,pygments词法分析器默认将“$redis”标识为“VARIABLE”,表示为自定义变量,但部分在程序代码中,$redis可以指在redis实例的实例名,是具有特殊意义的变量,此时可根据该构词规则生成表示自定义代码语义的正则表达式,并通过继承机制写入至pygments工具中,服务器在后续实现词法分析时,将“$redis”标识为“REDIS_INST”。
参见图9,图9为一个实施例中词法分析方法的流程示意图。该词法分析方法可以应用于图1的服务器中,参照图9,该词法分析方法具体包括以下步骤:
在预处理阶段中,服务器在获取到具有复杂层级结构的代码文件后,分析代码文件的层级结构,获取代码文件的入口函数以及代码文件中的类继承关系,并根据类继承关系构建父类哈希映射,父类哈希映射用于后续为提取反向变量哈希映射以及函数体哈希映射提供基础;
服务器从代码文件中提取变量映射,得到变量哈希映射,并利用父类哈希映射扩展变量哈希映射,以获取代码文件中所有自定义变量与原子级变量的映射关系,将变量哈希映射转换为反向变量哈希映射,其中反向变量哈希映射标识在某一代码文件/父类中自定义变量与原子级变量间的映射关系;
同时,服务器从代码文件中提取函数定义式,将函数定义式对应的函数名以及函数体保存到函数体哈希映射中,并利用父类哈希映射扩展函数体哈希映射;
经过预处理阶段,服务器最终获得代码文件中的一个或一组入口函数、向变量哈希映射以及函数体哈希映射。
在转化阶段,服务器根据预先构建的反向变量哈希映射,将所述入口函数的代码字符序列中的自定义变量替换为原子级变量,得到变量归一化后的代码字符序列;
同时,获取所述变量归一化后的代码字符序列中的函数调用代码,根据预先构建的函数体哈希映射将所述函数调用代码替换为被调用函数的函数体,得到过程式函数代码;
服务器在得到归一化后的过程式函数代码后,可以对该过程式函数代码逐行进行词法分析。
经过预处理和转换,服务器将具有复杂层级结构的代码文件转换得到一组token序列,其中,token序列数目等于代码入口函数的数目。
应该理解的是,虽然图3-8的流程图中的各个步骤按照箭头的指示依次显示,但是这些步骤并不是必然按照箭头指示的顺序依次执行。除非本文中有明确的说明,这些步骤的执行并没有严格的顺序限制,这些步骤可以以其它的顺序执行。而且,图3-8中的至少一部分步骤可以包括多个子步骤或者多个阶段,这些子步骤或者阶段并不必然是在同一时刻执行完成,而是可以在不同的时刻执行,这些子步骤或者阶段的执行顺序也不必然是依次进行,而是可以与其它步骤或者其它步骤的子步骤或者阶段的至少一部分轮流或者交替地执行。
在一个实施例中,如图10所示,提供了一种词法分析装置800,包括:入口函数获取模块802、变量归一模块804、函数展开模块806和词法分析模块808,其中:
入口函数获取模块802,用于获取代码文件并确定代码文件的入口函数,读取入口函数的代码字符序列;
变量归一模块804,用于根据预先构建的反向变量哈希映射,将入口函数的代码字符序列中的自定义变量替换为原子级变量,得到变量归一化后的代码字符序列;
函数展开模块806,用于获取变量归一化后的代码字符序列中的函数调用代码,根据预先构建的函数体哈希映射将函数调用代码替换为被调用函数的函数体,得到过程式函数代码;
词法分析模块808,用于对过程式函数代码进行词法分析,得到代码文件对应的单词序列。
在一个实施例中,函数展开模块806,用于逐行扫描变量归一化后的代码字符序列;当代码字符序列为函数调用代码时,从函数调用代码中获取被调用函数的函数名;根据被调用函数的函数名,从函数体哈希映射中获取与被调用函数的函数体,将代码字符序列中的函数调用代码替换为被调用函数的函数体。
在一个实施例中,函数展开模块806,还用于逐行扫描被调用函数的函数体中的代码字符序列;当被调用函数的函数体中的函数体中的代码字符序列为函数调用代码时,从函数调用代码中获取被调用函数的函数名;根据被调用函数的函数名,从函数体哈希映射中获取与被调用函数的函数体,将代码字符序列中的函数调用代码替换为被调用函数的函数体。
在一个实施例中,词法分析装置还包括反向变量哈希映射构建模块。反向变量哈希映射构建模块,用于获取预设的第一正则表达式,根据第一正则表达式提取代码文件中的变量赋值表达式;从变量赋值表达式中提取自定义变量以及自定义变量对应的原子级变量,根据自定义变量以及原子级变量构建反向变量哈希映射。
在一个实施例中,反向变量哈希映射构建模块,具体用于获取变量赋值表达式所在的代码文件的类信息以及位置信息;根据自定义变量、对应的原子级变量、类信息以及位置信息生成变量哈希映射;根据类信息以及代码文件的类继承关系,将变量哈希映射转换为反向变量哈希映射。
在一个实施例中,词法分析模块,用于根据预设构词规则,对过程式函数代码进行分词处理;根据分词处理结果获取代码文件的单词序列。
在一个实施例中,词法分析装置还包括函数体哈希映射构建模块。函数体哈希映射构建模块,用于获取预设的第二正则表达式,根据第二正则表达式提取代码文件中的函数定义式并获取函数定义式中的函数名;从函数定义式所在代码行起,对代码文件的代码字符序列行进行扫描,获取函数定义式对应的函数体;根据函数定义式的函数名以及函数体,构建函数体哈希映射。
在一个实施例中,本申请提供的词法分析装置可以实现为一种计算机程序的形式,计算机程序可在如图2所示的计算机设备上运行。计算机设备的存储器中可存储组成该词法分析装置的各个程序模块,比如,图10所示的入口函数获取模块802、变量归一模块804、函数展开模块806和词法分析模块808,其中。各个程序模块构成的计算机程序使得处理器执行本说明书中描述的本申请各个实施例的词法分析方法中的步骤。
例如,图2所示的计算机设备可以通过如图10所示的词法分析装置800中的入口函数获取模块802执行步骤202。计算机设备可通过变量归一模块804执行步骤204。计算机设备可通过函数展开模块806执行步骤206。计算机设备可通过词法分析模块808执行步骤208.
在一个实施例中,提供了一种计算机设备,包括存储器和处理器,存储器存储有计算机程序,计算机程序被处理器执行时,使得处理器执行上述词法分析方法的步骤。此处词法分析方法的步骤可以是上述各个实施例的词法分析方法中的步骤。
在一个实施例中,提供了一种计算机可读存储介质,存储有计算机程序,计算机程序被处理器执行时,使得处理器执行上述词法分析方法的步骤。此处词法分析方法的步骤可以是上述各个实施例的词法分析方法中的步骤。
本领域普通技术人员可以理解实现上述实施例方法中的全部或部分流程,是可以通过计算机程序来指令相关的硬件来完成,所述的程序可存储于一非易失性计算机可读取存储介质中,该程序在执行时,可包括如上述各方法的实施例的流程。其中,本申请所提供的各实施例中所使用的对存储器、存储、数据库或其它介质的任何引用,均可包括非易失性和/或易失性存储器。非易失性存储器可包括只读存储器(ROM)、可编程ROM(PROM)、电可编程ROM(EPROM)、电可擦除可编程ROM(EEPROM)或闪存。易失性存储器可包括随机存取存储器(RAM)或者外部高速缓冲存储器。作为说明而非局限,RAM以多种形式可得,诸如静态RAM(SRAM)、动态RAM(DRAM)、同步DRAM(SDRAM)、双数据率SDRAM(DDRSDRAM)、增强型SDRAM(ESDRAM)、同步链路(Synchlink)DRAM(SLDRAM)、存储器总线(Rambus)直接RAM(RDRAM)、直接存储器总线动态RAM(DRDRAM)、以及存储器总线动态RAM(RDRAM)等。
以上实施例的各技术特征可以进行任意的组合,为使描述简洁,未对上述实施例中的各个技术特征所有可能的组合都进行描述,然而,只要这些技术特征的组合不存在矛盾,都应当认为是本说明书记载的范围。
以上所述实施例仅表达了本申请的几种实施方式,其描述较为具体和详细,但并不能因此而理解为对本申请专利范围的限制。应当指出的是,对于本领域的普通技术人员来说,在不脱离本申请构思的前提下,还可以做出若干变形和改进,这些都属于本申请的保护范围。因此,本申请专利的保护范围应以所附权利要求为准。
Claims (10)
1.一种词法分析方法,包括:
获取代码文件并确定所述代码文件的入口函数,读取所述入口函数的代码字符序列;
根据预先构建的反向变量哈希映射,将所述入口函数的代码字符序列中的自定义变量替换为原子级变量,得到变量归一化后的代码字符序列;
获取所述变量归一化后的代码字符序列中的函数调用代码,根据预先构建的函数体哈希映射将所述函数调用代码替换为被调用函数的函数体,得到过程式函数代码;
对所述过程式函数代码进行词法分析,得到所述代码文件对应的单词序列。
2.根据权利要求1所述的方法,其特征在于,所述根据预先构建的函数体哈希映射将所述函数调用代码替换为被调用函数的函数体的步骤,包括:
逐行扫描所述变量归一化后的代码字符序列;
当代码字符序列为函数调用代码时,从函数调用代码中获取被调用函数的函数名;
根据所述被调用函数的函数名,从所述函数体哈希映射中获取与所述被调用函数的函数体,将所述代码字符序列中的函数调用代码替换为所述被调用函数的函数体。
3.根据权利要求2所述的方法,其特征在于,所述将所述代码字符序列中的函数调用代码替换为所述被调用函数的函数体的步骤之后,还包括:
逐行扫描所述被调用函数的函数体中的代码字符序列;
当所述被调用函数的函数体中的代码字符序列为函数调用代码时,跳转至从函数调用代码中获取被调用函数的函数名的步骤。
4.根据权利要求1所述的方法,其特征在于,所述根据预先构建的反向变量哈希映射,将所述入口函数的代码字符序列中的自定义变量替换为原子级变量的步骤之前,还包括:
获取预设的第一正则表达式,根据所述第一正则表达式提取所述代码文件中的变量赋值表达式;
从所述变量赋值表达式中提取自定义变量以及所述自定义变量对应的原子级变量,根据所述自定义变量以及所述原子级变量构建反向变量哈希映射。
5.根据权利要求4所述的方法,其特征在于,所述根据所述自定义变量以及所述原子级变量构建反向变量哈希映射的步骤,包括:
获取变量赋值表达式所在的代码文件的类信息以及位置信息;
根据所述自定义变量、对应的原子级变量、类信息以及位置信息生成变量哈希映射;
根据类信息以及所述代码文件中的类继承关系,将所述变量哈希映射转换为反向变量哈希映射。
6.根据权利要求2所述的方法,其特征在于,所述根据预先构建的函数体哈希映射将所述函数调用代码替换为被调用函数的函数体的步骤之前,还包括:
获取预设的第二正则表达式,根据所述第二正则表达式提取所述代码文件中的函数定义式并获取所述函数定义式中的函数名;
从所述函数定义式所在代码行起,对所述代码文件的代码字符序列行进行扫描,获取所述函数定义式对应的函数体;
根据所述函数定义式的函数名以及函数体,构建函数体哈希映射。
7.根据权利要求1所述的方法,其特征在于,所述对所述过程式函数代码进行词法分析,得到所述代码文件对应的单词序列的步骤,包括:
根据预设构词规则,对所述过程式函数代码进行分词处理;
根据分词处理结果获取所述代码文件的单词序列。
8.一种词法分析装置,其特征在于,所述装置包括:
入口函数获取模块,用于获取代码文件并确定所述代码文件的入口函数,读取所述入口函数的代码字符序列;
变量归一模块,用于根据预先构建的反向变量哈希映射,将所述入口函数的代码字符序列中的自定义变量替换为原子级变量,得到变量归一化后的代码字符序列;
函数展开模块,用于获取所述变量归一化后的代码字符序列中的函数调用代码,根据预先构建的函数体哈希映射将所述函数调用代码替换为被调用函数的函数体,得到过程式函数代码;
词法分析模块,用于对所述过程式函数代码进行词法分析,得到所述代码文件对应的单词序列。
9.一种计算机设备,包括存储器和处理器,所述存储器存储有计算机程序,其特征在于,所述处理器执行所述计算机程序时实现权利要求1至7中任一项所述方法的步骤。
10.一种计算机可读存储介质,其上存储有计算机程序,其特征在于,所述计算机程序被处理器执行时实现权利要求1至7中任一项所述的方法的步骤。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201910720528.9A CN110413284B (zh) | 2019-08-06 | 2019-08-06 | 词法分析方法、装置、计算机设备和存储介质 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201910720528.9A CN110413284B (zh) | 2019-08-06 | 2019-08-06 | 词法分析方法、装置、计算机设备和存储介质 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN110413284A true CN110413284A (zh) | 2019-11-05 |
CN110413284B CN110413284B (zh) | 2023-10-17 |
Family
ID=68366025
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201910720528.9A Active CN110413284B (zh) | 2019-08-06 | 2019-08-06 | 词法分析方法、装置、计算机设备和存储介质 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN110413284B (zh) |
Cited By (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN111651164A (zh) * | 2020-04-29 | 2020-09-11 | 南京航空航天大学 | 代码标识符的归一化方法、装置 |
CN113779311A (zh) * | 2020-11-04 | 2021-12-10 | 北京沃东天骏信息技术有限公司 | 一种数据处理的方法、装置和存储介质 |
Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
JP2010191598A (ja) * | 2009-02-17 | 2010-09-02 | Mitsubishi Electric Corp | 情報処理装置及び情報処理方法及びプログラム |
CN107341399A (zh) * | 2016-04-29 | 2017-11-10 | 阿里巴巴集团控股有限公司 | 评估代码文件安全性的方法及装置 |
CN108614707A (zh) * | 2018-04-27 | 2018-10-02 | 深圳市腾讯网络信息技术有限公司 | 静态代码检查方法、装置、存储介质和计算机设备 |
-
2019
- 2019-08-06 CN CN201910720528.9A patent/CN110413284B/zh active Active
Patent Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
JP2010191598A (ja) * | 2009-02-17 | 2010-09-02 | Mitsubishi Electric Corp | 情報処理装置及び情報処理方法及びプログラム |
CN107341399A (zh) * | 2016-04-29 | 2017-11-10 | 阿里巴巴集团控股有限公司 | 评估代码文件安全性的方法及装置 |
CN108614707A (zh) * | 2018-04-27 | 2018-10-02 | 深圳市腾讯网络信息技术有限公司 | 静态代码检查方法、装置、存储介质和计算机设备 |
Cited By (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN111651164A (zh) * | 2020-04-29 | 2020-09-11 | 南京航空航天大学 | 代码标识符的归一化方法、装置 |
CN113779311A (zh) * | 2020-11-04 | 2021-12-10 | 北京沃东天骏信息技术有限公司 | 一种数据处理的方法、装置和存储介质 |
Also Published As
Publication number | Publication date |
---|---|
CN110413284B (zh) | 2023-10-17 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN108614707A (zh) | 静态代码检查方法、装置、存储介质和计算机设备 | |
Cummins et al. | Programl: A graph-based program representation for data flow analysis and compiler optimizations | |
CN111708539B (zh) | 一种应用程序代码转换方法、装置、电子设备和存储介质 | |
CN109426615A (zh) | 过程间的空指针解引用检测方法、系统、设备以及介质 | |
WO2018222327A1 (en) | Automated or machine-enhanced source code debugging | |
CN110413284A (zh) | 词法分析方法、装置、计算机设备和存储介质 | |
Lano et al. | Agile specification of code generators for model-driven engineering | |
JP4951416B2 (ja) | プログラム検証方法、プログラム検証装置 | |
CN109948309A (zh) | 一种代码保护方法、装置、计算机设备和存储介质 | |
CN109491884A (zh) | 代码性能检测方法、装置、计算机设备和介质 | |
CN116166236A (zh) | 代码推荐方法、装置、计算机设备及存储介质 | |
Prowell | TML: A description language for Markov chain usage models | |
CN113961768B (zh) | 敏感词检测方法、装置、计算机设备和存储介质 | |
CN116340940A (zh) | 代码识别方法、终端设备及存储介质 | |
EP3637249A1 (en) | Systems and methods for validating domain specific models | |
CN109325217A (zh) | 一种文件转换方法、系统、装置及计算机可读存储介质 | |
CN109359176A (zh) | 数据提取方法、装置、计算机设备和存储介质 | |
CN117113083A (zh) | 样本数据的生成方法和大型语言模型的训练方法 | |
CN113076089B (zh) | 一种基于对象类型的api补全方法 | |
Cummins et al. | Deep data flow analysis | |
CN113010550B (zh) | 结构化数据的批处理对象生成、批处理方法和装置 | |
Bajwa et al. | UCD-generator-A LESSA application for use case design | |
CN109344385A (zh) | 自然语言处理方法、装置、计算机设备和存储介质 | |
CN113805861A (zh) | 基于机器学习的代码生成方法、代码编辑系统及存储介质 | |
CN109299004B (zh) | 关键元素差异性分析方法及系统 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |