版权归原作者所有,如有侵权,请联系我们

[科普中国]-程序理解

科学百科
原创
科学百科为用户提供权威科普内容,打造知识科普阵地
收藏

任务

程序理解的任务就是要揭示程序的功能与实现机制,即理解系统的外部行为和内部构造,其具体任务可分解如下。

1)通过检查单个的程序设计结构,程序被表示成抽象语法树、符号表或普通源文本,这其中包括手工代码阅读、人工制品提取、程序分析、静态分析和动态分析几个过程。

2)尽量做到程序隐含信息的显性表示及程序内部关系的可视化。如控制流和数据流分析,各种程序视图的构造等。

3)从源代码中提取信息,并存放在通用的数据库中,然后通过查询语言对数据库进行查询。

4)检查程序构造过程中的结构关系,明确表示程序组成部分之间的依赖关系。

5)识别程序的高层概念,如标准算法、数据结构、语法及语义匹配等。2

内容经过分析,全面、准确、迅速地理解程序,对于软件的开发、维护、质量保证及逆向工程和再工程有着重要意义。不过,程序理解的内容比较多,要讲述程序理解的内容,就必须结合具体的程序设计语言。尽管如此,程序理解一般都包含如下内容:

·程序理解的功能和目标。

·掌握程序的结构信息,即从程序中细分出若干结构成分,如程序系统结构、控制结构、数据结构、输入/输出结构等。

·了解数据流信息,即涉及的数据源于何处,在哪里被使用。

·了解控制流信息,即了解每条路径的结果。

·程序理解的操作(使用)要求。

·面向对象的理解(对象、类、继承、通信等等)。3

相关技术1.语句分析

与自然语言类似,程序文件是由语句构成的,包括标识符、操作符、关键字、字符串、数字、标点符号等词法单元。语句分析分别构造程序的词法模型与语法模型,它们对应于词法分析与语法分析。由于这两种分析不生成任何语义信息,所以它们生成的模型仅仅适用于源代码的模式匹配。

2.程序流分析

程序流分析技术,即在程序运行之前,通过静态分析去发现程序在运行行为方面的某些特性。程序流分析包括控制流分析和数据流分析两种,其中控制流分析侧重于对程序结构的分析,而数据流分析则侧重于对变量控制结构中数据的赋值、使用及传递情况的分析。

程序理解的首要任务是发现它的控制结构,即语句的可能执行路径,通过控制流分析建立过程内部的控制层次。控制流分析可以分为两大类:必经点分析和区间分析,这两种分析方法都是先对程序文本进行分析,将其转化成某种中间表示,然后在中问表示的基础上进行分析,具体选用哪种方法需根据程序理解的任务而定。

数据流分析是为了计算被分析程序在生成数据方面的行为,通常用于程序优化,即为程序优化建立环境。目前,使用最为广泛的方法是对控制流图进行循环分析,称为迭代数据流分析。

由于非结构化程序会给测试、排错和程序维护带来较大的困难,因此按照结构化程序设计的要求,理想的程序设计是尽量避免使用goto语句,程序的控制结构尽量做到单入口、单出口。基于这些原因,在对被测软件进行分析时,系统地检查程序的控制结构成了十分有意义的工作。

3.软件结构图

软件结构图分程序调用关系图(或函数调用关系图)和系统结构图。函数调用关系图或者说是程序调用关系图,都是对源程序中函数关系的一种静态描述,在函数调用关系图中,节点表示函数,边表示函数之间的调用关系。3

基本策略从软件心理学和认知学的角度,通过对维护人员和维护人员理解过程的研究,总结出3种理解策略,并且提出若干相应的模型。

1.自顶向下的程序理解策略

自顶向下理解策略的原则是维护人员从程序的顶层开始,以从上到下的方式逐步理解下层细节。主要的自顶向下模型有Soloway模型等。Soloway在他的模型中采用自顶向下的方法,根据所拥有的知识和假设,把系统分解成能够在代码中实现的预料中的子系统,然后逐个分解每个子系统直到实现既定功能的一个个代码块。用这种方法构造的智力模型由目标和设计的层次构成,利用论述规则把目标分解成设计,继而分解成更低层的设计。该模型使用3种不同的设计类型:

