没有合适的资源?快使用搜索试试~ 我知道了~
理论计算机科学电子笔记141(2005)77-98www.elsevier.com/locate/entcs一个局部到全局变换Thomas Cleenewerck托马斯·克莱内韦克1,2PROG比利时布鲁塞尔自由大学Johan Brichau3PROG比利时布鲁塞尔自由大学摘要转换系统特别适合于实现模块化规则,将源语言的一个语言特征转换为目标语言的单个语言特征或语言特征的组合。然而,在实践中,必须编写转换规则,这些规则采用一种语言特征并将其转换为属于输出程序中不同位置的几种语言特征这些所谓的局部到全局的转换与重写规则的实现是非常复杂和紧密耦合的,这对维护和进化性施加了严格的约束目前的实现的四个主要耦合问题,我们指出这些可以消除和减少我们的重写规则系统的扩展。此外,我们展示了如何复杂的侵入性组合物可以解决抽象的,可重用的算法和机制,渲染本地到全球的transforma- tions到一个半自动的过程中的实施关键词:可维护性,可演化性,重写规则,程序转换,侵入式组合1这项研究部分是在e-VRT先进媒体项目(由佛兰德政府资助)的背景下进行的,该项目由VRT,VUB,UG和IMEC之间的联合合作组成2电子邮件地址:tcleenew@vub.ac.be3电子邮件地址:jbrichau@vub.ac.be1571-0661 © 2005 Elsevier B. V.在CC BY-NC-ND许可下开放访问。doi:10.1016/j.entcs.2005.02.05478T. Cleenewerck,J.Brichau/Electronic Notes in Theoretical Computer Science 141(2005)771引言今天使用的最主要的转换类型是重写规则[6,16,9]。它们非常成功,因为指定规则的简单性和底层转换系统的强大功能,该系统已经解决了调度[12]等复杂性,并提供了适当的控制结构,如模式匹配[15]。重写规则指定用目标AST的一部分替换源抽象语法树(AST)的一部分。因此,重写规则相对于目标和源语言的语法以及相对于其他规则是模块化的。 这意味着重写规则只涉及变换树的一部分,而不涉及上下文信息。因此,它可以在源AST的上下文可能不同的其他实现中重用。然而,仅仅由这样的“就地”转换组成的实现几乎是无法表达的。通常,单个 转 换 必 须 在 目 标 AST 的 其 他 部 分 上 施 加 一 些 输 出 。 在 Jonne vanWijngaarden et. [15]这些类型的变换被称为局部到全局变换。仅通过重写规则实现局部到全局的转换是非常复杂和混乱的。将转换系统扩展到重写规则范例,使用各种数据获取技术,如查询和树遍历[14],并没有减少混乱。我们发现,类似于其他软件开发技术,这种纠缠严重危及未来的维护和发展。在早期的工作[4]中,我们提出了一个重写规则系统的扩展,它可以解开实现。这是通过提供半自动过程来实现的,该半自动过程处理当前可用的“就地”替代机制不能处理的输出。在本文中,我们确定了当前实现中的4个主要耦合问题,并展示了如何通过我们的方法进行修改。此外,我们显示如何通过抽象和可重用的集成策略来解决复杂的侵入式组合。在下面的部分中,我们将研究迫使开发人员编写复杂的重写规则的基本问题。第3节介绍了我们的解决方案体系结构,其中更详细地解释了该体系结构。在第4节的架构进行评估,并讨论了该方法的影响。第5节讨论了相关工作,第6节总结了本文。T. Cleenewerck,J.Brichau/Electronic Notes in Theoretical Computer Science 141(2005)7779W向导(P页(Iinputfield(“appname”defvalue(“T”))I inputfield(“appdir”)Ddefvalue(stats((return(+(+(K(key(programpath)“/”)appname)))))Fig. 1. 用WIZ编写的安装程序的源AST。2局部到全局的转换我们构思了一个小型领域专用语言(DSL)来说明使用重写规则实现局部到全局转换的问题然后,我们概括这些具体的例子,并提炼出削弱可维护性和可演化性的根本原因。2.1激励的例子我们作为例子使用的小型DSL称为WIZ语言。它被设计用来描述安装向导。用WIZ编写的程序被转换成框架之上的Java程序。WIZ的目的是让开发人员避免使用冗长的粘合代码,并封装最佳实践来实例化底层框架。WIZ的表面语法对本文来说并不重要,相反,我们描述了如何使用该语言以及AST上的转换如何实现到Java的翻译。图1的示例WIZ程序描述了一个向导,页. 该页面包含应用程序名称(appname)的输入字段以及安装目录(appdir)的输入字段。默认值是注册表项programpath(保存应用程序的默认位置)和应用程序名(appname)连接的结果。当应用程序名称更改时,将重新计算程序路径(依赖于它)期望的转换此规格后的结果如图2A所示WIZ编译器的实现分为5个转换。每个转换对应于一个源AST节点到其Java计数器部分的转换。源AST节点是分别由W、P、I、D、K转换转换的向导、页面、输入字段、定义值和键。在图1中,节点通过将预固定节点作为输入的变换进行预固定。 这些转换产生的结果节点如图2A所示,也使用相同的前缀进行了前缀化。图2A清楚地显示了由转换产生的目标AST节点分散在所需的目标程序中。这种分散不是偶然的情况,而是结构性的问题80T. Cleenewerck,J.Brichau/Electronic Notes in Theoretical Computer Science 141(2005)771 W class(datamount(“Wizard”“向导”)2 I datamount(“Inputfield”“appname”)3 I datamount(“Inputfield”“appdir”)4 K datamount(“Key”“programpath”))5 W方法(“main”(.)(统计数据)6 Kassign(var(“programpath”)new(“Key”))7 Wassign(var(“Wizard”)new(“Wizard”))8 Passign(var(“page”)new(“Page”))9 我分配(var(“appname”)new(“InputField”))10 Iassign(var(“appdir”)new(“InputField”))11我mcall(var(“appname”)设置12 I(.mcall(()“appdirdefvalue”()).))13 I mcall(var(“appname”)setValue(“T”))14 I mcall(var(“appdir”)setValue15 D(mcall(()“defvalue”())))16 Pmcall(var(“page”)“add”(17 I var(“appname”)18 Pmcall(var(“page”)“add”(19 I var(“appdir”)20 W mcall(var(“wizard”)“add”(21 P var(“page”))22 W)23 D方法(“defvalue”()(stats(24 Dreturn(+(+)mcall(25 K var(“programpath”)“getValue”())“/”)26 D mcall(var(“appname”)“getValue”()27 D)1 class(datamount(“Wizard”“wizard”)2 datamounts(“Inputfield”“appname”)3 方法(“main”(.)(统计数据)4assign(var(“Wizard”)new(“Wizard”))5assign(var(“page”)new(“Page”))6assign(var(“appname”)new(“InputField”))7mcall(var(“appname”)setValue(“T”))8mcall(var(“page”)“add”(var(“appname”)9mcall(var(“page”)“add”(10CONS(var(“appdir”)11(不包括)12assign(var(“appdir”)new(“InputField”))13mcall(var(“appname”)setName14(... mcall(()“appdirdefvalue”()). )的情况)15mcall(var(“appdir”)setValue16CONS(mcall(()“defvalue”()17(不包括)18方法(“defvalue”()(stats(19return(+(+)CONS(20(mcall(var(“programpath”)“getValue”())“/”))21(NONONDATA(datamount(“Key”“programpath”)22NONKEY(assign(var(“programpath”)new(“Key”)23mcall(var(“appname”)“getValue”()24)(第25段)(第26段))27NONLOAD(datamount(“Inputfield”“appdir”))28mcall(var(“wizard”)“add”(var(“page”)29)图二. (A)图的左半部分显示了转换示例安装程序后获得的目标AST(图1)。(B)右边的部分显示了目标AST在输入字段转换产生的非局部变量的重定位和积分开始之前的状态。这两种语言之间。一个转换的结果节点可能不会全部替换源节点。只有特定类型的结果可以用源节点替换,以确保结果AST是类型正确的。不适合的结果必须放在树的其他地方。例如,源键节点是表达式的一部分,因此键转换产生的结果必须是表达式,以便产生正确的目标程序。它的其他结果,数据表和语句,因此必须放在目标程序的其他位置。除了类型问题之外,由于语法约束或DSL开发人员施加的特定语义约束,一些结果节点属于目标2.2使用重写规则重写规则描述了为了处理不适合位置的其他结果,即所谓的非局部结果,我们需要一个T. Cleenewerck,J.Brichau/Electronic Notes in Theoretical Computer Science 141(2005)7781解决办法人们可以想到几种变通方法,但它们都归结为以下策略。由于大多数重写规则系统都已经扩展了某种遍历机制[14],因此我们将在讨论解决方案时仅考虑局部到全局的转换被分解为几个重写规则和遍历,每个重写规则和遍历负责一个结果。每个转换的实现都需要三个步骤。首先,必须编写产生本地和非本地结果的主要重写规则。结果包含在一个元组(CONS(. 、...)细胞其次,为每个非本地结果编写一个二级遍历,以收集非本地结果。第三,必须将收集的非本地数据馈送到与非本地数据必须被集成的正确目标位置相匹配的次级重写规则中。虽然主要的重写规则是模块化的,但它们构造了一个中间表示(IR),这是一种新的结构,在语言发展时必须额外维护。因此,这种解决方案只会增加维护工作量。使用这种方法的实验表明,从Cobol到Java的转换需要大约70个IR [CDMS02],引入了大量的维护工作。此外,问题仅仅被转移到创建中间结构的转换上,因此没有创建真正的解决方案2.3耦合和缠结在各种软件开发方法中,促进演化和维护的最常见方法之一是最小化实现中的纠缠和耦合。通过这样做,一个实现的组件可以更容易地被另一个实现替换,并且可以在其他实现中重用。由于一组转换的实现可以被视为一个正常的软件工件,减少纠缠和耦合保持相同的前提。在本节的提示中,讨论了解决方案策略的耦合和纠缠问题这种策略的纠缠和耦合问题的根源是二次遍历和重写规则与其余重写规则的依赖性。我们区分以下4个耦合问题:(i) 变通方法的机制与局部到全局转换的具体实现交织在一起,以至于很难在其实现中区分它们。此外,它们的实现是手动的,并且降级为更具功能性的方法(说明如何而不是什么)。(ii) 二次遍历和重写规则的耦合以及输出-82T. Cleenewerck,J.Brichau/Electronic Notes in Theoretical Computer Science 141(2005)77主要重写规则。(iii) 二次遍历和重写规则的调度问题,以不违反其他二次遍历和重写规则的上下文条件。(iv) 二次遍历和重写的紧耦合对AST在变换过程中的某个阶段的确切性质起着决定性的作用。导致这3个后面的依赖关系的根本问题是,第二个重写规则和遍历都在已经完全重写到目标节点的树上操作。因此,它们的匹配子句完全用目标节点来表示。因此,由于演化或维护而导致的源语言的语法或转换的实现中的任何小的改变都容易破坏在二次遍历和重写规则的实现中所产生的大部分依赖性。让我们使用图2B更详细地讨论这些依赖关系中的每一个。第一个问题是次要遍历和重写规则与主要重写规则的结果的紧密耦合。考虑二次遍历和重写规则来收集和移动输入字段转换的非局部变量:最上面的cons单元格(第10行)的两个非局部语句(一个赋值(第12行)和两个方法调用(第13行和第15行))。 这两个非局部变量必须移到封闭方法节点中。 编写这样的遍历在很大程度上依赖于由页面转换和输入字段转换的非局部变量(第12-15行),以确保匹配正确的非局部变量。与遍历一样,在正确位置上集成非局部的次级重写规则的左手边、触发条件和右手边也用目标节点表示,这导致了相同的缺陷。第二个问题是二次遍历和重写规则的调度问题,以便不违反其他二次遍历和重写规则的上下文条件。 让我们来看看输入字段转换的二次遍历和重写规则的调度,以及默认值转换和键转换的调度。后者处理cons单元格的嵌套cons单元格中的非局部变量(第10行,由输入字段转换产生)。由键转换生成的非局部语句(第22行)的正确位置在main方法的开头。然而,根据处理cons细胞的策略,非本地人可能会在不同的位置结束。一个广度优先(自顶向下)策略,将非局部语句(第22行)放在其封闭方法defvalue中。但一个深度优先(自下而上)的策略来处理缺点,T. Cleenewerck,J.Brichau/Electronic Notes in Theoretical Computer Science 141(2005)7783单元格,将非局部语句(第22行)放在main方法中。因此,这些二次遍历和重写规则的实现取决于所选择的调度,反之亦然。第三个问题是二次遍历和重写规则在转换过程中的某个阶段对AST的确切属性的紧耦合。由于二次遍历和重写规则不断地改变树,它们的规范取决于转换过程中的特定阶段。例如,考虑由输入字段转换产生的不同非局部语句的集成:分配和创建新字段(第12行),将侦听器附加到其他依赖的输入字段(第13行)以及使用默认值初始化输入字段(第15行)。 虽然从一个输入字段的角度来看,这些语句的顺序是正确的,但当有两个或更多输入字段时,这些语句需要重新组合。很明显,首先必须在初始化或配置它们之前创建所有输入字段,其次必须将所有侦听器附加到每个输入字段,以便第三,当初始化输入字段时,所有相关输入字段都得到正确初始化。 重组的实现并不简单,并且严重依赖于main方法的内容。 重写规则几乎完全匹配主方法体的状态,以确定集成创建的正确位置新的输入字段,监听器的连接和输入字段的初始化。此外,由于main方法的内容通过移动和整合非局部语句而不断变化,因此整合重写规则仅在转换过程的特定点上起作用。3非本地目标节点我们的解决方案架构将本地到全局转换的三个职责模块化为3个步骤:(1)生成步骤,生成本地和非本地目标节点;(2)重定位步骤,通过目标AST导航以找到非本地节点的位置;(3)集成步骤,将生成的目标AST节点添加到该位置。最后两个责任由组合系统处理,该组合系统由声明性规范驱动,声明每个非局部变量的目标位置以及将非局部变量集成到树中。所需的声明性规范的某些部分可以从目标语言语法中自动导出,从而产生半自动组合系统。在下面的小节中,我们将详细描述每个步骤。由于该架构被认为是现有系统的扩展,84T. Cleenewerck,J.Brichau/Electronic Notes in Theoretical Computer Science 141(2005)77现有系统的复杂性及其各种性质迅速使其实施的讨论复杂化。因此,对该架构的实现的全面讨论超出了本文的范围。然而,每个小节都清楚地说明了实现架构所需的机制3.1生成步骤为了在重写规则中区分非本地目标节点和本地目标节点,非本地节点被附加到一个特殊的NONLOCALS(.)节点,该节点又与本地目标节点一起是cons单元的一部分。下面的示例代码显示了如何将键转换编写为正常的重写规则。KEY(NAME)-->CONS(mcall(var(NAME)“getValue”()NONKEY((“datamounts”,datamounts(“Key”NAME))(“initialize”,assign(var(NAME)new(“Key”)该系统的一个关键部分和解决方案之间的区别是,非本地人可以携带任何类型的信息。 这被半自动合成系统大量利用,以识别非局部变量并指导非局部变量的集成过程(见第3.3.2节)。为了简化和标准化非本地的识别,非本地总是至少有一个名字或一个身份证。与处理名称和标识符的常见方法相反,这些在重写规则中或在其他重写规则中不需要是唯一的。这种命名模式的优点是名称或标识符可以用作分组机制,抽象出非局部变量的实际数量。附加信息可用于选择遵守某些标准的子组。在上面的例子中,第一个非局部变量的名字是datamaret,第二个非局部变量的名字是initialize。没有提供其他补充资料,因为从名字上可以看出两者的区别。3.2重新定位步骤重定位步骤在执行所有模块化重写规则之后执行。在该步骤中,将非本地目标AST节点移动到它们在目标AST中的正确位置。非本地AST节点的正确位置由(1)目标语言的语法和(2)特定于所需目标程序的自定义语义确定。非局部变量的重定位(其正确位置基于目标语言的语法)现在由目标语言语法驱动,甚至可以自动化。非局部变量的重定位(正确的位置是基于自定义语义的)需要手动编写。T. Cleenewerck,J.Brichau/Electronic Notes in Theoretical Computer Science 141(2005)77853.2.1自动的重新定位通常,如果NL可以是子节点,则非本地NL可以被集成在节点E中根据目标语言的语法, 每个非本地目标节点在AST中向上提升,直到找到节点E,其中非本地目标节点NL可以被整合到E正确的孩子是由深度优先,从左到右的策略决定的。该算法的更多细节可以在[4]中找到。让我们来说明这个自动重定位过程是如何用于输入字段转换的。此时解析树的状态如图2B所示。输入场变换产生了两个非局部状态和一个非局部数据量。datamember的自动重定位过程将在树中向上移动datamember,直到它找到一个节点,根据Java的语法,该节点可以包含其他datamember。第一个能够这样做的节点是类节点(第1行)。类似地,语句的自动重定位过程将产生主方法节点(第3行)的stats非本地节点的实际集成将通过下一节中解释的集成步骤来执行。自动重定位仅在可以明确地确定非本地人的位置的情况下或者在存在简单的消除歧义的策略的情况下在领域特定语言(DSL)的情况下,自动重定位非常适合。领域特定语言承载了许多只能在特定上下文中使用的语言结构,因此通常不需要消除歧义。该技术对于通用目的语言的目标语言也是有用的。类、数据成员、方法和语句是典型的语言结构,只允许在特定的上下文中使用。如果其他语言结构(如表达式和语句)的位置无法明确确定,但最近的可能位置通常是所需的位置。然而,自动解析对于语言中的大多数类型的非局部变量都失败了,例如HTML,其中大多数语言结构可以用于其他语言结构中。对于这些语言,必须使用自定义重定位。3.2.2自定义搬迁如果自动重定位失败或重定位依赖于目标程序的特定语义,则必须由用户定义自定义重定位。非本地的自定义重定位路径在生成非本地时未指定。相反,路径是通过以下形式的86T. Cleenewerck,J.Brichau/Electronic Notes in Theoretical Computer Science 141(2005)77NONNING(_nameof thenonlocal_,NODE)OF_sourceastnode_-->NONLOCATE(_name of the nonlocal_,RELOCATE(NODE,_relocation path_))用下划线括起来的部分只是值的占位符他们表示。 由某个源AST节点产生的非本地NODE由其名称和源AST节点引用。它被重写为具有自定义重定位路径的非本地。重定位路径也用源AST来表示。相应地,重定位路径表示非本地节点应该被重定位到顶层目标AST节点,这是自定义重定位路径指向的源AST节点转换的结果,进一步集成到顶层目标AST节点的子树中是通过集成规则来完成的(下一节)。让我们用一个例子来说明上述情况考虑由初始化非局部数据映射的密钥转换产生的非局部状态(图2B中的第22由于datamount必须只初始化一次,因此初始化语句的正确位置是在main方法的开头。关键字的非初始化(INITIALIZE,NODE)-->非初始化(INITIALIZE,RELOCATE(NODE,//向导))上述规则将替换通过转换关键源AST节点产生的初始化非本地节点(用NONCLIENT(INITIALIZE,NODE)表示),为附加指定路径的非本地节点。路径//向导指向通过转换源AST祖先向导获得的主方法目标AST节点。表达路径的语言是[1]。3.2.3讨论我们没有根据目标节点指定重定位,而是根据源AST节点和nonlocal的名称使用“特殊”重写规则来指定重定位重定位路径和非局部之间的这种解耦禁止了产生非局部的规则和语言实现的其余部分之间的强依赖性。因此,产生非局部变量的重写规则与其他重写规则之间由第二耦合(第2.3节)通过消除这些依赖性,对语言实现的其余部分(语法和重写规则)的更改将不再使产生非局部的重写规则无效,而是仅使非局部结果必须被重定位到的对象无效,因此将仅在重定位路径上具有对象。T. Cleenewerck,J.Brichau/Electronic Notes in Theoretical Computer Science 141(2005)7787某种依赖。“特殊”重写规则只建立了AST源节点和非本地的名称的依赖性。这是一个较弱的依赖关系,它只依赖于AST源节点,并且依赖于这样一个事实,即源AST节点的转换产生了一个非局部可识别的,一个名字因此,该规则对于语言实现的未来演变(即,对其他重写规则的更改、它们产生的结果等)来说更加可维护且更加鲁棒。源AST之上的路径对于由重定位阶段和随后的集成阶段(其在接下来描述)对产生目标节点的重写规则的修改引起的对产生的目标AST的改变更鲁棒。此外,不需要详细的知识来进一步将非局部节点集成到所产生的顶级目标节点AST节点的子树中。实际的集成在单独的集成规则中捕获。这最小化了重新定位非本地节点的重写规则与产生顶级AST节点的重写规则之间的依赖性。3.3积分步长在上一节中,我们看到重定位将非局部变量移动到由重定位中描述的源AST节点的转换产生的顶级目标AST节点在最后一步中,非局部变量被侵入性地集成到子树中(从顶层目标AST节点开始)。3.3.1方法集成确保根据特定集成的语义和特定的语言约束,非局部变量被正确地集成到重定位路径所指向的例如,由输入字段转换产生的非局部语句到主方法体中的集成必须遵守用户定义的不同语句的顺序(首先创建所有输入字段,然后附加listeners,最后用默认值初始化它们另一个例子是将同一个transformation产生的非局部数据对象集成到主类中,这必须强制类中数据对象的唯一性约束一体化是一体化、对应化、结合化三种不同政策的紧密结合.为每个被重新定位到AST节点的非本地调用集成策略。它的任务是在AST节点本身或它的一个子节点中使用对应策略88T. Cleenewerck,J.Brichau/Electronic Notes in Theoretical Computer Science 141(2005)77通过集成策略检查AST中的节点是否需要与非本地合并。对应策略更像是在节点上定义的谓词,用于检查它们是否对应。合并策略执行节点之间的合并。一个非局部的积分是由一个包含规则名称和一些附加信息的积分、对应和组合节点的三元组(见下面的例子)指定的(政策1),对应(策略2)、组合(策略3))与自定义重定位路径类似,要使用的特定集成规则相反,要使用的特定规则也通过“特殊”重写规则附加到非本地,从而呈现相同的进化和可维护性要使用的规则通过以下形式的“特殊”重写规则附加到非本地NONNING(_nameof thenonlocal_,NODE)OF_sourceastnode_-->NONNING(_name of the nonlocal_,((INTEGRATION(POLICY1),CORRESPONDENCE(POLICY2),COMBINATION(POLICY3)),NODE))3.3.2一体化我们将从最简单的集成规则案例开始,即通用集成规则。然后,通过一个更复杂的例子解释了自定义集成规则.虽然集成依赖于特定的非本地和特定的目标子树,我们的体系结构提供了一个通用的集成规则,为每种目标AST节点实例化。通用集成规则减轻了开发人员繁琐的集成规则(例如遍历中间结构)。通用集成策略不能直接写入重写规则,需要为每种目标AST节点生成。用于AST节点NODE(NODE1*,NODE2*,.,NODEn*)首先从最左边的部分开始确定非本地节点NODEi*属于哪个第二,节点NODEi1,...,搜索与非本地节点对应的NODEim。当找到对应节点时,将该节点和非本地节点组合。否则,非局部被附加到部分NODEi*。类节点的通用集成策略的实例化如下所示。这两条规则将非本地NODE与默认的集成策略(第6行)集成到类节点的子节点NODE*中。 当其中一个NODE*节点使用POLICY2对应时,非本地节点NODE与之组合(第8行),否则仅将非本地节点添加到主体T. Cleenewerck,J.Brichau/Electronic Notes in Theoretical Computer Science 141(2005)7789第二条规则,第11行)。(1)节点 * =节点1 * 节点2节点2 *(2)CORRESPOND(POLICY2,NODE2,NODE)=TRUE(3)==>(4)INTEGRATE(DEFAULT,CLASS(NODE*),(5)NONDED(名称,(6)((INTEGRATION(DEFAULT),(7)对应(策略2)、组合(策略3))、节点))(8)= CLASS(NODE1* COMBINE(POLICY3,NODE2,NODE)NODE2*)(9)INTEGRATE(DEFAULT,CLASS(NODE*),NONLOAD(NAME,(10)((INTEGRATION(DEFAULT),CORRESPONDENCE(POLICY2),(11)组合(策略3)),节点))=类(节点 * 节点)注意,通用集成规则是可能的,因为集成被分成集成规则、组合规则和对应规则,所有这三个规则都由不同的重写规则集实现。当然,也可以提供自定义集成规则输入字段转换产生的非局部语句的集成必须重新组合语句,以便首先创建所有输入字段,然后安装侦听器,最后使用默认值初始化输入字段我们将利用我们系统的开放性,特别是每个非局部可以携带任意数量的信息来指导整合过程的事实(见3.1)。通过给每个非局部语句附加一个标识符,我们可以在集成过程中轻松地对语句进行分组组的顺序可以通过附加信息来指定,这些附加信息可以通过积分规则来下面显示了实现此集成规则的两个重写规则。非局部节点NODE用它所属的组(NAME)和指定其集成的三元组进行注释。 集成除了包含集成规则(GROUP)的名称外,还包含组的名称第一条规则是将非局部节点插入到语句列表(STATS)中,位于与非局部节点属于同一组(NAME)的第一个语句之前。 当没有这样的语句时,第二条规则将非局部语句插入到必须在它之前的语句组的(1)INTEGRATE(组,STATS(CONS1* CONS(NODE1,NAME)CONS2*), NONDED(NAME,((INTEGRATION(GROUP,NAME2),对应(默认)、组合(默认))、节点))= STATS(CONS1* CONS(NODE,NAME)CONS(NODE 1,NAME)CONS2*)(1)INTEGRATE(组,STATS(CONS1* CONS(NODE1,NAME)CONS2*), NONDED(NAME,((INTEGRATION(GROUP,NAME2),对应(默认)、组合(默认))、节点))= STATS(CONS1* CONS(NODE 1,NAME)CONS(NODE,NAME 2)CONS2*)90T. Cleenewerck,J.Brichau/Electronic Notes in Theoretical Computer Science 141(2005)77通过上述集成规则集实现非局部语句的重新分组不是针对特定转换的特定集成。集成规则是从语句所需的特定重新分组中抽象出来的,因为它们只实现了部分排序。实际的排序由附加到非局部变量的声明性信息驱动。因此,集成规则可以重用于需要偏序的类似情况。3.3.3对应非局部变量的集成受到目标语言约束和自定义语义的约束。例如,不能简单地将数据成员因此在集成过程中(参见3.3.2节),我们需要将非本地数据库与其他数据库成员进行比较,以确保这一约束。对应规则是声明两个节点是否对应的声明性规范。它们被实现为规则,当两个节点对应时,将包含名称和需要比较的两个节点的CORRESPOND节点转换为TRUE下面的对应规则称为DEFAULT,它规定当两个数据成员的名称相同时,它们对应CORRESPOND(DEFAULT,DATAMEMBER(NAME,TYPE),DATAMEMBER(NAME,TYPE2))= TRUE正如您所看到的,对应规则完全独立于WIZ语言的实现,只涉及目标语言节点。3.3.4组合组合规则是将两个AST节点组合在一个节点中的声明性规范。 它们是通过在COMBINATION节点上操作的重写规则实现的。与CORRESPOND节点类似,COMBINATION节点包含三个部分:名称和需要组合的两个节点。第一个节点是非本地节点,第二个节点是AST的一部分组合的结果是一个新节点。我们不能使用WIZ语言的当前实现来说明组合规则,因为不需要组合规则。但是,如果我们使用密钥转换的替代实现,则需要方法的组合规则KEY(NAME)-->CONS(mcall(var(NAME)“getValue”()NONKEY((“datamounts”,datamounts(“Key”NAME))(“initialize”,method(“main”()(stats(assign(var(NAME)new(“Key”)))))))而不是生成非局部赋值语句来初始化T. Cleenewerck,J.Brichau/Electronic Notes in Theoretical Computer Science 141(2005)7791nonlocal数据对象,重写规则产生一个nonlocalmain方法。重定位过程将主方法节点提升到根节点类,随后通过集成过程集成主方法节点。因为Java类不能包含两个具有相同签名的方法,发现两种主要方法之间存在对应关系,因此,必须将两种方法的主体结合起来。当然,有多种方法可以组合两个方法主体。它们中的每一个都可以编码在单独的重写规则中。在下面的两个主要方法的ONTOP组合规则中,非局部方法主体放置在另一个方法主体之前。组合(顶部,METHOD(NAME,ARGS,STATS(STATEMENT*)),METHOD(NAME,ARGS,STATS(STATEMENT*2)= METHOD(NAME,ARGS,STATS(STATEMENT* STATEMENT*2))上面的规则只是简单地连接方法体,而没有考虑可能的变量声明冲突,或者方法的参数名中的冲突。后者可以通过对偏离的方法主体进行适当的协调来进行修改。前者可以通过使用简单的遍历和条件扩展规则来修改(规则如下所示)。为了避免在合并方法的范围内重复变量声明,两个方法的变量声明的交集必须为空(第3行)。计算变量声明的集合是通过对两个方法的主体进行自顶向下的遍历来完成的,其中每个变量声明都被收集为一个集合(第1行)。当遇到其他节点时,遍历中断(第2行),以禁止遍历到内部作用域。(1) VARDECLS(VARDECL(VAR,TYPE,EXP),VARDECL*)=VARDECL* VARDECL(VAR,TYPE,EXP)(2) VARDECLS(NODE,VARDECL*)= VARDECL*(3) intersection(VARDECLS(STATS(STATEMENT*,[]),(4)VARDECLS(STATS(STATEMENT*2,[])= [](5)==(6)组合(顶部,METHOD(NAME,ARGS,STATS(STATEMENT*)),METHOD(NAME,ARGS,STATS(STATEMENT*2)= METHOD(NAME,ARGS,STATS(STATEMENT* STATEMENT*2))与对应规则一样,组合规则也是以单独的规则来陈述的,并且只涉及两个节点的组合。因此,这些组合规则的优点也与对应规则的优点相同:模块性和可重用性,从而减少了实现的复杂性,并对编译器实现的维护和发展产生了积极的影响。92T. Cleenewerck,J.Brichau/Electronic Notes in Theoretical Computer Science 141(2005)773.3.5讨论通信检查促进了许多必要和有趣的机制。两个最重要的机制是部分结果的组合和唯一性约束的强制执行。通过在两个部分主要方法之间建立对应关系,在集成过程中将它们组合在一起成为一个完整的方法。通过在数据成员节点之间建立一个对应关系(第3.3.3节),我们能够强制类中的数据成员必须是唯一的。集成过程的分离产生集成、对应和组合规则,这些规则被很好地分离为不同的关注点。这种分离的优点有两个方面:提高了可重用性和可维护性。以下三个论点支持这一主张。首先,通过为每个关注点提供任意数量的规则,可以更容易地定制和裁剪集成。这些替代方案与其他现有规则无缝地协同工作,使开发人员能够重用大部分现有的集成逻辑。说明这种定制的优点的一个示例是通用集成规则。由于集成是在一个单独的关注点中捕获的,因此我们能够提供自动生成的集成规则,这些规则可以与自定义指定的对应和组合规则进行确认。第二,对应和组合规则只涉及目标语言节点,使得它们即使在共享相同目标语言的多个实现中也是可重用的。甚至集成规则也可以抽象为一般集成策略的级别,方法是用附加到非局部变量的声明性信息第三,非本地人的融入过程并不取决于融入过程中的某个阶段。这是通过两个属性实现的:可创建性和声明性。首先,集成规则在生成的目标AST中增量地集成非局部变量。这样,我们就可以放松对目标AST的特定状态的集成要求。其次,集成规则由附加到非局部变量的信息驱动。这使我们能够将积分规则从手头的特
下载后可阅读完整内容,剩余1页未读,立即下载
cpongm
- 粉丝: 4
- 资源: 2万+
上传资源 快速赚钱
- 我的内容管理 收起
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
会员权益专享
最新资源
- zigbee-cluster-library-specification
- JSBSim Reference Manual
- c++校园超市商品信息管理系统课程设计说明书(含源代码) (2).pdf
- 建筑供配电系统相关课件.pptx
- 企业管理规章制度及管理模式.doc
- vb打开摄像头.doc
- 云计算-可信计算中认证协议改进方案.pdf
- [详细完整版]单片机编程4.ppt
- c语言常用算法.pdf
- c++经典程序代码大全.pdf
- 单片机数字时钟资料.doc
- 11项目管理前沿1.0.pptx
- 基于ssm的“魅力”繁峙宣传网站的设计与实现论文.doc
- 智慧交通综合解决方案.pptx
- 建筑防潮设计-PowerPointPresentati.pptx
- SPC统计过程控制程序.pptx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功