CN113508385B - 使用子例程图谱进行形式语言处理的方法和系统 - Google Patents
使用子例程图谱进行形式语言处理的方法和系统 Download PDFInfo
- Publication number
- CN113508385B CN113508385B CN202080015415.XA CN202080015415A CN113508385B CN 113508385 B CN113508385 B CN 113508385B CN 202080015415 A CN202080015415 A CN 202080015415A CN 113508385 B CN113508385 B CN 113508385B
- Authority
- CN
- China
- Prior art keywords
- graph
- subroutine
- node
- intermediate representation
- location
- 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.)
- Active
Links
Images
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/43—Checking; Contextual analysis
- G06F8/433—Dependency analysis; Data or control flow analysis
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F40/00—Handling natural language data
- G06F40/20—Natural language analysis
- G06F40/205—Parsing
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F40/00—Handling natural language data
- G06F40/40—Processing or translation of natural language
- G06F40/58—Use of machine translation, e.g. for multi-lingual retrieval, for server-side translation for client devices or for real-time translation
-
- 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
-
- 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
-
- 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/44—Encoding
- G06F8/447—Target code generation
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/44—Arrangements for executing specific programs
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- General Engineering & Computer Science (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Software Systems (AREA)
- Computational Linguistics (AREA)
- General Health & Medical Sciences (AREA)
- Health & Medical Sciences (AREA)
- Audiology, Speech & Language Pathology (AREA)
- Artificial Intelligence (AREA)
- Devices For Executing Special Programs (AREA)
- Machine Translation (AREA)
Abstract
一种用于在由计算装置实现的形式语言处理期间处理基于子例程结构化图谱的中间表示的方法。该方法包括:根据一组子例程中的子例程之间的相互递归关系,对在代码的中间表示中标识所述组子例程进行分类;记录相互递归关系;标记以跟踪所述相互递归关系;构造一组图谱表示;收集用于区分所生成的代码中的动作点的部分位置;标记中间表示的图谱的节点;通过前序深度优先遍历来序列化所述中间表示的图谱,生成随后的中间表示;以及根据所述中间表示创建所生成的代码。
Description
相关申请的交叉引用
本申请要求在2019年2月19日提交的美国临时申请No.62/807,704的权益,该申请在此通过引用并入。
技术领域
在此示出和描述的本发明的实施例涉及形式语言处理(formal languageprocessing)。具体地,实施例提供了一种用于管理使用子例程图谱(subroutine graph)的形式语言源文件的中间表示的改进过程。
背景技术
形式语言翻译是将源语言变换成目标语言的过程。形式语言翻译涉及解析、构造以有利于分析处理的形式捕捉语言特征的数据结构、将数据结构变换成其它数据结构以适于进一步处理以及生成目标代码。该过程是从以下理解开发的,即,解析(语法分析)可以被形式化、自动化,并且输入可以被变换成有用的数据结构以供进一步分析。解析被扩展到语法树的处理。稍后介绍通过引入特殊令牌(即UP和DOWN令牌)从语法树构造令牌流,以指定树结构和“假想”令牌以捕获其它语法结构,所述其它语法结构可以与从词法分析(解析字母数字和其它字符的流以构造令牌)导出的更普通的令牌相交织。添加图谱结构化令牌以使得能够进行图谱解析,以便变换和分析通常在编译器中找到的图谱表示,例如控制流图谱、数据流图谱和Petri网。语言处理工具是软件开发的基础;语言翻译处理的自动化加快并加强了复杂软件的开发。
解析(也称为语法分析)是分析可以是串或类似格式的一组符号的过程,其中“串”是项目的序列,在这种情况下是序列有限的符号,并且这些符号是从称为字母表的一组可能的符号中选择的。解析过程可应用于自然语言、计算机语言和包括DNA序列的类似系统。解析过程应用一组形式语法规则,该规则专用于所处理的语言。解析过程是计算机实现的过程,并且该术语在计算机科学领域理解的意义上使用,并且更具体地在计算语言学领域内使用。
在计算语言学中,解析过程还被理解为用于指计算机处理器和程序对自然或计算机语言中的句子或其它单词串的形式分析,其中句子或串被分类成其组成部分,从而产生解析树,其显示了每个组成部分与每个其它组成部分的语法关系。这个解析树也可以包含关于正被处理的句子或单词串的语义信息和其它相关信息。
在计算机科学内的一些应用中,解析过程用于计算机语言的分析,并且涉及将输入代码语法分析为其组成部分,以便进行编译器和/或解释器的后续功能,这些编译器和/或解释器用于将以一种计算机语言编写的代码转换为可执行形式,即计算机处理器能够执行的计算机语言。
发明内容
一种用于在由计算装置实现的形式语言处理期间处理基于子例程结构化图谱的中间表示的方法,所述方法包括:根据来自源文件或一组对象文件的代码的中间表示中标识的一组子例程中的子例程之间的相互递归关系,对所述组子例程分类;在一组子例程记录数据结构中记录所述相互递归关系;标记所述中间表示中的相关节点或来自所述中间表示的令牌,以跟踪所述相互递归关系;构造包括所述组子例程中的每个子例程的图谱表示的一组图谱表示;分析所述中间表示的图谱,所述中间表示的图谱通过经由深度优先的前序图谱遍历的序列化或穿过所述中间表示的图谱的路径行走而从所述一组图谱表示被分解为子例程图谱,收集部分位置,所述部分位置区分所生成的代码中的动作点,其中,在所述中间表示中的节点的部分位置列表中跟踪部分位置,所述部分位置列表标识所述中间表示的图谱中的点,其中,所述节点中的每个节点取自单独的子例程图谱,并且所述列表是通向终结节点的调用的回溯,并且其中,所述列表中除了终结节点之外的每个节点引用来自所述一组子例程的一个子例程;标记来自所述部分位置列表的所述中间表示的所述图谱的节点或所述中间表示的令牌,以在所生成的代码中进行运行时间跟踪,使得在所生成的代码中的相关联的位置处执行相关联的动作;利用前序深度优先遍历来序列化所述中间表示的图谱,生成随后的中间表示;以及根据所述中间表示创建所生成的代码。
附图说明
在附图中,通过示例而非限制的方式示出了本发明的实施例,在附图中,相同的附图标记表示相似的元件。应当注意,在本公开中对本发明的“一”或“一个”实施例的引用不一定是相同的实施例,并且它们意味着至少一个。
图1是形式语言处理的示例的流程图。
图2是整个图谱和该图谱内的一组子图谱的示意图。
图3A至图3C是一组递归子例程图谱的一个示例实施例的示意图。
图4是一个实施例的示意图,其示出了本文所述的过程和系统如何适合基于图谱的中间表示(IR)构造和分析。
图5是令牌分类过程的一个实施例的流程图。
图6是递归点处理过程的一个实施例的流程图。
图7是令牌序列化过程的一个实施例的流程图。
图8是测试游标过程的一个实施例的流程图。
图9是用于测试游标过程的“前”处理的一个实施例的流程图。
图10是用于测试游标过程的“前进”处理的一个实施例的流程图。
图11是标记过程的一个实施例的流程图。
图12A和图12B是来自部分位置的集合的图谱构造的示例的示意图。
图13A是作为包括标记转移开关的标记过程的结果而生成的Java运行时间代码的示例。
图13B是具有基于状态变量的动作的选择的Java运行时间代码的示例。
图14是标记创建过程的一个实施例的流程图。
图15A是用于创建标记和转移记录的宽度优先过程的示例的示意图,具体示出了部分标记过程。
图15B是包括作为较大图谱的一部分的部分标记过程的结果的宽度优先过程的示例的示意图。
图16是标记传播过程的一个实施例的流程图。
图17是标记传播的示例的示意图。
图18是在路径行走期间可能遇到的路径的示例的示意图。
图19是路径行走过程的一个实施例的流程图。
图20是解析系统的一个实施例的示意图。
图21是实现解析过程的计算机系统的一个实施例的示意图。
具体实施方式
在以下描述中,阐述了许多具体细节。然而,应当理解,本发明的实施例可以在没有这些具体细节的情况下实施。在其它实例中,没有详细示出公知的电路、结构和技术,以免混淆对本描述的理解。然而,本领域技术人员将理解,本发明可以在没有这些具体细节的情况下实施。本领域的普通技术人员利用所包括的描述将能够实现适当的功能而无需过度的实验。
将参考附图中所示的示例性实施例来描述附图中的流程图中所描绘的操作。然而,应当理解,流程图中所示的操作可以由本发明的实施例执行,而不是参考附图所讨论的那些实施例来执行,并且参考附图中的图所讨论的实施例可以执行与参考附图的流程图所讨论的那些操作不同的操作。
可以使用在一个或多个电子装置(例如,终端站、网络元件等)上存储和执行的代码和数据来实现图中所示的技术。这样的电子装置使用非暂时性机器可读或计算机可读介质(诸如非暂时性机器可读或计算机可读存储介质(例如,磁盘、光盘、随机存取存储器、只读存储器、闪存装置和相变存储器))和暂时性计算机可读传输介质(例如,电、光、声或其他形式的传播信号——诸如载波、红外信号、数字信号)来存储和通信(内部地和/或通过网络与其他电子装置通信)代码和数据。另外,此类电子装置通常包括耦合到一个或多个其它组件的一个或多个处理器的集合,所述一个或多个其它组件例如为一个或多个存储装置、用户输入/输出装置(例如,键盘、触摸屏及/或显示器)和网络连接。如在此使用的“集合”指的是任何正整数的项目。处理器的集合和其它组件通常通过一个或多个总线和桥(也称为总线控制器)耦合。存储装置表示一个或多个非暂时性机器可读或计算机可读存储介质,和非暂时性机器可读或计算机可读通信介质。因此,给定电子装置的存储装置通常存储用于在该电子装置的一个或多个处理器的集合上执行的代码和/或数据。当然,可以使用软件、固件和/或硬件的不同组合来实现本发明的实施例的一个或多个部分。
概述
图谱在形式语言处理中是常见的,尤其是在编译器中,它们用于分析控制和数据流;它们还具有语法分析和解析器生成的价值。本申请描述了“子例程图谱”的使用,其中图谱不被扩展而是被处理为子图谱的即时集合,其中,顶点(节点)在上下文中经由来自形成坐标层级的子图谱的节点的列表或栈来引用。由于用于构建这种图谱的节点分组的选择与子例程结构匹配,因此,选择子例程图谱术语,该子例程结构是计算机语言的特征,无论是C功能、上下文无关语法的产生、还是其它形式。针对图谱节点的前序序列化以及用于可以跟随图谱中的环回的路径行走(path walk),描述了使用这些坐标结构的通过图谱的导航。描述了一种用于将编译时间坐标转换成运行时间标记的节点标记过程,使得编译时间分析期间的空间节省转换成紧凑运行时间大小和快速运行时间执行。
介绍性资料
形式语言由语法来描述,该语法由定义构成该语言中的句子的“字符”的所有合法序列的“规则”或“产生”构成。上下文无关语言是可以由上下文无关语法(CFG)描述的各种形式语言,其中上下文无关语法G被定义为
G=(N,T,P,S)
其中,N是一组非终结符号,T是语言允许的一组终结符号(字符),P是一组形式的产生(或重写规则)
n-><终结和非终结的序列>,
其中n为非终结;
且S是起点符号(另一个非终结)。
对于语言处理,CFG规范由替代运算符“|”扩充,使得对于每个n,存在唯一的产生。这被称为巴科斯范式(Backus-Naur Form,BNF),其通常被扩展(EBNF)以包括短语的分组(短语),并且重复——A*指示A的0或更多出现,而A+指示一个或多个出现,并且A?表示0或1个出现。如这里所使用的,非终结以小写字母作为开头,而终结以大写字母作为开头;产生被写为
a:<符号序列>;
实际上,更一般的形式语言是根据扩充的CFG来定义的,以支持根据通用编程语言描述的“动作”,包括语义谓词(semantic predicates)。语义谓词用于查询上下文信息,并且当谓词评估为假时使替代无效。
图谱表示
扩充的CFG可以以具有连接顶点(“节点”)的有向边(directed edge)的图谱的形式来表示,其中每个节点被单个终端、动作或语义谓词占据。由于CFG支持递归(recursion),因此还需要添加两种附加的节点类型,这两种附加的节点类型是支持返回上下文信息的保存和恢复所需要的;逻辑上,这些节点键入来自栈的压入和弹出值,POP节点根据从栈中检索的值确定跟随哪个节点。为了理解这一点,考虑递归产生:
a:A a B
|B a C
|D;
在第一替代中,在识别A并递归地调用之后,返回路径必须涉及识别B;在第二替代中,在识别B并递归地调用之后,返回路径必须涉及识别C。以图谱形式,在递归调用(循环回到A的第一次调用)之前,必须插入PUSH_CONTEXT节点;在产生结束时(分号出现的情况),插入POP_CONTEXT节点。为了处理方便,还支持“(“and”)”节点,这些节点表示可能的判定点(POP_CONTEXT节点也是如此)。
如果增加了形式的开始产生
s:E a F;
则可以将得到的语法表示为图谱。
特殊令牌类型
在这里描述的一个示例性实施方式中,语法中引用的大多数令牌类型表示在运行时间要匹配的令牌,但是一些表示判定或所需的处理动作,并且存在于AST和图谱表示两者中。
这些包括:
替代的分组的BLOCK开始(当存在替代时使用的判定节点)。
分组的EOB结束(用于循环的判定节点)。
(…)*的CLOSURE判定节点,其在图谱中表示为((…)+)?.
如上所述的POP_CONTEXT。
如上所述的PUSH_CONTEXT
对于BLOCK、EOB和CLOSURE令牌,重要的是在AST表示中使用的相同令牌被用于图谱表示中,以便在一个表示中的编辑可以在另一个表示中被读取。这些令牌被嵌入在“载体”节点中,或者在AST或图谱表示中,或者在这两者中。
AST到图谱的转换
所采取的基本方法是为开始产生而使AST行走,从而生成令牌序列。然后处理这些以便构建语法图谱:非终结令牌被行内扩展,除了需要特殊处理的递归产生之外。扩展包括为所引用的产生而使AST行走(第一次遇到),或(随后遇到)复制所引用的AST并使该副本行走;这些行走生成按顺序处理的令牌序列,当遇到非终结(nonterminal)时将该非终结扩展。当复制时,复制的产生被重命名,作为非终结引用。递归产生是行内扩展的例外;它们被变换为动态循环(loops ono the fly)。
处理递归
为了跟踪递归,保持非终结名称的栈,其在图谱构造期间跟踪规则嵌套(rulenesting);在加入另一级嵌套之前,针对栈的内容检查非终结;如果存在,则将PUSH_CONTEXT节点添加到图谱和上下文值的数组以用于递归产生。该节点包含被设置为其在数组中的偏移量的上下文索引值。当递归产生的扩展完成时,使用数组创建从PUSH_CONTEXT节点到图谱中的产生的开始的环回(loopbacks);POP_CONTEXT节点被附加到图谱,并且被循环回到图谱中PUSH_CONTEXT节点之后的节点。
用于形式语言处理的子例程图谱
编译器和语言翻译应用程序中语言的中间表示通常采取树和图谱表示的形式。从扩展的图谱表示到最小冗余码生成是一个挑战性的问题。该实施例提供了用于避免图谱扩展的图谱处理和后续代码生成的有效方法。当子图谱在图谱构造期间被引用时,扩展子图谱可以导致生成的代码中的大量存储器使用和冗余;在LGLL算法的实际应用中,对于中等语法,所生成的文件达到数十兆字节,而这里描述的方法将所生成的源代码缩小到可由现代编译器管理的大小。
规则或子例程的基于栈的处理是软件中运行时间处理的标准特征。通过在编译时间分析期间对运行时间处理进行建模,可以将“整个”图谱分解成“子例程”图谱,并且可以将较大图谱中的位置表示为取自子例程图谱的各节点的栈。包括这种节点栈(以及其它适当的内务管理信息)的位置描述符允许等效的图谱导航能力,如在扩展图谱中可以实现的节点到节点导航。
考虑位置描述符{node0,node1,…,nodeN}。node0来自主图谱,node1从node0图谱调用,等等。然后,挑战是从这样的位置信息遍历(traverse)整个图谱。
实施例包含许多元素,包括1.)用关键图谱元素构造的图谱,2)用于分析的前序遍历,3.)路径跟踪和宽度优先图谱遍历(breadth-first graph traversal),3.)路径标记和4.)代码生成。这些元素中的每一个都将在下面进一步描述。
图谱元素
形式语言处理涉及操纵表示符号的“令牌”,其中每个符号被分配数值。符号是数学抽象;计算机自动符号推理需要符号的具体表示,即,令牌。令牌是携带符号标识符(“令牌类型”)的数据结构(对象),并且可以包括附加信息,诸如解析的文本、行号、行位置以及类似信息。
形式语言处理通常开始于词法分析程序阶段(lexer phase),其中,字符流(对于该阶段,令牌仅是标识字符的数字;在ASCII编码中,字符“A”由数字65表示)被解析以识别形成文本项的字符组,该文本项然后被布置到令牌流中;此时,令牌是至少包含文本串(一组字符)和整数值令牌类型的数据对象。字符流可以从文件或类似的输入源输入。符号是抽象实体,令牌是与整数令牌类型值相关联的数据结构的实例,并且字符是字节的序列(例如,一个用于ASCII,更多用于多码)。
令牌流被解析和排列成数据结构,例如解析树(parse tree)或抽象语法树(abstract syntax tree)。解析树包含来自输入源的所有识别出的令牌,以及反映用于识别令牌序列的语法结构的非终结令牌。解析树还包括作为解析过程的一部分而添加的标记,以表示非终结符号(产生名称)。解析树可以省略一些识别的令牌,这些省略的令牌通常限于表示空白(空白格、跳格设定、换行字符等)的令牌。抽象语法树理想地仅包含表示所识别文本的抽象语法所需的那些令牌,而不包含用于构造该树的语法的轨迹。
语言处理的一个进步是抽象语法树可以用树语法来描述,树语法解析器可以从这些语法中生成,这些语法处理抽象语法树的前序遍历(pre-order traveral)。这个概念在ANTLR 3中被进一步形式化,其中引入“UP”和“DOWN”标记来描述树导航。这进一步允许将前序遍历封装在(树)令牌流对象中。令牌流对象提供了通用方法(LA(k)),以找到用于流中的第k个预先查找(lookahead)令牌的令牌标识符,用于第k个令牌本身的LT(k)使得可以解析任何令牌流。在下文中,令牌流可以被假定为以对象形式而被实例化。
从解析树或有时在解析期间,可以构造一系列进一步的数据结构以执行对解析的数据的分析。实施例提供了涉及这些进一步的数据结构的过程和系统,这些进一步的数据结构采取具有携带(键入)令牌的节点(顶点)的图谱的形式。这些图谱可以被构造为具有叠加的环回边(loopback edge)的有向非循环图谱(directed acyclic graphs)。保持一组边与描述非循环图谱的那些边分开。
在一些实施例中,图谱的节点之间的边不携带或标识信息。在边可能携带信息的其他实施例中,节点被添加到图谱以携带信息,使得添加节点以分割每条边。包括这些节点的结果被称为Petri网。这种图谱结构便于序列化。在其它实施例中,非结构化图谱也可与(部分)顺序索引集一起使用。
在实施例中,对从这样的图谱导出的令牌流执行处理。特殊的令牌被输出以描述图谱结构,并且附加的令牌类型(PUSH_CONTEXT和POP_CONTEXT)表示用于实现递归并识别递归点的栈操作。如这里所使用的,大写名称,例如PUSH_CONTEXT,指的是示例令牌类型。
在整个图谱中,图谱中的PUSH_CONTEXT和POP_CONTEXT节点指示栈操作,但是在被称为“子图谱”的子例程图谱中的递归更复杂。对子图谱的引用可以是递归的,或者它可以是顶级调用(对于该子例程;多级递归导致相互递归的子例程之间的复杂关系)。为此,PUSH_CONTEXT节点在逻辑上是两用的。尽管为了避免重新键入节点,但是在以下讨论中,PUSH_CONTEXT节点通常指的是PUSH_CONTEXT/NEST节点对。取决于上下文,PUSH_Context节点是栈操作(stack operation)或NEST操作(nest operation)。还取决于上下文,POP_CONTEXT节点可以是空操作(null operation)或栈推动(stack push)。
在一些实施例中,存在两种形式的NEST操作。对于第一种情况,NEST操作仅通过名称来指代子例程图谱(即,子例程图谱具有单个入口点)。在更一般的第二种情况下,NEST操作命名子例程图谱,并且指定子例程图谱的入口点。对于一些问题,如线性广义LL(GLL)子图谱具有单个入口点,但是其它子图谱(如数据和控制流程图谱)将具有多个入口点的子图谱。
总体语言处理方法
关于图1所示的总体语言处理方法和编译过程描述了各实施例,该总体语言处理方法和编译过程包括关于图2至图19更详细地描述的多个组件和过程。
图1是编译过程的一个实施例的示意图。该过程是相对于复杂语言翻译或编译来描述的。通过输入源代码文件来启动该过程(框101)。源代码可以是任何类型的高级语言。源文件可以具有任何类型的格式。可输入单个源文件,或者任何数量的源文件和任何量的源代码可被组合,以便由将词法分析应用于源代码的词法分析程序处理源代码文件中的源代码(框102)。词法分析将源文件变换成令牌流。词法分析程序可以对词法分析程序的输出应用任何类型的词法分析算法,该词法分析程序被放置在令牌缓冲器中(框103)。
解析(框104)令牌缓冲器以生成抽象语法树(AST)(框105)。可以应用局部分析和/或其他类型的变换(框107)来生成一个或多个中间表示(IR)(框109和框111)。这些局部分析和变换可以包括常量合并(用常量替换常量表达式),如将2*3转换为6(变量的标识),以及类似过程。在将AST转换成一个或多个中间表示的过程(框109)之前,可以顺序地、迭代地、递归地或类似地将局部分析和变换(框107)应用于AST。
IR可以是数据流图、控制流程图或为特定形式的分析而构建的源代码的子集的某种其它表示,包括抽象语法树或甚至仅仅是令牌缓冲器。可以对IR应用多轮局部分析和变换处理(框113)。在多轮局部分析和变换之后,IR被转换回AST(框115)。树解析器或访问器处理AST(框117),以生成一组对象文件或目标源代码(框119)。
在编译过程的第二阶段中,通常被描述为“链接”与通过第一阶段(框101至框119)生成的整个或全部程序的源代码相对应的一组对象文件,经处理以生成一个或多个全部程序IR(框123)。这些IR可以采用与用于局部优化的那些IR相同的形式(框125)。然后,通过一组全局分析和变换处理(方框127)处理IR,该组全局分析和变换处理可以类似于局部优化和变换处理。全局分析和变换过程可以包括变量移除、存储器调度和类似过程。这些全局分析和变换过程可以顺序地、串行地、递归地或类似地应用于IR。在全局分析和变换过程完成之后,IR被准备用于代码生成(框129)。然后处理IR(框131),以生成输出文件(框133)。输出文件可以是目标源代码、应用可执行或类似的最终产品(框133)。
下面结合图2至图19描述的实施例的进一步过程主要在IR转换(框109、框111)、局部分析和变换过程(框113)、在多文件处理情况下的整个程序生成(框123和框125)以及图1所示的整个编译过程的全局分析和变换(框127)中实现。上述IR可以是源代码的图谱的形式。实施例的各个过程通过将这些图谱分成子图谱来对这些图谱进行操作。图2是示出示例性整个程序图谱的示意图。图2还包括示出将整个程序图重构为两个子例程图谱“a”和“b”的示意图。
图2标识了整个图谱上的示例路径203。行走(即,遍历)示例路径203继续通过整个图谱中的位置。路径203由连接节点A、节点b1、节点b2、节点b4和节点d的虚线示出,该路径可类似地描述为:
{a:A},{a:b,b1},{a:b,b2},{a:b,b4},{a:D}。
在上述位置,子图谱a由名称引用,而剩余元素是图谱节点。在图谱中没有节点引用起点节点,因此主子图谱可以由名称引用,除非它随后再次被引用为递归调用。该过程还可以包括位置标记227和用于描述整个图谱和子图谱之间的转移点的数组225。
图3A至图3C是一递归组的子例程图谱的一个示例实施例的示意图。三个子例程(图3A至图3C)被示意为图谱。第一子例程(3A)图谱包括一组节点,该组节点包括调用子例程f的节点,该子例程f被示为子例程(图3B)。第二子例程包括一组节点,该组节点包括调用子例程g的节点。第三子例程(图3C)包括一组节点,该组节点包括调用为递归调用的f的第一子例程的节点。递归调用子例程f的节点具有PUSH_CONTEXT类型。PUSH_CONTEXT和POP_CONTEXT类型(在图中缩写为PUSH(推动、压入或入栈)和POP(弹出或出栈))在路径行走期间触发上下文栈操作,如将在下面进一步描述的。
图4示出了将子例程图谱与基于图谱的IR的处理相结合得到的过程。在图谱构造之前,但在前一表示已被分解成子例程形式(即,可为每一子例程提供令牌流)之后,子例程被分类,以确定子例程之间的递归关系,递归点的部分位置(子例程“a”调用“a”或“a”调用“b”调用……调用“a”的点)被收集,并且这些部分位置被用于标记节点,以跟踪递归上下文。递归标记可以被推迟,但是必须在动作的依赖于上下文的标记之前。
该过程开始于(框401)生成中间表示,如AST。这可以是解析文件并构造IR的结果,或者来自从多个文件构造IR的文件读取器的结果;在生成来自框401的IR之前,可存在多个IR通过。编译器前端通常使用单个文件解析;多个文件读取是链接器的特征。然后,在框403中使用该IR来标识子例程、构造这些子例程的记录、并(经由图5中所示的过程)对子例程进行分类,以得到涉及一个或多个子例程的递归关系。下一步(框405)是使用图6中所示的过程来收集递归调用的部分位置(在这种情况下,该位置使用令牌而不是节点)。然后,使用这些部分位置(框407)来标记递归令牌。
此后,构造子图谱(框409),然后将其用于分析(框411和框413)。分析的细节取决于所解决的具体问题(控制流程、数据流、SSA波前等),但是分析将涉及按序列化所创建的次序来处理节点/位置(经由图7至图10的过程的框411),然后执行路径行走(经由图19的过程的框413)以收集信息。该步骤的输出用于构建部分位置和相关联动作的列表;然后,这些用于创建标记和转移记录(如将在图11至图17中示出的框415至框417)。
在图谱构建之后,在分析期间使用通过前序、宽度优先遍历和路径行走的图谱序列化。对于标识依赖于上下文的动作的分析,路径行走与选择这样的动作的收集位置相关联;这些位置用于上下文相关性标记。不是所有的分析问题都需要两种形式的图谱遍历,而是将采用这两种形式中的至少一种。
在分析之后,进行依赖于上下文的标记。依赖于上下文的标记提供了运行时间有限状态自动机的稍后分析和构造的基础,以用于在选择要采取的适当动作时确定上下文。图谱序列化可用于构造随后的IR或用于代码生成。
递归分析
从子例程图谱的角度来看,递归(以及来自递归调用的返回)是从一个子例程图谱中的一个位置跳到另一个或同一子例程图谱中的另一个位置。保存当前位置,并且将该位置设置为根调用(即,将当前位置被重置为当最初调用递归调用时的位置),而不是在沿着通过整个图谱的路径时遇到递归调用时、嵌套子图谱。例如,可以保存位置{a,b,c,d,e,c}的副本,并且在继续行走之前,将位置重置为{a,b,c}。当遇到下一个POP_CONTEXT节点时,假设没有遇到介入PUSH_CONTEXT,则从{a,b,c,d,e,c}中的终结符c之后的节点继续行走。
在能够将PUSH_CONTEXT和POP_CONTEXT节点插入到图谱中之前,有必要确定哪些子图谱是递归的,并且识别递归链——相互递归的子图谱集合。这是通过对一些子例程表示(例如,AST、令牌缓冲器或子图谱)进行前序行走以识别图谱中的递归位置来实现的。构造子图谱记录,当遇到递归点时,记录被标记为递归的,并且构造递归链:{a,b,c,d,e,c}导致注意到c,d和e都属于同一递归链。子图谱记录是记录子例程图谱的属性的数据结构。一旦构建了记录并且记录了递归子图谱,则构建插入了PUSH_CONTEXT和POP_CONTEXT节点的子图谱。如在此所使用的,术语“记录”指的是子例程记录。
多级递归的挑战之一是确定递归索引。递归索引是用于标识给定递归是n个可能递归中的哪个的数据结构。针对子例程图谱计算这样的递归索引,但是这样的递归索引在整个图谱中具有绝对值。
图5是确定实现的递归关系并将结果存储在一组子例程记录中的过程的一个实施例的流程图。相互递归的子图谱可以以各种方式被调用,但是在整个程序图谱中,仅出现(实现)了一些调用模式。例如:A调用B;B调用C;C调用A和C,但是仅直接调用A,因此A是主要的,而C是次要的(B不递归)。在其它语法中,B和C(以及A)可以作为主要的出现。递归链中的任何子例程都可以被认为是主子例程,即直接调用的子例程,而不是来自子例程链的其他子例程成员之一,这取决于整个图谱结构。从入口子例程开始,遍历整个图谱以标识递归子例程。
在一个实施例中,在子图谱构造之前,遍历整个图谱以识别递归子例程。因此,图5中描述的过程示出了来自令牌流的令牌(框501)。在该示例中,维持两个栈:用于子例程记录的记录栈和用于令牌流的令牌流栈。子例程记录用于跟踪关于各个子例程的信息,诸如相关联的子例程图谱。这些信息中的一些处理递归,而其它信息是应用特定的。信息可以包括子例程是否是递归的,以及关于其调用的其它相互递归子例程的信息。这种子例程的列表被称为子例程链。信息可以包括递归子例程是否是主子例程,即,是否是由不在递归链中的子例程调用的子例程。信息可以包括递归子例程是否作为次根出现;即,在由主子例程直接或间接调用之后的处理期间是否遇到递归调用。在随后的处理期间收集这些信息以供参考。令牌流被用于通过前序深度优先遍历(pre-oder,depth first traversal)从子例程图谱访问令牌。关于图5描述的处理的关键在于记录递归信息。在该示例中,令牌流中的各个令牌被忽略,除非它们表示子例程,在这种情况下,这些令牌是递归调用或直接调用,在这种情况下,相应的记录被推动到记录栈上,并且令牌流被推动到令牌流栈上,并且当前令牌流被设置为对应于该调用。递归调用可以由特殊动作来处理。
对于递归调用,活动记录被记录为递归的。找到记录栈中记录的索引。对于该记录,状态变量“isRoot”被设置为真。从栈中的该点到栈顶部的所有记录被标记为递归的。栈中索引记录之后的所有记录都被记录为从属的。“isRoot”和“从属的”记录状态二者都是临时状态变量。这些介入记录中的每一个都属于相同的递归链,从而在介入记录当前不同的情况下,巩固了递归链。
当令牌流耗尽时,在重置之前,检查临时状态变量isRoot和从属的。如果栈顶记录被标记为isRoot和从属的,则该记录被标识为主要的,否则被标记为从属的。在达到实际的主要记录时,该记录的递归链将已经完成。多级递归关系确保被标记为主要的任何记录实际上是主要记录。记录在一个上下文中可以是主要的,而在另一个上下文中是次要的,并且记录在第三上下文中既不是主要的也不是次要的。
如图5所示的过程,可以通过将令牌流设置到起点位置来启动用于识别所实现的递归关系的分类过程(框501)。检查在流中是否有更多的令牌可用(框503)。如果在流中没有令牌,则检查两个栈是否都是空的(框505)。如果两个栈都为空,则该过程完成(框509)。如果两个栈都不为空,则该过程根据isRoot变量的值和从属变量的值设置记录递归状态,即,主要的、次要的或两者都不设置。该过程将isRoot和从属重置为错误的,弹出记录栈,弹出流栈,并将令牌流设置为弹出的流(框507)。在完成框507的这一栈操作之后,通过检查在要处理的令牌流中是否存在附加令牌(框503)来继续该过程。
如果在令牌流中存在更多令牌,则选择下一个令牌进行处理(框511)。可以使用任何选择机制,在一些实施例中,令牌按照它们在源文件中出现的顺序或类似的顺序被处理。分析所选择的令牌以确定令牌是“嵌套”令牌还是指示输入令牌流中的嵌套结构的令牌(框513)。如果所选择的令牌不是指示嵌套的令牌,则选择对更多令牌的检查(框503)和选择下一令牌(框511)。
如果所选择的令牌是嵌套令牌,则该过程获得该令牌的子图谱记录(框517)。一旦检索到该令牌的记录,就检查该记录是否已经在记录栈中(框519)。如果在记录栈中没有找到记录,则该过程将记录推动到记录栈上,推动令牌流,并从记录中设置令牌流(框523)。如果在记录栈中找到该记录,则标记该记录,或者记录该记录是递归的并且管理递归链(框521)。为该记录设置isRoot,并且记录栈中的后续其它记录被标记为从属。在两种情况下,该过程然后通过检查要处理的更多令牌而继续(框503)。当处理了所有令牌并且处理结束时,所有子例程记录都被关于它们的递归属性进行适当分类。在很大程度上,该信息用于避免不必要的处理;例如,相对递归位置收集仅处理递归记录。
图6是用于收集相对递归位置的过程的一个实施例的流程图,因为它们是从每个主要递归子图谱而不是从整个图谱的入口开始而被确定的,因此递归位置是相对的。为了将相对位置转换成绝对位置,将当前(绝对)位置截断为主要调用并附加相对位置。因此,给定相对位置{c:f,g}和当前位置{a,b,c,d,e},{a,b,c,d,e}被截断为{a,b,c},{e,f}被附加以将相对位置转换为绝对位置{a,b,c,f,g}。这些相对位置被用于路径行走和用于标记。
该过程可以通过选择下一子例程记录(框603)开始(框601)。下一记录可以由任何选择机制来选择。检查所选记录以确定它是否是主要记录(框605)。如果该记录不是主要记录,则选择下一记录(框603)。如果记录是主要记录,则设置令牌流(框607)。然后检查该流是否包含进入令牌处理循环的令牌(框609)。这可以有效地是无操作(no-op);递归子例程具有令牌。
检查所选择的令牌以确定该令牌是否具有NEST令牌类型并且是否在递归链中(框613)。如果所选择的令牌不是NEST令牌并且不在递归链中,则选择下一令牌(框609)。如果该令牌是NEST令牌并且在递归链中,则将当前(相对)位置保存到命名数组中(框617)。如果令牌不在记录栈中,则将令牌推动到令牌栈上,将记录推动到记录栈中,并将令牌流推动到流栈上(框619)。在任一情况下,该过程继续选择下一令牌以进行处理(框609)。在这种情况下,调用完整的“下一令牌”判定过程。如果当前令牌流已经用尽,则测试令牌流栈以查看其是否为空(框623)。如果不是,则弹出令牌流栈,并且利用弹出的令牌流继续进行流处理。如果令牌流栈为空,则该过程继续下一记录循环(框625),然后退出该过程。
图谱解析
前序序列化(pre-order serialization)是使得可以解析图谱的过程。相反,令牌流可以被解析,而不管它们是如何创建的。
用于整个图谱的前序深度优先序列化
这里描述的前序深度优先序列化过程是通过图谱遍历过程完成的。该过程用于构造令牌流,其中添加了一些逻辑用于令牌化并处理递归问题。要处理的图谱具有单个起点(start)节点和单个末尾(end)节点。图谱中的每个节点具有“前”沿和“后”沿。用于表示形式语言的图谱是强有向的(strongly directed)且具有带分叉(fork)和连接点的常规结构。
用于前序深度优先序列化的相关定义包括:
nodeOffset是下面讨论的数组中的有效元素的数量。
数组:对于该过程有三个相关的数组:fanNodes,扇出(fanout)和nodeIndex。fanNodes是具有多个后沿的节点的数组,fanout是后沿数组的数组,并且nodeIndex是进入后沿数组的索引的数组。
表:表将节点映射到它们已经被遇到的次数(例如,连接或前索引值)。由于分叉/连接组合可能遇到多于一次,所以每当连接节点已经完成处理时,其在表中的值被重置为0。
图7示出了对于整个图谱遍历和子例程图谱遍历二者都有效的高级处理逻辑。通过将游标设置到图谱的起点节点,开始前序深度优先序列化过程。然后,该过程执行addTokens处理循环,其中执行测试游标(testCursor)过程(框701;对整个图谱的空操作)。执行测试以查看是否存在更多的令牌要处理(框703);如果不是,则该过程从addTokens过程返回。如果有更多的令牌要处理,则执行测试(框705)以查看是否有路径合并要处理。如果没有路径合并要处理,则过程跳到前进操作(框711)。
然后,该过程执行processBefore操作(框707),并执行测试(框709)以确定是否已经为该合并处理了所有合并路径;如果没有剩余的额外的合并要处理,则过程返回(框713)。如果有额外的合并要处理,则该过程执行前进过程(框711)并随后返回(框713)。
在非子例程图谱的情况下,processBefore操作包括从将节点映射到先前相遇的计数的表中获得当前路径的连接索引值,并且递增所映射的索引值。然后,该过程发出(即,添加到令牌流)引用当前游标的TERMINUS令牌。
该过程递增当前nodeIndex值。如果当前nodeIndex值小于扇出边的当前计数,则该过程将游标设置到从当前扇出开始的下一路径。否则,如果nodeIndex值等于前沿的数量,则该过程发出引用前沿的JOIN令牌,并前进到随后的合并完成测试(框709),该测试然后评估为“是”,使得该过程执行前进过程(框711)。
如果当前nodeIndex等于扇出边的数量,则该过程发出引用当前游标的ENDFORK令牌。nodeOffset递减。如果索引值等于前沿的数量,则处理继续到完成测试(框709),其评估为“是”,使得过程执行前进过程(框711)。如果索引值不等于前沿的数量,则该过程将游标设置到从当前扇出的下一路径,递增当前nodeIndex,并且前进至测试(框709),其评估为“否”,从而使该过程返回。
在一些实施例中,前进过程确定游标处的节点是否是一个或多个环回的端点,然后前进过程发出引用当前游标的LOOPJOIN令牌。如果游标处的节点具有多于一个的前沿,则前进过程发出引用该游标的TARGET节点。
然后,该过程可以发出当前游标的令牌值。如果游标处的节点具有多个后沿,则该过程发出FORK令牌,递增nodeOffset,设置fanNode和扇出,并将nodeIndex[nodeOffset]设置为0。
如果游标处的节点具有环回,则该过程发出引用LOOPJOIN节点的LOOPBACK令牌。如果节点是分叉,则该过程将游标设置为fanout[nodeOffset][0],否则,将游标设置为当前游标之后的节点。然后,该过程结束addTokens循环。该过程递增地处理被添加到令牌流的令牌。如果最后的addTokens循环添加了0个令牌,则该过程停止,否则该过程继续到下一游标节点。
用于子例程结构化的图谱的前序深度优先序列化
前序深度优先序列化过程适用于包括子例程图谱的图谱。为了跟踪整个图谱的遍历状态,使用两个栈。使用跟踪与子例程图谱嵌套相关的位置的节点栈。使用包括记录在遍历期间遇到的规则/产生/子例程的属性的一组记录的记录栈。另外,该过程使用由子例程图谱名称索引的记录的映射。
当在遍历期间遇到NEST类型节点时,NEST类型节点被推动到节点栈上,对应的记录被恢复并被推动到记录栈上,并且相应的子例程图谱被取出。整个图谱的遍历以子例程图谱的引用入口处的节点继续。在子例程图谱的末尾,弹出节点和记录栈,并且遍历以弹出的节点之后的节点继续。
图8至图10详细描述了来自图7的用于子例程图谱子的过程:图8示出了测试游标逻辑,图9示出了processBefore,而图10示出了提前操作。
图8是用于testCursor功能的过程的一个实施例的示意图。如果在图谱中仍然存在要遍历的节点,则testCursor功能确保游标为非空。testCursor功能开始于询问当前游标是否为空(框801)。如果游标为空,则该过程返回假(框819),指示这不是图谱的末尾。否则,该过程执行去嵌套(unnest)操作(即,弹出节点栈,并将游标设置为弹出的值)(框803)。如果新游标具有环回(框805),则发出LOOPBACK令牌(框807)。如果游标在子图谱的末尾,则重复去嵌套(框809)并且继续(框805),直到到达(整个)图谱的末尾(框817)或者游标具有随后的节点(框813)。图谱末尾令牌是特殊的。该令牌不被发出,但是可以具有环回(框815),并且返回值指示这一点。
如上所述,合并节点可以用特殊处理来处理。下一节点从最近的分叉开始下一路径,或者完成该最近的分叉的处理,并且可以合并先前的分叉。相关的处理需要分叉索引(路径段的起点)和连接索引(路径段的末尾)。图9是实现该合并逻辑的来自图7的processBefore功能的一个实施例的流程图。第一步是获取连接索引并递增其存储值(方框901),然后发出TERMINUS令牌以标记路径段的终点(方框903)。然后,获取分叉索引(框905)并将其与该分叉中的替代路径段的数量进行比较(框907)。如果这不是从该分叉的最后一个路径段,则设置游标以从该分叉开始下一个路径段(框909)并返回。如果它是从分叉的最后一个路径段,则该过程发出ENDFORK令牌(框911)并执行连接处理(框913至框917)。
图10是图7的前进功能的一个实施例的图。前进功能在前进到当前路径中的下一个节点之前发出游标的令牌和任何相关联的图谱结构令牌。第一步是确定游标是否开始任何(一个或多个)循环(框1001)。如果游标确实开始循环,则该过程发出LOOPJOIN令牌(框1003)。然后,该过程检查游标是否是合并或连接(框1005),如果是,则发出TARGET令牌(框1007)。然后,该过程发出用于游标的令牌(框1009)。如果游标开始分叉(框1011),则该过程发出FORK令牌(框1013)。如果游标结束循环(框1015),则该过程发出LOOPBACK令牌(框1017)。然后,该过程将游标前进到路径中的下一节点并返回(框1019)。
标记
由于任何节点可以存在于整个图谱中的多个位置处,因此为该节点生成的代码可以具有多个版本,使得有必要确定哪个版本在给定的上下文中有效。即,当图谱不再可用时,有必要在运行时间跟踪整个图谱的部分的上下文。这是用数字标记来完成的,并且所生成的代码然后采取以下形式:
int saveState=ruleState;
switch(ruleState){
case A:
ruleState=A1;
break;
case B:
ruleState=B1;
break;
…
}
call subroutine();
ruleState=saveState;
终结开关/切换(switch)将选择要执行的功能。标记跟踪上下文;在分析期间遇到的部分位置如{c,d,e}被转换成标记序列,如{DEFAULT,LABEL_a,LABEL_b}。在调用子例程之前,将有一个包含默认情况的开关,该默认情况将ruleState设置为LABEL_a。在调用b之前,将存在a
case LABEL_a:
ruleState=LABEL_b;
break;
并且c与以下相关
case LABEL_b:
function_c0();
break;
为了得到这个运行时间动作的序列,包含对DEFAULT和LABEL_a的引用的数据结构被存储到与a相关联的数组中,{LABEL_a,LABEL_b}与b相关联,以及{LABEL_b,function_c0}与c相关联。
如图11所示,标记作为四步过程进行:将需要标记的部分位置的集合转换成图谱,从该图谱中标识联网社区(networked communities),在每个社区上的一组初始宽度优先遍历期间创建标记,然后传播这些标记以覆盖所有相关上下文。
跟踪整个图谱中的所有位置将为大多数形式语言问题生成难以管理的大型代码体,因此必须标记尽可能少的所生成的代码。在一些实施例中,标记将仅跟踪感兴趣的部分位置,并且仅标记构成那些部分位置的节点/令牌。幸运的是,存在基于图谱的解决方案。图谱的替代表示是根据节点(顶点)和邻接矩阵A,其中,
如果nodei连接到nodej,则A[i,j]=1
如果不是,则A[i,j]=0
邻接矩阵的相关特性是
M=A+A2+A3+……
具有的特性是
如果从nodei可到达nodej,则M[i,j]=1;如果不是,则M[i,j]=0。
M[i,i]=1是特别感兴趣的节点,因为它们属于节点的社区。图谱中的社区是最大一组节点,对于该最大一组节点,给定该组中的任意两个节点{a,b},存在从a到b和从b到a的路径。社区的概念对于社会网络分析是关键的。
将这一概念应用于子例程图谱,部分位置可以被转换成逻辑图谱元素,其中node0→node 1、node 1→node 2等,然后添加noden→node 0以确保节点属于社区。
图12示出了这种图谱构造的示例。在所示的示例中。环回用虚线示出:在社区检测中使用了环回,但是在随后的标记过程中不使用环回,除了递归标记之外。在对一组位置的每一个进行此操作之后,可以构造邻接矩阵,并且识别社区。如前所述,“节点0”可以是子例程图谱名称,而不是作为或将成为子例程图谱中的节点的元素。在顶点列表/邻接矩阵表示中,顶点可以具有完全不同的数据类型。
一旦识别了社区,就使用宽度优先匹配方法来创建标记并将标记分配给节点/令牌。标记包括将{predecessor(前驱),value(值)}对添加到被标记的节点的转移数组。第一节点被标记为{“default(默认)”,value0},下一节点被标记为{value0,value1}。终结节点用“功能”值标记。
首先,收集从nodeA开始的那些位置,标记nodeA,然后注意力转移到nodeA之后的节点。例如,收集的位置中的第一个可以具有在position1处的nodeB。针对位置1处的nodeB,扫描所有收集的位置,并且收集它们并将其从集合中移除。该过程继续,从一组精简的位置收集节点,以及向下继续收集位置中的节点,直到所有位置都被处理。
标记涉及将转移记录附加到节点/令牌,其中转移记录是包含先前标记、为除终结节点之外的所有节点设置的当前标记字段、以及仅为终结节点设置的功能值的数据结构。这允许创建类似于图EX1中的运行时间代码。
标记过程的目标是将状态机并入所生成的代码中,以在所生成的代码中的点处从一组可能的上下文相关动作(功能调用)中进行选择。图13A示出了具有转移开关的Java运行时间代码的示例。在转移开关中,每种替代情况改变状态变量的值,在该示例情况下为“ruleState”。图13B示出了具有基于“ruleState”的当前值的动作选择的Java运行时间代码。[未示出“ruleState”在每个转移开关之前的保存,以及在从导致动作选择的功能调用返回之后的恢复。]
图14是标记创建过程的一个实施例的流程图。如上所述,这是针对每个社区的宽度优先匹配过程(框1401)。第一步是将社区中的所有部分位置收集到数组中(框1403)。然后,将迭代索引i设置为零(框1405),并且将当前标记设置为默认值“default”。如果社区数组(不是在这个初始步骤期间,而是在随后的迭代中)是空的,则处理完成(框1407)。如果不是,则该过程开始收集子数组,提取与父数组中第一位置的当前索引处的节点相匹配的数组(框1409)。如果已经提取了所有元素(框1411),则将转移记录分配给具有被设置为当前标记的先前值的节点,并且指示被分配给该记录的功能值。继续从社区数组中收集下一个阵列。否则,该过程标记第i个节点,并递增i(框1413)。标记涉及创建新串、将该串与唯一整数值相关联、创建具有被设置到当前标记的先前值和被设置到该串的当前值的转移记录。一旦已经创建了转移记录并将其添加到节点的转移记录,则将当前标记设置为串值。继续收集子数组。
图15A是用于创建标记记录和转移记录的宽度优先过程的示例的示意图。特别地,图15A的示意图出了部分标记过程。图15B是用于创建包括作为较大图谱的一部分的该部分标记的结果的标记记录和转移记录的示例宽度优先过程的又一示意图。部分标记(如图15A所示)开始于收集以k开始的部分位置(图15A中未示出),并以f1(即,引用f的NEST节点)继续。L3a被创建并被分配给“k”节点作为从默认(在图15B中缩写为Dflt)的转移标记。然后,创建标记L3b,并将其分配给f1节点,并且注意到从L3a到L3b的转移。然后,对每个收集的部分位置中的下一个节点继续进行标记。收集开始(f1,c)的所有部分位置,并将L3c标记分配给c,从而创建从L3b→L3c的转移。在这些部分位置的标记完成之后,收集并标记以(f1,g)开始的所有部分位置。这些导致L3标记和转移,如图15B所示。
标记传播
图16是传播标记的过程的一个实施例的流程图。该过程传播标记用于处理在整个处理的先前步骤中未解决的转移。流程图的最后操作是针对每个社区传播标记,如图14所示。在社区内,由位置对象描述的路径可以重叠,因此初始标记没有描述所有可能的转移。标记传播扩展了转移标记以覆盖所有转移。考虑位置{a,b,c,d,e,F}和{c,d,g,H}。在第二位置中,当加上{a,b}作为前缀时,c不具有默认标记。在这种情况下,从{a,b}开始的标记序列接着到d,然后添加从d到g的转移,该转移对齐{g,H}的标记序列,以在未加上{a,b}作为前缀时与{c,d,g,H}的标记序列匹配。
在每个社区内,以部分位置为基础,在部分位置上进行标记传播。标记传播过程为每个社区构造有限状态自动机,以便能够跟踪后续中间表示中的上下文或所生成的运行时间代码中的上下文。从部分位置开始(框1601),该过程从社区中紧接在该部分位置之前的节点收集标记的数组(框1603)。然后,将位置索引(到位置列表的当前偏移量)初始化为0(框1605),并且该过程将引用标记变量设置为默认值,诸如“default”。然后,通过创建后继数组(框1607)并识别其先前值与引用标记匹配的转移记录,开始对该位置索引的处理(框1607)。该过程还将引用标记设置为来自该转移记录的标记值。然后,对于标记数组中的每个串(框1609),该过程在该索引处找到其先前字段与该串匹配的节点的转移记录(框1611)。该过程测试该记录是否为空(框1613)。如果记录为空,则该过程创建从该串转移到来自引用转移记录的引用标记或功能的转移记录(框1621)。该过程将来自该串的路径合并到为重叠的部分位置创建的预先存在的路径中。如果记录不为空,则该过程将来自所找到的转移记录的标记添加到后继数组(框1615)。然后,该过程测试是否继续到标记数组中的下一个标记(框1617)并继续(框1609),或者测试是否标记数组中的所有标记都已经被处理,并测试了位置索引是否在部分位置的末尾;如果是,则该部分位置的处理已经完成。如果该位置不在索引的末尾,则该过程用后继数组替换(框1623)标记数组,并继续(框1607)。
图17是示出标记传播的示例的示意图。在图17的示例中,该过程传播来自图15A和图15B的L3标记。整个图谱、标记和示例是图15A和图15B中所示的延续。在图17中,插图示出了正在被操作的部分位置以及与各个节点相关联的两个转移集合。默认情况是“a”转移到L1b,然后L1b转移到L1c,再转移到“d”。另一方面,L3a→L3b转移不具有“d”转移,因此必须合并到转移的默认系列中。因此,添加了将L1b转移到L1c的转移,并且确保当到达{k,f,c,d,tgtA}时调用适当的tgtA功能(tgtA function)。
收集用于分析的位置
标记的要点在于各个节点变得与从中生成代码的数据结构相关联。每个这样的数据结构与单个节点相关联,但是当那些数据结构取决于它们出现的上下文时,则必须在运行时间确定上下文以选择适当的动作。因此,对于数据结构所附的每个节点,关联了{position(位置),data(数据)}元素的数组,其在每次遇到该节点时被添加。
在大多数情况下,收集位置是不够的:为了限制标记的数量,需要对位置进行修整以移除前缀节点(例如,{a,b,c,d,e}可以被修整为{d,e}),以便将位置收缩为仅覆盖所需的上下文。如何修整位置取决于具体的问题。下面描述与标记的这个方面相关的三个具体问题。
递归标记
递归位置需要被标记,以便计算递归索引,并且在传播其它标记时重置转移索引。
代替修整,相对于主要-递归-子例程,确定递归位置。遍历每个主要子例程以找到递归点,不是从“开始”子图谱开始。在一些情况下,递归链的多于一个成员作为主要子例程出现;从递归链导出的所有位置将最终属于相同的社区。
用于线性GLL识别器生成的宽度优先模式匹配
开始于{a,b,c,d,e}并终止于{a,b,g,h,k}的路径具有局部上下文{c,d,e}——起点和末尾都被局部化到前缀位置{a,b},并且感兴趣的位置是开始位置。实际上,将存在多个末尾位置,因此修整算法是要找到最短前缀。
变量分配跟踪
静态单个分配形式在逻辑上用仅被分配一次的变量来替换在程序中的被分配在多个点处的变量,但是查看变量引用与分配也可能是感兴趣的。变量分配位置和变量引用位置提供了用于标记的界限,尽管这种标记的效用并不清楚。
路径行走和宽度优先模式匹配
上述标记算法的核心是宽度优先模式匹配的良好示例。与遍历整个图谱的路径相比,子例程图谱中的路径行走需要稍微更多的机器。路径行走过程需要位置信息,保存和恢复递归跳转位置的栈也是如此。递归标记跟踪也是所希望的。这些特征可以被收集到“坐标”对象中以用于导航路径行走。坐标用于单步执行路径行走。
图18是在路径行走过程期间可能遇到的示例路径的示意图。图18示出了来自图3的递归示例的示例路径行走。以第一子例程图谱中的“A”节点开始路径,行走一步以到达“f”(NEST)节点,并且在嵌套之后,路径行走过程到达f中的FORK(即,第二子例程图谱中的第一节点)和位置{f,FORK}。选择上面的替代并步进使过程到{f,D}。另步骤到达{f,g},其嵌套到{f,g,FORK}。再次,选择上面的路径并前进,过程到达{f,g,E},随后是{f,g,f/PUSH}。递归返回到{f,FORK}位置,但是{f,g,G}被推到栈上(稍后在POP_CONTEXT节点处被弹出)。从这里开始,路径行走将继续,直到路径行走完成所有递归和相关联的栈操作,以弹出所有相关上下文为止。
图19是用于遍历一组子例程图谱的路径的一个实施例单步骤动作的流程图。在遍历这些子例程图谱时存在三个不寻常的入口条件:对于正常入口,例外是当前节点是PUSH_CONTEXT节点(框1901),在这种情况下,当前坐标被推动到适当的栈上(框1903)。如果当前节点不是PUSH-CONTEXT节点,则该过程确定当前节点是否是子图谱的末尾(框1907),在这种情况下执行去嵌套操作(框1909)。
然后,该过程可以前进至下一节点(框1911)。替代地,如果当前节点令牌跟随判定点和坐标分割,则过程可进入这里(框1905)。该过程检查当前节点并采取一组可能动作中的一个(框1913)。如果该节点是NEST节点(嵌套节点),则该过程解除引用(dereference)(框1917)并重新评估(框1913)。NEST节点的每个解除引用推动NEST节点及其相关联的子例程记录,并且将当前节点设置到由相关联的子例程记录引用的图谱的起点;每个解除引用最终跟随有弹出节点和记录栈的去嵌套,并将当前节点设置为在嵌套节点之后的节点。如果该节点是POP_CONTEXT节点(框1923),则该过程检查是否存在跟随的上下文(框931)。如果POP_CONTEXT不相关(即,是穿过(passthrough)——框‘K33)并且被步进经过去嵌套,或者如果适当的上下文栈具有要跳转到的一组坐标,则发生这种情况。如果没有跟随的话,那么该过程返回POP_CONTEXT令牌(框1929),因此调用者可以采取适当的动作。如果下一个令牌既不是NEST也不是POP_CONTEXT(框1921),则该过程返回该令牌(框1929)。
如果返回的令牌是判决节点,即,它在环回之后具有多个节点或已经环回,则可以利用程序干预来继续行走,因为路径分叉了。另一方面,路径行走趋向于作为宽度优先模式匹配的一部分而发生,并且在任何情况下路径将需要通过令牌类型来分割。这是坐标分割之后的替代起点的源。
图20是实现语言处理器(可以是编译器或语言翻译器或链接器)的计算机系统的一个实施例的示意图。计算机系统可包括处理器2001或一组处理器,以执行实现本文所述的解析过程的语言处理器生成器2003。在另一个实施例中,语言处理器2003和相关过程可以以分布方式在多个相互通信的计算机系统上执行。为了清楚起见,下面本文描述在单个计算机系统内执行的实施例。然而,本领域技术人员将理解,本文描述的原理和结构与具有诸如分布式实现之类的其他配置的其他实施例一致。
在一个实施例中,语言处理器2003包括用于将输入语法处理为诸如AST的中间表示的解析器或文件读取器2005前端、用于构造子例程记录以及执行递归分析以填写记录内容并将递归标记添加到令牌的图谱前构造操作2007、子例程图谱构造2009、使用子例程图谱IR的分析2011、分析后令牌标记2013、以及用于创建运行时语言处理代码的包括代码生成的终端处理2015。前端解析器或文件读取器2005将源代码或对象文件2017作为输入,并且生成中间表示(AST)2019,并且创建如上所述的子例程图谱记录2021的表。子例程前图谱构造处理2007将中间表示2019作为输入,以记录子例程记录2021的信息。子例程图谱构造2009产生与子例程记录相关联的子例程图谱2023。分析2011产生位置列表,其用作标记2013的输入。
语法或对象代码2017和最终生成的代码2027可以位于计算机系统的存储器(磁盘)2033中,并且可以通过总线2013或类似的互连来访问语言处理器2003。中间表示2019、子例程记录2021、子例程图谱2023和位置列表2025可以位于计算机系统的工作存储器中,并且可以通过总线2013或类似的互连来访问语言处理器2003。处理器2001可以通过总线2031、芯片级或系统区域网或类似的通信系统与工作存储器2035和存储装置2033通信,所述工作存储器2035和存储装置2033存储了源代码2015、中间表示2015、图谱表示2017和生成的解析器2019。工作存储器2021可以是任何类型的存储装置,例如固态随机存取存储器。工作存储器2021除了存储编译的代码之外,还可以存储任何上述数据结构,工作存储器2021和永久性存储装置(未示出)负责存储编译器和解析器及其子组件的可执行程序。
工作存储器2035可以通过总线2031与处理器2001通信。然而,本领域技术人员将理解,总线2031并不严格指示仅有总线将处理器2001分开,并且总线2031可包括实现处理器2001和语言处理器2003之间通信的中间硬件、固件和软件组件。本领域技术人员将理解,计算机系统是作为示例而非限制来提供的,并且为了清楚起见,计算机系统的公知结构和组件已被省略。
图21示出了计算机系统的示例性形式的机器的示意图,在该机器内可以执行用于使该机器执行本文所讨论的方法中的任何一个或多个的指令集。在替代实施例中,机器可连接(例如,联网)到局域网(LAN)、内联网、外联网或因特网中的其它机器。该机器可以在客户端-服务器网络环境中以服务器或客户端机器的能力来操作,或者在对等(或分布式)网络环境中作为对等机器来操作。该机器可以是个人计算机(PC)、平板PC、机顶盒(STB)、个人数字助理(PDA)、蜂窝电话、web设备、服务器、网络路由器、交换机或网桥、或者能够执行指定该机器要采取的动作的一组指令(顺序的或以其他方式的)的任何机器。此外,虽然仅示出了单个机器,但是术语“机器”还应被理解为包括单独地或联合地执行一组(或多组)指令以执行本文所讨论的方法中的任何一个或多个机器(例如,计算机)的任何集合。
示例性计算机系统包括处理装置2102、主存储器2104(例如,只读存储器(ROM)、闪存、诸如同步DRAM(SDRAM)或Rambus DRAM(RDRAM)之类的动态随机存取存储器(DRAM)等)、静态存储器2106(例如,闪存、静态随机存取存储器(SRAM)等)以及辅助存储器2118(例如,数据存储装置),它们经由总线彼此通信。
处理装置2102表示一个或多个通用处理装置,例如微处理器、中央处理单元等。更具体地说,处理装置可以是复杂指令集计算(CISC)微处理器、精简指令集计算(RISC)微处理器、超长指令字(VLIW)微处理器、实现其他指令集的处理器、或实现指令集的组合的处理器。处理装置2102还可为一个或多个专用处理装置,例如专用集成电路(ASIC)、现场可编程门阵列(FPGA)、数字信号处理器(DSP)、网络处理器或等。处理装置2102被配置为执行编译器,该编译器包括语言处理器生成器2126和/或相关组件,以用于执行本文所讨论的操作和步骤。
计算机系统2100还可以包括网络接口装置2108。计算机系统还可以包括视频显示单元2110(例如,液晶显示器(LCD)或阴极射线管(CRT))、字母数字输入装置2112(例如,键盘)、游标控制装置2114(例如,鼠标)以及信号生成装置2116(例如,扬声器)。
辅助存储器2118可以包括机器可读存储介质2128(或更具体地,非暂时性计算机可读存储介质),在其上存储体现本文描述的方法或功能中的任何一个或多个(例如,语言处理器生成器2126)的一组或多组指令(例如,解析器和/或语言处理器生成器2126)。语言处理器生成器2126(即,实现本文中描述的方法)在由计算机系统2100执行期间,还可以完全或至少部分地驻留在主存储器2104内和/或处理装置2102内;主存储器2104和处理装置也构成机器可读存储介质。还可以经由网络接口装置2108通过网络发送或接收语言处理器生成器2126。
机器可读存储介质2128可以是非暂时性计算机可读存储介质,其还可以用于持久地存储语言处理器生成器2126模块。虽然在示例性实施例中非暂时性计算机可读存储介质被示为单个介质,但是术语“非暂时性计算机可读存储介质”应当被理解为包括存储一组或多组指令的单个介质或多个介质(例如,集中式或分布式数据库,和/或相关联的高速缓存和服务器)。术语“非暂时性计算机可读存储介质”还应当被理解为包括能够存储或编码指令集的任何介质,所述指令集用于由机器执行,使得机器执行本发明的方法中的任何一个或多个。术语“非暂时性计算机可读存储介质”因此应当被认为包括但不限于固态存储器以及光学和磁性介质。
计算机系统2100可另外包括用于实现上述编译过程的功能的语言处理器生成器2126。本文描述的模块、组件和其它特征可实施为离散硬件组件或集成在例如ASIC、FPGA、DSP或类似装置等硬件组件的功能中。此外,该模块可以被实现为硬件装置内的固件或功能电路系统。此外,该模块可以以硬件装置和软件组件的任何组合来实现。
以下详细描述的某些部分是根据对计算机存储器内的数据位的操作的算法和符号表示来呈现的。这些算法描述和表示是数据处理领域的技术人员用来最有效地将他们工作的实质传达给本领域的其他技术人员的手段。算法在这里并且通常被认为是导致期望结果的步骤的自相容序列。这些步骤是需要对物理量进行物理操作的步骤。通常,尽管不是必须的,这些量采用能够被存储、传送、组合、比较和以其他方式操纵的电或磁信号的形式。主要出于通用的原因,将这些信号称为位、值、元素、符号、字符、项、数字等已被证明有时是方便的。
然而,应当记住,所有这些和类似的术语都与适当的物理量相关联,并且仅仅是应用于这些量的方便的标记。除非特别声明,否则如从以下讨论中显而易见的,可以理解,在整个描述中,利用诸如“执行”、“确定”、“设置”、“转换”、“构造”、“遍历”等术语的讨论指的是计算机系统或类似电子计算装置的动作和过程,其操纵表示为计算机系统的寄存器和存储器内的物理(电子)量的数据,并将其变换成类似地表示为计算机系统存储器或寄存器或其他这样的信息存储、传输或显示装置内的物理量的其他数据。
本发明的实施例还涉及用于执行本文的操作的设备。该设备可以是为所需目的而专门构造的,或者它可以包括由存储在计算机系统中的计算机程序选择性编程的通用计算机系统。这种计算机程序可以存储在计算机可读存储介质中,例如但不限于,包括光盘、CD-ROM和磁光盘的任何类型的盘、只读存储器(ROM)、随机存取存储器(RAM)、EPROM、EEPROM、磁盘存储介质、光存储介质、闪存装置、其它类型的机器可访问存储介质、或适于存储电子指令的任何类型的介质,每个都耦合到计算机系统总线。
这里提出的算法和显示并非固有地与任何特定计算机或其它设备相关。各种通用系统可以与根据这里的教导的程序一起使用,或者可以证明构造更专用的设备来执行所需的方法步骤是方便的。用于各种这些系统的所需结构将如以下描述中所阐述的那样出现。此外,本发明不是参考任何特定的编程语言来描述的。应当理解,可以使用各种编程语言来实现这里描述的本发明的教导。
应当理解,上述描述是说明性的,而不是限制性的。在阅读和理解以上描述时,许多其它实施例对于本领域技术人员将是显而易见的。尽管已经参照具体的示例性实施例描述了本发明,但是应当认识到,本发明不限于所描述的实施例,而是可以在所附权利要求的精神和范围内进行修改和改变来实施。因此,说明书和附图应被认为是说明性的而不是限制性的。因此,本发明的范围应当参考所附权利要求以及这些权利要求所授权的等同物的全部范围来确定。
Claims (21)
1.一种用于在由计算装置实现的形式语言处理期间、处理基于子例程结构化图谱的中间表示的方法,所述方法包括:
根据来自源文件或一组对象文件的代码的中间表示中标识的一组子例程中的子例程之间的相互递归关系,对所述组子例程分类;
在一组子例程记录数据结构中记录所述相互递归关系;
标记所述中间表示中的相关节点或来自所述中间表示的令牌,以跟踪所述相互递归关系;
构造包括所述一组子例程中的每个子例程的图谱表示的一组图谱表示;
分析所述中间表示的图谱,所述中间表示的图谱通过经由深度优先的前序图谱遍历的序列化或穿过所述中间表示的图谱的路径行走而从所述一组图谱表示被分解为子例程图谱,收集部分位置,所述部分位置区分所生成的代码中的动作点,其中,在所述中间表示中的节点的部分位置列表中跟踪部分位置,所述部分位置列表标识所述中间表示的图谱中的点,其中,所述节点中的每个节点取自单独的子例程图谱,并且所述列表是通向终结节点的调用的回溯,并且其中,所述列表中除了终结节点之外的每个节点引用来自所述一组子例程的一个子例程;
标记来自所述部分位置列表的所述中间表示的所述图谱的节点或所述中间表示的令牌,以在所生成的代码中进行运行时间跟踪,使得在所生成的代码中的相关联的位置处执行相关联的动作;
利用前序深度优先遍历来序列化所述中间表示的图谱,生成随后的中间表示;以及
根据所述中间表示创建所生成的代码。
2.根据权利要求1所述的方法,其中,标识多组相互递归的子例程,并且关于是否在整个图谱中递归地调用这些组中的子例程,以及关于具有递归调用的节点是否作为在特定调用中要调用的组中的第一子图谱出现在整个图谱中或者是二次递归的,来对这些组中的子例程进行分类。
3.根据权利要求1所述的方法,其中,用于子例程结构化的整个图谱的前序深度优先遍历涉及:从一个位置步进到下一个位置,在从所述子例程图谱中的第一位置继续之前、解除引用子例程引用以将引用的子例程图谱推动到所述位置上,以及当子例程图谱的遍历完成时弹出位置栈,并从调用的子图谱中遇到的最后位置继续,其中,通过在所述遍历中的每个步骤处返回所述终结节点来实现序列化。
4.根据权利要求1所述的方法,其中,路径行走包括:从一个位置导航到下一个位置,在图谱节点处进行软件干预,所述图谱节点具有用于后续节点的多个替代。
5.根据权利要求1所述的方法,其中,标记包括:通过将部分位置中的各节点顺序地逻辑链接并且将部分位置中的最后一个节点逻辑链接到第一节点,将节点的社区标识为多组节点,对于所述多组节点,存在来自一组部分位置列表的从所述组中的任一节点到所述组中的任一其它节点的路径,以建立社区中的节点可达性要求,并且然后,通过邻接矩阵操作来标识社区以使所生成的标记的数量最小化。
6.根据权利要求1所述的方法,其中,标记包括标记创建以用于表示在宽度优先导航期间、通过包括社区的所述部分位置的状态转移,在所述社区中,状态转移与令牌相关联,使得先前标记转移到当前标记值或转移到所生成的运行时间代码中的功能。
7.根据权利要求1所述的方法,其中,标记包括:在每个社区内传播标记转移。
8.一种非暂时性计算机可读存储介质,其中存储有指令集,所述指令集在由计算装置执行时使所述计算装置执行一组操作,以实现用于在由计算装置实现的形式语言处理期间处理基于子例程结构化图谱的中间表示的方法,所述一组操作包括:
根据来自源文件或一组对象文件的代码的中间表示中标识的一组子例程中的子例程之间的相互递归关系,对所述组子例程分类;
在一组子例程记录数据结构中记录所述相互递归关系;
标记所述中间表示中的相关节点或来自所述中间表示的令牌,以跟踪所述相互递归关系;
构造包括所述组子例程中的每个子例程的图谱表示的一组图谱表示;
分析所述中间表示的图谱,所述中间表示的图谱通过经由深度优先的前序图谱遍历的序列化或穿过所述中间表示的图谱的路径行走而从所述一组图谱表示被分解为子例程图谱,收集部分位置,所述部分位置区分所生成的代码中的动作点,其中,在所述中间表示中的节点的部分位置列表中跟踪部分位置,所述部分位置列表标识所述中间表示的图谱中的点,其中,所述节点中的每个节点取自单独的子例程图谱,并且所述列表是通向终结节点的调用的回溯,并且其中,所述列表中除了终结节点之外的每个节点引用来自所述一组子例程的一个子例程;
标记来自所述部分位置列表的所述中间表示的所述图谱的节点或所述中间表示的令牌,以在所生成的代码中进行运行时间跟踪,使得在所生成的代码中的相关联的位置处执行相关联的动作;
利用前序深度优先遍历来序列化所述中间表示的图谱,生成随后的中间表示;以及
根据所述中间表示创建所生成的代码。
9.根据权利要求8所述的非暂时性计算机可读存储介质,其中,标识多组相互递归的子例程,并且关于是否在整个图谱中递归地调用这些组中的子例程,以及关于具有递归调用的节点是否作为在特定调用中要调用的组中的第一子图谱出现在整个图谱中或者是二次递归的,来对这些组中的子例程进行分类。
10.根据权利要求8所述的非暂时性计算机可读存储介质,其中,用于子例程结构化的整个图谱的前序深度优先遍历涉及:从一个位置步进到下一个位置,在从该子例程图谱中的第一位置继续之前、解除引用子例程引用以将引用的子例程图谱推动到所述位置上,以及当子例程图谱的遍历完成时弹出位置栈,并从调用的子图谱中遇到的最后位置继续,其中,通过在所述遍历中的每个步骤返回所述终结节点来实现序列化。
11.根据权利要求8所述的非暂时性计算机可读存储介质,其中,路径行走包括:从一个位置导航到下一个位置,在图谱节点处进行软件干预,所述图谱节点具有用于后续节点的多个替代。
12.根据权利要求8所述的非暂时性计算机可读存储介质,其中,标记包括:通过将部分位置中的各节点顺序地逻辑链接并且将部分位置中的最后一个节点逻辑链接到第一节点,将节点的社区标识为多组节点,对于所述多组节点,存在来自一组部分位置列表的从所述组中的任一节点到所述组中的任一其它节点的路径,以建立社区中的节点可达性要求,并且然后,通过邻接矩阵操作来标识社区以使所生成的标记的数量最小化。
13.根据权利要求8所述的非暂时性计算机可读存储介质,其中,标记包括标记创建以用于表示在宽度优先导航期间、通过包括社区的所述部分位置的状态转移,在所述社区中,状态转移与令牌相关联,使得先前标记转移到当前标记值或转移到所生成的运行时间代码中的功能。
14.根据权利要求8所述的非暂时性计算机可读存储介质,其中,标记包括:在每个社区内传播标记转移。
15.一种在形式语言处理期间处理基于子例程结构化图谱的中间表示的计算系统,所述计算系统包括:
非暂时性计算机可读介质,其存储有语言处理器生成器;以及
处理器,其与所述非暂时性计算机可读介质通信,所述处理器执行所述语言处理器生成器,所述语言处理器生成器用于根据来自源文件或一组对象文件的代码的中间表示中标识的一组子例程中的子例程之间的相互递归关系,对所述组子例程分类;在一组子例程记录数据结构中记录所述相互递归关系;标记所述中间表示中的相关节点或来自所述中间表示的令牌,以跟踪所述相互递归关系;构造包括所述一组子例程中的每个子例程的图谱表示的一组图谱表示;分析所述中间表示的图谱,所述中间表示的图谱通过经由深度优先的前序图谱遍历的序列化或穿过所述中间表示的图谱的路径行走而从所述组图谱表示被分解为子例程图谱,收集部分位置,所述部分位置区分所生成的代码中的动作点,其中,在所述中间表示中的节点的部分位置列表中跟踪部分位置,所述部分位置列表标识所述中间表示的图谱中的点,其中,所述节点中的每个节点取自单独的子例程图谱,并且所述列表是通向终结节点的调用的回溯,并且其中,所述列表中除了终结节点之外的每个节点引用来自所述一组子例程的一个子例程;标记来自所述部分位置列表的所述中间表示的所述图谱的节点或所述中间表示的令牌,以在所生成的代码中进行运行时间跟踪,使得在所生成的代码中的相关联的位置处执行相关联的动作;利用前序深度优先遍历来序列化所述中间表示的图谱,生成随后的中间表示;以及根据所述中间表示创建所生成的代码。
16.根据权利要求15所述的计算系统,其中,标识多组相互递归的子例程,并且关于是否在整个图谱中递归地调用这些组中的子例程,以及关于具有递归调用的节点是否作为在特定调用中要调用的组中的第一子图谱出现在整个图谱中或者是二次递归的,来对这些组中的子例程进行分类。
17.根据权利要求15所述的计算系统,其中,用于子例程结构化的整个图谱的前序深度优先遍历涉及:从一个位置步进到下一个位置,在从该子例程图谱中的第一位置继续之前、解除引用子例程引用以将引用的子例程图谱推动到所述位置上,以及当完成子例程图谱的遍历时弹出位置栈,并从调用的子图谱中遇到的最后位置继续,其中,通过在所述遍历中的每个步骤返回所述终结节点来实现序列化。
18.根据权利要求15所述的计算系统,其中,路径行走包括:从一个位置导航到下一个位置,在图谱节点处进行软件干预,所述图谱节点具有用于后续节点的多个替代。
19.根据权利要求15所述的计算系统,其中,标记包括:通过将部分位置中的各节点顺序地逻辑链接并且将部分位置中的最后一个节点逻辑链接到第一节点,将节点的社区标识为多组节点,对于所述多组节点,存在来自一组部分位置列表的从所述组中的任一节点到所述组中的任一其它节点的路径,以建立社区中的节点可达性要求,并且然后,通过邻接矩阵操作来标识社区以使所生成的标记的数量最小化。
20.根据权利要求15所述的计算系统,其中,标记包括标记创建以用于表示在宽度优先导航期间、通过包括社区的所述部分位置的状态转移,在所述社区中,状态转移与令牌相关联,使得先前标记转移到当前标记值或转移到所生成的运行时间代码中的功能。
21.根据权利要求15所述的计算系统,其中,标记包括:在每个社区内传播标记转移。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202210430047.6A CN114692600B (zh) | 2019-02-19 | 2020-02-14 | 使用子例程图谱进行形式语言处理的方法和系统 |
Applications Claiming Priority (3)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
US201962807704P | 2019-02-19 | 2019-02-19 | |
US62/807,704 | 2019-02-19 | ||
PCT/IB2020/051225 WO2020170091A1 (en) | 2019-02-19 | 2020-02-14 | Method and system for using subroutine graphs for formal language processing |
Related Child Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202210430047.6A Division CN114692600B (zh) | 2019-02-19 | 2020-02-14 | 使用子例程图谱进行形式语言处理的方法和系统 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN113508385A CN113508385A (zh) | 2021-10-15 |
CN113508385B true CN113508385B (zh) | 2022-04-26 |
Family
ID=72042101
Family Applications (2)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202080015415.XA Active CN113508385B (zh) | 2019-02-19 | 2020-02-14 | 使用子例程图谱进行形式语言处理的方法和系统 |
CN202210430047.6A Active CN114692600B (zh) | 2019-02-19 | 2020-02-14 | 使用子例程图谱进行形式语言处理的方法和系统 |
Family Applications After (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202210430047.6A Active CN114692600B (zh) | 2019-02-19 | 2020-02-14 | 使用子例程图谱进行形式语言处理的方法和系统 |
Country Status (4)
Country | Link |
---|---|
US (2) | US10891117B2 (zh) |
EP (1) | EP3928244A4 (zh) |
CN (2) | CN113508385B (zh) |
WO (1) | WO2020170091A1 (zh) |
Families Citing this family (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN115645905B (zh) * | 2022-10-21 | 2023-06-20 | 圣名科技(广州)有限责任公司 | 游标显示的方法和装置、电子设备和存储介质 |
US20240256235A1 (en) * | 2023-01-26 | 2024-08-01 | Google Llc | Syntactically coherent code segmentation |
CN115795114B (zh) * | 2023-02-10 | 2023-04-28 | 山东浪潮科学研究院有限公司 | 深度学习推理的计算图表示和存储方法及其相关组件 |
CN116841622B (zh) * | 2023-09-01 | 2023-11-24 | 上海燧原智能科技有限公司 | 一种地址自增访存指令的生成方法、装置、设备及介质 |
CN118364891B (zh) * | 2024-06-19 | 2024-09-03 | 上海燧原科技股份有限公司 | 深度学习模型中的可逆结构识别方法、装置、设备及介质 |
Citations (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US4330822A (en) * | 1971-09-02 | 1982-05-18 | Burroughs Corporation | Recursive system and method for binding compiled routines |
CN104484459A (zh) * | 2014-12-29 | 2015-04-01 | 北京奇虎科技有限公司 | 一种对知识图谱中的实体进行合并的方法及装置 |
Family Cites Families (9)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US4710872A (en) * | 1985-08-07 | 1987-12-01 | International Business Machines Corporation | Method for vectorizing and executing on an SIMD machine outer loops in the presence of recurrent inner loops |
EP1910923A2 (en) * | 2005-07-25 | 2008-04-16 | Hercules Software, LLC | Direct execution virtual machine |
FR2917866B1 (fr) * | 2007-06-20 | 2009-09-04 | Inst Nat Rech Inf Automat | Dispositif informatique pour la simulation d'un ensemble d'objets en interaction et procede correspondant |
EP3025227A1 (en) * | 2013-07-23 | 2016-06-01 | Huawei Technologies Co., Ltd. | Method for constructing a graph-based intermediate representation in a compiler |
CN106537333A (zh) * | 2014-06-13 | 2017-03-22 | 查尔斯斯塔克德拉珀实验室公司 | 用于软件产物的数据库的系统和方法 |
WO2016007923A1 (en) * | 2014-07-11 | 2016-01-14 | Craymer Loring G Iii | Method and system for linear generalized ll recognition and context-aware parsing |
CN106663094B (zh) * | 2014-07-11 | 2020-03-27 | 洛林·G·克雷默三世 | 用于线性广义ll识别和上下文感知解析的方法和系统 |
US20180315023A1 (en) * | 2017-04-26 | 2018-11-01 | General Electric Company | Subject matter knowledge mapping |
US10740075B2 (en) * | 2018-02-06 | 2020-08-11 | Smartshift Technologies, Inc. | Systems and methods for code clustering analysis and transformation |
-
2020
- 2020-02-14 CN CN202080015415.XA patent/CN113508385B/zh active Active
- 2020-02-14 EP EP20759363.3A patent/EP3928244A4/en not_active Withdrawn
- 2020-02-14 WO PCT/IB2020/051225 patent/WO2020170091A1/en unknown
- 2020-02-14 US US16/790,896 patent/US10891117B2/en active Active
- 2020-02-14 CN CN202210430047.6A patent/CN114692600B/zh active Active
- 2020-12-03 US US17/111,256 patent/US11262988B2/en active Active
Patent Citations (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US4330822A (en) * | 1971-09-02 | 1982-05-18 | Burroughs Corporation | Recursive system and method for binding compiled routines |
CN104484459A (zh) * | 2014-12-29 | 2015-04-01 | 北京奇虎科技有限公司 | 一种对知识图谱中的实体进行合并的方法及装置 |
Also Published As
Publication number | Publication date |
---|---|
CN114692600A (zh) | 2022-07-01 |
EP3928244A4 (en) | 2022-11-09 |
US11262988B2 (en) | 2022-03-01 |
WO2020170091A1 (en) | 2020-08-27 |
CN114692600B (zh) | 2023-04-18 |
EP3928244A1 (en) | 2021-12-29 |
CN113508385A (zh) | 2021-10-15 |
US20210089284A1 (en) | 2021-03-25 |
US20200264852A1 (en) | 2020-08-20 |
US10891117B2 (en) | 2021-01-12 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN113508385B (zh) | 使用子例程图谱进行形式语言处理的方法和系统 | |
CN112100054B (zh) | 一种面向数据管控的程序静态分析方法和系统 | |
US6662354B1 (en) | Determining destinations of a dynamic branch | |
US5671416A (en) | Apparatus and a method for searching and modifying source code of a computer program | |
US7958493B2 (en) | Type inference system and method | |
Wagner et al. | Incremental analysis of real programming languages | |
Claessen et al. | Generating constrained random data with uniform distribution | |
CN105138335A (zh) | 一种基于控制流图的函数调用路径提取方法及装置 | |
CN115509514B (zh) | 一种前端数据模拟方法、装置、设备及介质 | |
CN115291854A (zh) | 代码补全方法、装置及设备 | |
El-Boussaidi et al. | Detecting patterns of poor design solutions using constraint propagation | |
CN106663094B (zh) | 用于线性广义ll识别和上下文感知解析的方法和系统 | |
Ramsey | Beyond relooper: recursive translation of unstructured control flow to structured control flow (functional pearl) | |
Mennie et al. | Giving meaning to macros | |
KR20050065015A (ko) | 프로그램의 복제 여부를 검사하는 방법 및 시스템 | |
Grigorev et al. | String-embedded language support in integrated development environment | |
Bransen | On the Incremental Evaluation of Higher-Order Attribute Grammars | |
CN114003234A (zh) | 小程序局部编译方法、装置、设备及计算机可读存储介质 | |
Odebäck | CTriPio: Developing an Intermediate Representation of C code in Trieste for Static Analysis | |
Rowland | Combining parsing and evaluation for attributed grammars | |
CN116755700A (zh) | 一种数据收集方法、装置及介质 | |
CN117806647A (zh) | 基于软件流程图的c程序合成方法及装置、设备、介质 | |
CN112650680A (zh) | 基于抽象语法树的冗余变量和冗余方法的检测方法及系统 | |
CN114329492A (zh) | 一种针对Go语言链码的漏洞检测方法 | |
CN117785213A (zh) | 基于Rust开发的前端构建工具及构建方法 |
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 |