(1)战略性设计,它描述程序中的整体策略;

(2)策略性设计,它与局部的问题解决策略有关;

(3)实现性设计,它考虑实现策略格局的语言的特征。

2.自底向上的理解策略

自底向上理解策略的原则是软件人员自底向上认知程序的模式,聚合这些模式可以得到更有意义的高层结构,然后再按照自底向上的方式把这些高层结构聚合在一起,构成更大的结构,直到程序被完全理解。在构造的过程中使用了交叉引用表,可把过程层或语句层的表示直接映射到功能层表示。更高层次的设计可让维护人员重新考虑程序模型并做出必要的变更和改进。

3.机会主义的理解策略

在实际工作中,程序理解过程很少像上述这些模型所描述的那样定义完备。所以,VonMayrhauser和Vans提出了使用一种集成模型的机会主义的理解策略。他们的研究发现,理解过程是自顶向下与自底向上这两种方法的结合过程。集成模型包括4个主要部分,即程序模型、状况模型、自顶向下模型和知识库。当对代码熟悉时,使用自顶向下模型,而对代码完全不熟悉时,使用自底向上模型,通过这种灵活的方式推进理解过程。知识库能够帮助对其他3个部分模型的构造,每个模型均由代码的中间表示以及建立这种中间表示的策略构成,知识库融合了以前需要的相关信息和知识。在理解过程中,新的信息被开发出来放在知识库中以便将来使用。4

具体方法下面简单介绍几种程序理解方法。

1、工程法:利用工程的方法来进行程序理解。工程法包括正向工程、逆向工程、再结构、重用工程以及软件再工程的方法等。

2)程序切片法:程序切片(program slicing)是根据控制流和数据流分析引进的一种程序分析技术。包括语句切片、无定型切片、过程间和过程内切片以及面向对象切片方法等。

3)格局识别法:维护人员必须在改正、加强和再工程程序之前找到相关代码,通常是适合某种模式的代码。模式是一种结构或行为,依赖于寻找有特定语法结构的代码,还是与程序执行有关的特定数据流、控制流或动态相关的代码。为定位这种模式需要一种更接近软件工程师智力模型的搜寻机制(而不是一般的程序分析工具),这种机制称为格局识别。

4)概念赋值和概念分析法:概念赋值(concept assignment)是发现面向人类的概念中的问题,并把它们赋值给它们在软件系统内部的实现实例。概念赋值是在用户终端应用语义层的模式匹配,是一个在源代码内重新识别概念,并通过联系可识别概念及对应程序来建立程序的一种理解的过程。概念分析(concept analysis)把任何对象和属性之问的关系转换成一个完全的概念格,可通过代数含义来研究这些概念格,并且利用概念格能够很成功地研究初始关系的特性和结构的本质。

5)模式匹配法:模式匹配是在不同的抽象层次卜对程序的各种模式进行匹配的过程。软件理解技术按如下递增抽象形式考虑源代码:粗糙文本、预处理文本、词汇标志、语法树、带符号表的注解抽象语法树、控制流/数据流图、程序格局、构筑范式描述和概念模型等。对不同的用户和不同的软件理解目的来说必须进行不同层次的分析。用基于语法、语义和概念模式匹配的逆向工程理解方法能够加强对程序的理解。

6)程序分析法:程序分析包括静态程序分析和动态程序分析两种:静态程序分析无需执行主题程序而只是根据一些模型推断程序本质结果的过程。静态程序分析包括语法分析、类型检查和推理、控制和数据流分析、结构化分析、交叉引用、复杂度度量等过程;动态程序分析是在一个主题系统中发现运行时依赖的过程。它包括对象实例依赖、动态联编和多态性、方法调用图、路径覆盖测试、内存管理、功能瓶颈、分支和并发等。

