CN108549535A - 一种基于文件依赖关系的高效程序解析方法和系统 - Google Patents

一种基于文件依赖关系的高效程序解析方法和系统 Download PDF

Info

Publication number
CN108549535A
CN108549535A CN201810218332.5A CN201810218332A CN108549535A CN 108549535 A CN108549535 A CN 108549535A CN 201810218332 A CN201810218332 A CN 201810218332A CN 108549535 A CN108549535 A CN 108549535A
Authority
CN
China
Prior art keywords
syntax tree
file
abstract syntax
header file
parsing
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
Application number
CN201810218332.5A
Other languages
English (en)
Other versions
CN108549535B (zh
Inventor
高庆
马森
张世琨
张君福
朱何龙
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Beijing Beida Software Engineering Ltd By Share Ltd
Peking University
Original Assignee
Beijing Beida Software Engineering Ltd By Share Ltd
Peking University
Priority date (The priority date 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 date listed.)
Filing date
Publication date
Application filed by Beijing Beida Software Engineering Ltd By Share Ltd, Peking University filed Critical Beijing Beida Software Engineering Ltd By Share Ltd
Priority to CN201810218332.5A priority Critical patent/CN108549535B/zh
Publication of CN108549535A publication Critical patent/CN108549535A/zh
Application granted granted Critical
Publication of CN108549535B publication Critical patent/CN108549535B/zh
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/42Syntactic analysis
    • G06F8/427Parsing

Landscapes

  • Engineering & Computer Science (AREA)
  • General Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Software Systems (AREA)
  • Physics & Mathematics (AREA)
  • General Physics & Mathematics (AREA)
  • Devices For Executing Special Programs (AREA)
  • Stored Programmes (AREA)

Abstract

本发明提供了一种基于文件依赖关系的高效程序解析方法和系统,该方法包括:S1,对源文件进行分割处理,获取对应的预处理单元集合;S2,对预处理单元集合中的每个预处理单元执行以下处理:若确认预处理单元的类型为预处理指令中的文件包含指令,则提取预处理单元中的头文件;若确认存在通过预先解析头文件获取到的抽象语法树,则将头文件的抽象语法树链接至源文件的抽象语法树;若确认不存在通过预先解析头文件获取到的抽象语法树,则将头文件作为源文件执行步骤S1和S2以对头文件进行解析。本发明判断头文件是否被预先解析,将预先解析得到的抽象语法树链接至源文件的抽象语法树,避免相同头文件的重复解析,减少了程序解析时间。

Description

一种基于文件依赖关系的高效程序解析方法和系统
技术领域
本发明涉及程序分析技术领域,具体涉及一种基于文件依赖关系的高效程序解析方法和系统。
背景技术
解析是程序分析的第一步,目标是从程序源代码产生抽象语法树(AbstractSyntax Tree,AST)。一棵抽象语法树描述了程序的层次,如图1所示,为一个main函数的抽象语法树,其抽象语法树具体包括根结点(TranslationUnit)和一棵关于函数声明(MethodDeclaration)的子树组成,其中函数声明中又包含了函数返回类型(PrimitiveType)、函数名(SimpleName)以及函数体(Block),函数体包括返回语句(ReturnStatement)和数字文字(NumberLiteral)。一个解析单元对应于一个源文件,由于该示例函数比较简单,因此该例中单个函数声明组成了一个解析单元。
解析的过程包括词法分析和语法分析两个部分;词法分析把源程序拆解为记号;语法分析根据词法分析的结果,把记号组合成语法单元,进而通过预处理和对预处理后语法单元的分析形成一棵抽象语法树。
现有的针对程序解析的静态分析方法存在较大的效率问题。由于缺陷检测首先需要知道程序的语法结构,如果不能很快地解析出抽象语法树,整个检测速度将随之变慢。如图2所示,每个源文件都是通过一个单独的进程被解析为一棵抽象语法树(即AST);然而,每个源文件可能包括一些头文件,这些头文件在不同的源文件中都被包含,因而在整个解析过程中被重复解析。
现有技术中已经存在针对头文件重复解析问题的研究,但是当前研究只在编译领域解决该问题,而在静态分析领域中尚缺乏解决该问题的技术;其次,当前研究由于针对编译进行优化,而在编译时每个文件都是通过独立的进程运行的,因此跨文件的抽象语法树难以实现内存共享,现有的编译加速技术在全程序分析的场景下难以应用。
发明内容
针对现有技术中存在的上述缺陷,本发明提供一种基于文件依赖关系的高效程序解析方法和系统。
本发明的一方面提供一种程序解析方法,包括S1,对源文件进行分割处理,获取对应的预处理单元集合;S2,对预处理单元集合中的每个预处理单元执行以下处理:若确认预处理单元的类型为预处理指令中的文件包含指令,则提取预处理单元中的头文件;若确认存在通过预先解析头文件获取到的抽象语法树,则将头文件对应的抽象语法树链接至源文件对应的抽象语法树;若确认不存在通过预先解析头文件获取到的抽象语法树,则将头文件作为源文件执行步骤S1和S2以对头文件进行解析,并将解析后获取的头文件对应的抽象语法树链接至源文件对应的抽象语法树;若确认预处理单元的类型不为预处理指令中的文件包含指令,则对预处理单元进行解析,并将解析后获取的抽象语法树链接至源文件对应的抽象语法树。
其中,所述S1中对源文件进行分割处理的步骤前还包括:初始化源文件对应的抽象语法树,其中,初始化的抽象语法树为不含有结点的空树。
其中,所述S2中若确认存在通过预先解析头文件获取到的抽象语法树的具体包括:根据预先存储的头文件与抽象语法树之间的映射关系,获取头文件对应的抽象语法树;若头文件对应的抽象语法树不为空,则确认存在通过预先解析头文件获取到的抽象语法树;相应地,所述S2中若确认不存在通过预先解析头文件获取到的抽象语法树的步骤具体包括:若头文件对应的抽象语法树为空,则确认不存在通过预先解析头文件获取到的抽象语法树。
其中,所述S2中将解析后获取的头文件对应抽象语法树链接至源文件对应的抽象语法树的步骤具体包括:将头文件对应的抽象语法树上根结点的子树链接至源文件对应的抽象语法树。
本发明的另一方面提供一种程序解析系统,包括:分割模块,用于对源文件进行分割处理,获取对应的预处理单元集合;处理模块,用于对预处理单元集合中的每个预处理单元执行以下处理:若确认预处理单元的类型为预处理指令中的文件包含指令,则提取预处理单元中的头文件;若确认存在通过预先解析头文件获取到的抽象语法树,则将头文件对应的抽象语法树链接至源文件对应的抽象语法树;若确认不存在通过预先解析头文件获取到的抽象语法树,则将头文件作为源文件输入分割模块以对头文件进行解析,并将解析后获取的头文件对应的抽象语法树链接至源文件对应的抽象语法树;若确认预处理单元的类型不为预处理指令中的文件包含指令,则对预处理单元进行解析,并将解析后获取的抽象语法树链接至源文件对应的抽象语法树。
其中,所述分割模块还用于:初始化源文件对应的抽象语法树,其中,初始化的抽象语法树为不含有结点的空树。
其中,所述处理模块具体用于:根据预先存储的头文件与抽象语法树之间的映射关系,获取头文件对应的抽象语法树;若头文件对应的抽象语法树不为空,则确认存在通过预先解析头文件获取到的抽象语法树;若头文件对应的抽象语法树为空,则确认不存在通过预先解析头文件获取到的抽象语法树。
其中,所述处理模块具体用于:将头文件对应的抽象语法树上根结点的子树链接至源文件对应的抽象语法树。
本发明的又一方面提供一种程序解析设备,包括:至少一个处理器;以及与所述处理器通信连接的至少一个存储器,其中:所述存储器存储有可被所述处理器执行的程序指令,所述处理器调用所述程序指令能够执行本发明上述方面提供的程序解析方法,例如包括:S1,对源文件进行分割处理,获取对应的预处理单元集合;S2,对预处理单元集合中的每个预处理单元执行以下处理:若确认预处理单元的类型为预处理指令中的文件包含指令,则提取预处理单元中的头文件;若确认存在通过预先解析头文件获取到的抽象语法树,则将头文件对应的抽象语法树链接至源文件对应的抽象语法树;若确认不存在通过预先解析头文件获取到的抽象语法树,则将头文件作为源文件执行步骤S1和S2以对头文件进行解析,并将解析后获取的头文件对应的抽象语法树链接至源文件对应的抽象语法树;若确认预处理单元的类型不为预处理指令中的文件包含指令,则对预处理单元进行解析,并将解析后获取的抽象语法树链接至源文件对应的抽象语法树。
本发明的又一方面提供一种非暂态计算机可读存储介质,所述非暂态计算机可读存储介质存储计算机指令,所述计算机指令使所述计算机执行本发明上述方面提供的程序解析方法,例如包括:S1,对源文件进行分割处理,获取对应的预处理单元集合;S2,对预处理单元集合中的每个预处理单元执行以下处理:若确认预处理单元的类型为预处理指令中的文件包含指令,则提取预处理单元中的头文件;若确认存在通过预先解析头文件获取到的抽象语法树,则将头文件对应的抽象语法树链接至源文件对应的抽象语法树;若确认不存在通过预先解析头文件获取到的抽象语法树,则将头文件作为源文件执行步骤S1和S2以对头文件进行解析,并将解析后获取的头文件对应的抽象语法树链接至源文件对应的抽象语法树;若确认预处理单元的类型不为预处理指令中的文件包含指令,则对预处理单元进行解析,并将解析后获取的抽象语法树链接至源文件对应的抽象语法树。
本发明提供的基于文件依赖关系的高效程序解析方法和系统,通过判断头文件是否被预先解析,并将预先解析得到的抽象语法树直接链接至源文件的抽象语法树,避免了相同头文件在程序解析过程中的重复解析,减少了程序解析时间,提高了解析效率。
附图说明
为了更清楚地说明本发明实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作一简单地介绍,显而易见地,下面描述中的附图是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。
图1为现有技术提供的示例程序抽象语法树示意图;
图2为现有技术提供的静态分析技术的解析方法示意图;
图3为本发明实施例提供的程序解析方法的流程示意图;
图4为本发明实施例提供的程序解析方法的示例程序的示意图;
图5为本发明实施例提供的程序解析方法的示例程序的解析过程示意图;
图6为本发明实施例提供的程序解析系统的结构示意图;
图7为本发明实施例提供的程序解析设备的结构示意图。
具体实施方式
为使本发明实施例的目的、技术方案和优点更加清楚,下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚地描述,显然,所描述的实施例是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
图3为本发明实施例提供的程序解析方法的流程示意图,如图3所示,包括:S1,对源文件进行分割处理,获取对应的预处理单元集合;S2,对预处理单元集合中的每个预处理单元执行以下处理:若确认预处理单元的类型为预处理指令中的文件包含指令,则提取预处理单元中的头文件;若确认存在通过预先解析头文件获取到的抽象语法树,则将头文件对应的抽象语法树链接至源文件对应的抽象语法树;若确认不存在通过预先解析头文件获取到的抽象语法树,则将头文件作为源文件执行步骤S1和S2以对头文件进行解析,并将解析后获取的头文件对应的抽象语法树链接至源文件对应的抽象语法树;若确认预处理单元的类型不为预处理指令中的文件包含指令,则对预处理单元进行解析,并将解析后获取的抽象语法树链接至源文件对应的抽象语法树。
在步骤S1中,程序可以由一个或多个源文件组成;对于每个源文件,首先使用预处理函数,将源文件分割为预处理单元集合,预处理单元集合包含至少一个预处理单元;每个预处理单元对应的可能是一条预处理指令,也可能是一个函数声明或变量定义。
在步骤S2中,根据步骤S1获取的预处理单元集合,对于集合中每个预处理单元,需要判断预处理单元的类型是否为预处理指令中的包含指令,即“#include”;若为包含指令,则会提取出预处理单元中包含的头文件。
并且,进一步判断该头文件是否被解析过;如果预先解析过,则可以直接获取预先解析时存储的抽象语法树,那么可以直接将该头文件对应的抽象语法树链接到源文件的抽象语法树,避免了对头文件的再次解析,这里也实现了该预处理单元的抽象语法树的解析;而如果没有解析过,就将头文件作为源文件再次输入到步骤S1和S2(即递归执行步骤S1和S2),同样能够获取到头文件的抽象语法树,并将抽象语法树链接到源文件中。
另外,如果预处理单元的类型不为文件包含指令,则直接对预处理单元进行解析,获取到预处理单元对应的抽象语法树,并链接至源文件的抽象语法树。
综上,源文件的抽象语法树由各预处理单元的抽象语法树组成;对于不为文件包含指令类型的预处理单元,按照常规方法进行解析;对于为文件包含指令类型的预处理单元,则根据包含的头文件是否被解析过进行相应处理,同样能够获得预处理单元对应的抽象语法树。
以下对上述本发明实施例提供的程序解析方法进行举例说明,本发明实施例定义PARSE函数进行上述解析方法,具体如下:
PARSE函数的输入为所有源文件的路径集合fileSet,输出为每个源文件对应的抽象语法树集合TUs;对于每个fileSet中的文件file,调用PARSE_FILE函数来解析。
PARSE_FILE函数的输入为一个源文件file,通过预处理函数PREPROCESS,将文件分割为一个预处理单元集合preprocessResult;对于preprocessResult中的每个预处理单元preprocessUnit,首先判断其类型是不是预处理指令中的包含指令,即“#include”。
如果该预处理单元是包含指令,则通过函数GET_INCLUDED_FILE提取出预处理单元中的头文件,并且调用函数GET_TRANSLATION_UNIT尝试获取其抽象语法树。
如果获取到(includedTU不为空,即预先解析过该头文件),则直接将其抽象语法树链接至当前所解析文件(源文件)的抽象语法树translationUnit上;否则,递归调用PARSE_FILE函数,使其解析该被包含的文件(即将头文件作为源文件重复进行步骤S1和S2);解析后,调用ADD_INCLUDED函数,将其抽象语法树链接至当前PARSE_FILE函数所解析文件file的抽象语法树上。
如果该预处理单元不是包含指令,该预处理单元对应的可能是一个函数声明、函数定义、全局变量定义,也可能是关于宏定义的预处理指令,解析结果是一个声明;调用PARSE_DECLARATION函数,直接进行解析;并调用ADD_DECLARATION将整棵树链接至当前文件file的抽象语法树上。
因此,PARSE_FILE函数的参数可能是来源于PARSE函数的源文件,又可能是通过PARSE_FILE自身递归调用的,也就是解析源文件中包含的头文件。
本发明实施例提供的程序解析方法,通过判断头文件是否被预先解析,并将预先解析得到的抽象语法树直接链接至源文件的抽象语法树,避免了相同头文件在程序解析过程中的重复解析,减少了程序解析时间,提高了解析效率。
在上述任一实施例的基础上,所述S1中对源文件进行分割处理的步骤前还包括:初始化源文件对应的抽象语法树,其中,初始化的抽象语法树为不含有结点的空树。
具体地,PARSE_FILE函数的输入为一个文件file后,首先初始化该文件对应的抽象语法树translationUnit,初始值为不含有任何结点的空树(用EMPTY_TU表示)。在解析过程中得到的预处理单元的抽象语法树链接至初始化得到的空树上。
在上述任一实施例的基础上,所述S2中若确认存在通过预先解析头文件获取到的抽象语法树的具体包括:根据预先存储的头文件与抽象语法树之间的映射关系,获取头文件对应的抽象语法树;若头文件对应的抽象语法树不为空,则确认存在通过预先解析头文件获取到的抽象语法树;相应地,所述S2中若确认不存在通过预先解析头文件获取到的抽象语法树的步骤具体包括:若头文件对应的抽象语法树为空,则确认不存在通过预先解析头文件获取到的抽象语法树。
具体地,在程序的解析过程中,对每个头文件进行解析后,都会存储与头文件对应的抽象语法树;并基于存储的映射关系来判断文件是否预先解析过;例如在上述PARSE_FILE函数,用户尝试获取头文件抽象语法树的函数GET_TRANSLATION_UNIT中,存储了从头文件到抽象语法树的映射。
在上述任一实施例的基础上,所述S2中将解析后获取的头文件对应抽象语法树链接至源文件对应的抽象语法树的步骤具体包括:将头文件对应的抽象语法树上根结点的子树链接至源文件对应的抽象语法树。
例如,将头文件抽象语法树上根结点的子树链接至当前PARSE_FILE函数所解析文件file的抽象语法树上。
为了对本发明实施例提供的解析方法进行说明,以下结合图4提供的示例程序进行说明;如图4提供的C++程序示例,该程序由用户写的两个源文件组成,图中的“解析单元”分别代表一个源文件。解析单元1.c中有一个main函数,并且包含了iostream头文件;解析单元2.c中有一个f函数,同样包含了iostream头文件。图中用一个结点“main”和“f”分别代表两个这两个函数,其他结点分别表示头文件。
其中,iostream是C++标准库的头文件,里面又包含了c++config.h和ostream等标准库的头文件,而ostream又包含了ios等头文件,以此类推。因此,通过包含iostream这一个头文件,无论main或者f函数有多么简单的结构,解析器均需要在不同的源文件中对同一个iostream头文件进行重复解析。这造成了大量的时间浪费。
由于重复对同一个头文件进行解析,解析时间与代码量并不是线性关系。在QT(面向对象的框架)项目中该问题尤其突出;QT项目除了使用C++标准库的头文件之外,还使用QT库的头文件。QT是跨平台C++图形用户界面应用程序开发框架,根据调研,在QT项目qtractor中,单个源文件对QT库头文件的包含深度可多达15层。而几乎每个源文件都要使用QT中的一个或多个头文件,从而使解析器重复地解析所有被迭代包含的库文件,使解析速度大幅减缓。
下面结合图5所示的算法详细描述该例的解析过程,其中,函数main和函数b依然通过原有方式解析(用实线箭头表示),但是头文件与解析单元分离(用虚线箭头表示);也就是说,每个头文件不再在解析源文件的时候被解析,而是被单独解析;被单独解析的过程中,该头文件包含的其他头文件不被解析;具体包括如下步骤:
步骤1:按照原有的解析顺序解析各个源文件,假设先解析1.c,后解析2.c。
步骤2:调用PARSE_FILE函数解析1.c;首先进入预处理阶段,发现一条预处理的包含命令:#include<iostream>;然后查找该头文件是否已经被解析。由于iostream头文件是第一次遇到,之前没有被解析过,因此进入步骤3。
步骤3:调用PARSE_FILE函数,解析iostream。类似地,查找c++config.h是否已经被解析。由于c++config.h头文件也是第一次遇到,因此进入步骤4.
步骤4:调用PARSE_FILE函数,解析c++config.h。以类似步骤3的方式类推,继续解析os_defines.h。
步骤5:调用PARSE_FILE函数,解析os_defines.h。由于os_defines.h不再包含头文件,因此调用若干次PARSE_DECLARATION函数后,得到os_defines.h的抽象语法树。
步骤6:返回步骤4所调用的PARSE_FILE函数中,解析其他语法单元得到c++config.h的抽象语法树,然后返回步骤3所调用的PARSE_FILE函数中,解析新遇到的头文件ostream。
步骤7:以类似方式解析ostream,最后调用PARSE_DECLARATION解析main函数,完成1.c的解析。其中,在解析iosfwd时,由于c++config.h的抽象语法树已经存在,因此通过GET_TRANSLATION_UNIT函数获得其抽象语法树,直接跳过c++config.h的解析。同时,将c++config.h的抽象语法树的组成单元链接至iosfwd的抽象语法树中,从而省去了c++config.h的一次解析开销。
步骤8:解析2.c,由于iostream的抽象语法树已经存在,因此直接将iostream的抽象语法树的组成单元链接至2.c的抽象语法树上,从而跳过一整串iostream包含层次上的头文件,只需要解析f函数即得到2.c的抽象语法树。
因此,解析过程采用的是一种递归的方法。值得注意的是,虽然PREPROCESS函数会对包含的同一个头文件进行重复预处理,但是因为每个头文件的预处理命令只有#include一行,因此重复解析的时间开销很低,可以忽略不计。
该方案通过把每个头文件的结果进行记录,可以根据包含关系灵活地组合不同的模块,因此提高了解析效率。每增加一个源文件,就可能增加若干次对头文件的重复分析,使用本方法便可减少若干次对头文件的分析。随着程序规模的增大,时间节省的效果也就越明显。
图6为本发明实施例提供的程序解析系统的结构示意图,如图6所示,包括:分割模块601,用于对源文件进行分割处理,获取对应的预处理单元集合;处理模块602,用于对预处理单元集合中的每个预处理单元执行以下处理:若确认预处理单元的类型为预处理指令中的文件包含指令,则提取预处理单元中的头文件;若确认存在通过预先解析头文件获取到的抽象语法树,则将头文件对应的抽象语法树链接至源文件对应的抽象语法树;若确认不存在通过预先解析头文件获取到的抽象语法树,则将头文件作为源文件输入分割模块以对头文件进行解析,并将解析后获取的头文件对应的抽象语法树链接至源文件对应的抽象语法树;若确认预处理单元的类型不为预处理指令中的文件包含指令,则对预处理单元进行解析,并将解析后获取的抽象语法树链接至源文件对应的抽象语法树。
其中,程序可以由一个或多个源文件组成;对于每个源文件,分割模块601首先使用预处理函数,将源文件分割为预处理单元集合,预处理单元集合包含至少一个预处理单元;每个预处理单元对应的可能是一条预处理指令,也可能是一个函数声明或变量定义。
其中,处理模块602根据分割模块601获取的预处理单元集合,对于集合中每个预处理单元,处理模块602需要判断预处理单元的类型是否为预处理指令中的包含指令,即“#include”;若为包含指令,则会提取出预处理单元中包含的头文件。
并且,处理模块602进一步判断该头文件是否被解析过;如果预先解析过,则处理模块602可以直接获取预先解析时存储的抽象语法树,那么可以直接将该头文件对应的抽象语法树链接到源文件的抽象语法树,避免了对头文件的再次解析,这里也实现了该预处理单元的抽象语法树的解析;而如果没有解析过,就将头文件作为源文件再次输入到分割模块601,并递归利用分割模块601和处理模块602,同样能够获取到头文件的抽象语法树,并将抽象语法树链接到源文件中。
另外,如果预处理单元的类型不为文件包含指令,则处理模块602直接对预处理单元进行解析,获取到预处理单元对应的抽象语法树,并链接至源文件的抽象语法树。
综上,源文件的抽象语法树由各预处理单元的抽象语法树组成;对于不为文件包含指令类型的预处理单元,按照常规方法进行解析;对于为文件包含指令类型的预处理单元,则根据包含的头文件是否被解析过进行相应处理,同样能够获得预处理单元对应的抽象语法树。
本发明实施例提供的程序解析系统,通过判断头文件是否被预先解析,并将预先解析得到的抽象语法树直接链接至源文件的抽象语法树,避免了相同头文件在程序解析过程中的重复解析,减少了程序解析时间,提高了解析效率。
在上述任一实施例的基础上,所述分割模块还用于:初始化源文件对应的抽象语法树,其中,初始化的抽象语法树为不含有结点的空树。
具体地,PARSE_FILE函数的输入为一个文件file后,首先分割模块初始化该文件对应的抽象语法树translationUnit,初始值为不含有任何结点的空树(用EMPTY_TU表示)。在解析过程中得到的预处理单元的抽象语法树链接至初始化得到的空树上。
在上述任一实施例的基础上,所述处理模块具体用于:根据预先存储的头文件与抽象语法树之间的映射关系,获取头文件对应的抽象语法树;若头文件对应的抽象语法树不为空,则确认存在通过预先解析头文件获取到的抽象语法树;若头文件对应的抽象语法树为空,则确认不存在通过预先解析头文件获取到的抽象语法树。
具体地,在程序的解析过程中,处理模块对每个头文件进行解析后,都会存储与头文件对应的抽象语法树;并基于存储的映射关系来判断文件是否预先解析过;例如在上述PARSE_FILE函数,用户尝试获取头文件抽象语法树的函数GET_TRANSLATION_UNIT中,存储了从头文件到抽象语法树的映射。
在上述任一实施例的基础上,所述处理模块具体用于:将头文件对应的抽象语法树上根结点的子树链接至源文件对应的抽象语法树。
例如,处理模块将头文件抽象语法树上根结点的子树链接至当前PARSE_FILE函数所解析文件file的抽象语法树上。
图7为本发明实施例提供的程序解析设备的结构示意图,如图3所示,该设备包括:至少一个处理器701;以及与所述处理器701通信连接的至少一个存储器702,其中:所述存储器702存储有可被所述处理器701执行的程序指令,所述处理器701调用所述程序指令能够执行上述各实施例所提供的程序解析方法,例如包括:S1,对源文件进行分割处理,获取对应的预处理单元集合;S2,对预处理单元集合中的每个预处理单元执行以下处理:若确认预处理单元的类型为预处理指令中的文件包含指令,则提取预处理单元中的头文件;若确认存在通过预先解析头文件获取到的抽象语法树,则将头文件对应的抽象语法树链接至源文件对应的抽象语法树;若确认不存在通过预先解析头文件获取到的抽象语法树,则将头文件作为源文件执行步骤S1和S2以对头文件进行解析,并将解析后获取的头文件对应的抽象语法树链接至源文件对应的抽象语法树;若确认预处理单元的类型不为预处理指令中的文件包含指令,则对预处理单元进行解析,并将解析后获取的抽象语法树链接至源文件对应的抽象语法树。
本发明实施例还提供一种非暂态计算机可读存储介质,该非暂态计算机可读存储介质存储计算机指令,该计算机指令使计算机执行对应实施例所提供的程序解析方法,例如包括:S1,对源文件进行分割处理,获取对应的预处理单元集合;S2,对预处理单元集合中的每个预处理单元执行以下处理:若确认预处理单元的类型为预处理指令中的文件包含指令,则提取预处理单元中的头文件;若确认存在通过预先解析头文件获取到的抽象语法树,则将头文件对应的抽象语法树链接至源文件对应的抽象语法树;若确认不存在通过预先解析头文件获取到的抽象语法树,则将头文件作为源文件执行步骤S1和S2以对头文件进行解析,并将解析后获取的头文件对应的抽象语法树链接至源文件对应的抽象语法树;若确认预处理单元的类型不为预处理指令中的文件包含指令,则对预处理单元进行解析,并将解析后获取的抽象语法树链接至源文件对应的抽象语法树。
以上所描述的程序解析设备等实施例仅仅是示意性的,其中作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部模块来实现本实施例方案的目的。本领域普通技术人员在不付出创造性的劳动的情况下,即可以理解并实施。
通过以上的实施方式的描述,本领域的技术人员可以清楚地了解到各实施方式可借助软件加必需的通用硬件平台的方式来实现,当然也可以通过硬件。基于这样的理解,上述技术方案本质上或者说对现有技术做出贡献的部分可以以软件产品的形式体现出来,该计算机软件产品可以存储在计算机可读存储介质中,如ROM/RAM、磁碟、光盘等,包括若干指令用以使得一台计算机设备(可以是个人计算机,服务器,或者网络设备等)执行各个实施例或者实施例的某些部分方法。
最后应说明的是:以上实施例仅用以说明本发明的技术方案,而非对其限制;尽管参照前述实施例对本发明进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本发明各实施例技术方案的精神和范围。

Claims (10)

1.一种程序解析方法,其特征在于,包括,
S1,对源文件进行分割处理,获取对应的预处理单元集合;
S2,对预处理单元集合中的每个预处理单元执行以下处理:
若确认预处理单元的类型为预处理指令中的文件包含指令,则提取预处理单元中的头文件;
若确认存在通过预先解析头文件获取到的抽象语法树,则将头文件对应的抽象语法树链接至源文件对应的抽象语法树;
若确认不存在通过预先解析头文件获取到的抽象语法树,则将头文件作为源文件执行步骤S1和S2以对头文件进行解析,并将解析后获取的头文件对应的抽象语法树链接至源文件对应的抽象语法树;
若确认预处理单元的类型不为预处理指令中的文件包含指令,则对预处理单元进行解析,并将解析后获取的抽象语法树链接至源文件对应的抽象语法树。
2.根据权利要求1所述的方法,其特征在于,所述S1中对源文件进行分割处理的步骤前还包括:
初始化源文件对应的抽象语法树,其中,初始化的抽象语法树为不含有结点的空树。
3.根据权利要求1所述的方法,其特征在于,所述S2中若确认存在通过预先解析头文件获取到的抽象语法树的具体包括:
根据预先存储的头文件与抽象语法树之间的映射关系,获取头文件对应的抽象语法树;若头文件对应的抽象语法树不为空,则确认存在通过预先解析头文件获取到的抽象语法树;
相应地,所述S2中若确认不存在通过预先解析头文件获取到的抽象语法树的步骤具体包括:
若头文件对应的抽象语法树为空,则确认不存在通过预先解析头文件获取到的抽象语法树。
4.根据权利要求1所述的方法,其特征在于,所述S2中将解析后获取的头文件对应抽象语法树链接至源文件对应的抽象语法树的步骤具体包括:
将头文件对应的抽象语法树上根结点的子树链接至源文件对应的抽象语法树。
5.一种程序解析系统,其特征在于,包括:
分割模块,用于对源文件进行分割处理,获取对应的预处理单元集合;
处理模块,用于对预处理单元集合中的每个预处理单元执行以下处理:
若确认预处理单元的类型为预处理指令中的文件包含指令,则提取预处理单元中的头文件;
若确认存在通过预先解析头文件获取到的抽象语法树,则将头文件对应的抽象语法树链接至源文件对应的抽象语法树;
若确认不存在通过预先解析头文件获取到的抽象语法树,则将头文件作为源文件输入分割模块以对头文件进行解析,并将解析后获取的头文件对应的抽象语法树链接至源文件对应的抽象语法树;
若确认预处理单元的类型不为预处理指令中的文件包含指令,则对预处理单元进行解析,并将解析后获取的抽象语法树链接至源文件对应的抽象语法树。
6.根据权利要求5所述的系统,其特征在于,所述分割模块还用于:初始化源文件对应的抽象语法树,其中,初始化的抽象语法树为不含有结点的空树。
7.根据权利要求5所述的系统,其特征在于,所述处理模块具体用于:根据预先存储的头文件与抽象语法树之间的映射关系,获取头文件对应的抽象语法树;若头文件对应的抽象语法树不为空,则确认存在通过预先解析头文件获取到的抽象语法树;若头文件对应的抽象语法树为空,则确认不存在通过预先解析头文件获取到的抽象语法树。
8.根据权利要求5所述的系统,其特征在于,所述处理模块具体用于:将头文件对应的抽象语法树上根结点的子树链接至源文件对应的抽象语法树。
9.一种程序解析设备,其特征在于,包括:
至少一个处理器;
以及与所述处理器通信连接的至少一个存储器,其中:所述存储器存储有可被所述处理器执行的程序指令,所述处理器调用所述程序指令能够执行如权利要求1至4任一所述的方法。
10.一种非暂态计算机可读存储介质,其特征在于,所述非暂态计算机可读存储介质存储计算机指令,所述计算机指令使所述计算机执行如权利要求1至4任一所述的方法。
CN201810218332.5A 2018-03-16 2018-03-16 一种基于文件依赖关系的高效程序解析方法和系统 Active CN108549535B (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN201810218332.5A CN108549535B (zh) 2018-03-16 2018-03-16 一种基于文件依赖关系的高效程序解析方法和系统

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN201810218332.5A CN108549535B (zh) 2018-03-16 2018-03-16 一种基于文件依赖关系的高效程序解析方法和系统

Publications (2)

Publication Number Publication Date
CN108549535A true CN108549535A (zh) 2018-09-18
CN108549535B CN108549535B (zh) 2021-02-05

Family

ID=63516519

Family Applications (1)

Application Number Title Priority Date Filing Date
CN201810218332.5A Active CN108549535B (zh) 2018-03-16 2018-03-16 一种基于文件依赖关系的高效程序解析方法和系统

Country Status (1)

Country Link
CN (1) CN108549535B (zh)

Cited By (5)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN110109672A (zh) * 2019-04-17 2019-08-09 北京奇安信科技有限公司 一种表达式的解析处理方法及装置
CN112000339A (zh) * 2020-07-09 2020-11-27 北京大学 安卓apk文件依赖组件识别方法及装置
CN112231278A (zh) * 2020-11-03 2021-01-15 百度国际科技(深圳)有限公司 项目工程文件的分析方法、装置、设备及存储介质
CN112379885A (zh) * 2020-11-19 2021-02-19 北京百度网讯科技有限公司 小程序编译方法、装置、设备及可读存储介质
CN115904353A (zh) * 2023-03-02 2023-04-04 上海合见工业软件集团有限公司 一种用户界面的目标源文件的生成方法及系统

Citations (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
EP0432802A2 (de) * 1989-12-15 1991-06-19 Siemens Nixdorf Informationssysteme Aktiengesellschaft Verfahren für die automatische Syntaxanalyse (Parsen) des Textes von Computer-Programmen in Kompilierern
CN101770502A (zh) * 2009-12-30 2010-07-07 深圳市同洲电子股份有限公司 一种脚本处理的方法、装置和嵌入式浏览器
CN106294156A (zh) * 2016-08-11 2017-01-04 北京邮电大学 一种静态代码缺陷检测分析方法及装置
CN106970820A (zh) * 2017-04-26 2017-07-21 腾讯科技(深圳)有限公司 代码存储方法及代码存储装置

Patent Citations (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
EP0432802A2 (de) * 1989-12-15 1991-06-19 Siemens Nixdorf Informationssysteme Aktiengesellschaft Verfahren für die automatische Syntaxanalyse (Parsen) des Textes von Computer-Programmen in Kompilierern
CN101770502A (zh) * 2009-12-30 2010-07-07 深圳市同洲电子股份有限公司 一种脚本处理的方法、装置和嵌入式浏览器
CN106294156A (zh) * 2016-08-11 2017-01-04 北京邮电大学 一种静态代码缺陷检测分析方法及装置
CN106970820A (zh) * 2017-04-26 2017-07-21 腾讯科技(深圳)有限公司 代码存储方法及代码存储装置

Cited By (8)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN110109672A (zh) * 2019-04-17 2019-08-09 北京奇安信科技有限公司 一种表达式的解析处理方法及装置
CN110109672B (zh) * 2019-04-17 2023-01-10 奇安信科技集团股份有限公司 一种表达式的解析处理方法及装置
CN112000339A (zh) * 2020-07-09 2020-11-27 北京大学 安卓apk文件依赖组件识别方法及装置
CN112231278A (zh) * 2020-11-03 2021-01-15 百度国际科技(深圳)有限公司 项目工程文件的分析方法、装置、设备及存储介质
CN112379885A (zh) * 2020-11-19 2021-02-19 北京百度网讯科技有限公司 小程序编译方法、装置、设备及可读存储介质
CN112379885B (zh) * 2020-11-19 2024-04-09 北京百度网讯科技有限公司 小程序编译方法、装置、设备及可读存储介质
CN115904353A (zh) * 2023-03-02 2023-04-04 上海合见工业软件集团有限公司 一种用户界面的目标源文件的生成方法及系统
CN115904353B (zh) * 2023-03-02 2023-06-23 上海合见工业软件集团有限公司 一种用户界面的目标源文件的生成方法及系统

Also Published As

Publication number Publication date
CN108549535B (zh) 2021-02-05

Similar Documents

Publication Publication Date Title
CN108549535A (zh) 一种基于文件依赖关系的高效程序解析方法和系统
US11526531B2 (en) Dynamic field data translation to support high performance stream data processing
CN106547527B (zh) 一种JavaScript文件构建方法及装置
CN106843840B (zh) 一种基于相似度分析的源代码版本演化注释复用方法
US10055399B2 (en) Method and system for linear generalized LL recognition and context-aware parsing
CN107704382A (zh) 面向Python的函数调用路径生成方法和系统
CN108595334B (zh) 一种计算Java程序动态切片的方法、装置及可读存储介质
CN107885501A (zh) 获取Android中组件相互引用关系的方法及装置
CN111008020B (zh) 将逻辑表达式解析为通用查询语句的方法
CN110069259A (zh) 基于idl文件的解析方法、装置、电子设备和存储介质
CN104572231B (zh) 不同操作平台之间的工程移植方法和装置
CN109116828A (zh) 一种控制器中模型代码配置方法和装置
CN110347416B (zh) 脚本的更新方法和装置
CN114443041A (zh) 抽象语法树的解析方法及计算机程序产品
US10642714B2 (en) Mapping dynamic analysis data to source code
CN108897678B (zh) 静态代码检测方法和静态代码检测系统、存储设备
CN108563561B (zh) 一种程序隐性约束提取方法及系统
CN113608748A (zh) C语言转换Java语言的数据处理方法、装置及设备
WO2017065631A1 (en) Method and system for transforming a source code into a target code on a computer
US20180314497A1 (en) Translation of assembler language code using intermediary technical rules language (trl)
CN113779311A (zh) 一种数据处理的方法、装置和存储介质
CN106663094B (zh) 用于线性广义ll识别和上下文感知解析的方法和系统
AU2018313995B2 (en) Systems and methods for providing globalization features in a service management application interface
CN112306470A (zh) 一种复杂同步语言程序的化简转化和自动验证方法
CN110879699A (zh) 领域专用语言dsl的图形化处理方法和设备

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