7)智能理解(intelligent understanding)法:利用人工智能和专家系统技术帮助进行软件理解。1

辅助工具阅读源代码是程序理解的一项重要活动,但是阅读别人的代码是枯燥乏味而且比较困难的工作,所以开发辅助工具成了程序理解的一项重要研究内容,并且在这一领域已经有了很多成果。这些工具能以更清晰、更可读、更可理解的方式组织和表示源代码,把人们从烦躁的代码阅读中解放出来。常见的辅助工具有以下几种:程序切分器、静态分析器、动态分析器等。程序切分器能够帮助程序员选择并只观察所提议更改影响的程序部件,不受无关部件的干扰,显示数据链和相关特征,使程序员能够跟踪更改影响。静态分析器能够帮助程序员快速提取模块、过程、变量、数据元素、对象与类、类层次结构等信息。在理解过程中,理解人员应该使用这些工具,以提高理解效率。

目前,除了针对C++、Java以及Ada等语言而专门开发的程序理解工具Understand外,专门用于程序理解的工具还不是很多,并且其中大多是作为辅助功能用于支持开发、测试或其他任务,如Logiscope、Panorama++、McCabe IQ、Klocwork以及有关的IDE。国内北大青鸟在“九五”期间专门将c++的程序理解工具作为科技攻关项目,并取得了较好的成绩,但遗憾的是并未看到他们普及应用的商业化产品或开源产品。3

提高对策正确、完整、快速地理解程序意味着程序理解的效率高。在程序理解过程中,维护人员要尽可能多地搜集信息(程序文档、源代码、程序的组织与表示等),而这些信息的完整性、易读性、可靠性都直接影响理解的效率。另外,软件人员自身的专业知识和应用领域知识也很重要,这些都是影响程序理解的因素,针对这些因素,可采用下列对策。

1.提高维护人员的素质

维护人员是软件理解过程的主体,所以维护人员自身的素质直接影响理解的效率。维护人员在应用领域或编程语言方面的经验越多,越容易理解程序以及整个软件系统。因此,应该多给维护人员培训的机会,提高他们的专业水平,使维护团队的整体素质得到提高。另外,还应该拓宽维护人员的知识领域。例如,若要理解的是某个应用在金融领域的系统,在理解的开始,就应该邀请该领域的专家对理解者做相应的培训工作,拓宽他们的知识面,帮助他们较快地进入到软件理解的环境中去。

2.科学地管理开发过程

程序理解是在现有系统和保存信息的基础上进行的,所以程序理解活动中经常要咨询系统开发时的参与者。但这存在一定的困难,原因之一可能是这些工作人员任务繁重,或是由于遗忘,很难配合维护人员的工作;也可能这些人已经离开了本单位,根本无法咨询。所以,在系统开发时就应该采取科学的管理。它包含两层含义:一是保留所有有关的文档,并做到及时更新。例如从最初的需求规格说明,系统设计文档到维护文档,都要做到妥善保存、及时更新。这些信息都直接影响到维护人员搜集信息的质量。二是要注意系统的实现问题,例如命名风格、注释、嵌套层次,最好使用统一的规则,这些都直接影响维护人员理解的容易程度和深度。

3.有效地使用自动化辅助工具

开发辅助工具是软件理解的一项重要研究内容,并且在这一领域已经有了很多成果。这些工具能以更清晰、更可读、更可理解的方式组织和表示源代码,把人们从烦琐的代码阅读中解放出来。常见的辅助工具有程序切分器、静态分析器、动态分析器等。程序切分器能够帮助维护人员选择并只观察要修改和受修改影响的程序部件,不受其他无关部件的干扰,显示数据链和相关特征,使维护人员能够跟踪变更的影响。静态分析器能够帮助维护人员快速提取模块、过程、变量、数据元素、对象与类、类层次结构等信息。在理解过程中,维护人员应该使用这些工具,提高理解效率。4