基于部件的源代码生成器的制作方法

文档序号:6419192阅读:667来源:国知局
专利名称:基于部件的源代码生成器的制作方法
技术领域
本发明涉及源代码生成器,更具体地说,本发明涉及在基于部件进行编程情况下生成的源代码。尤其是,利用生成指令和参数集,生成器生成接近重复的源代码和重复源代码供开发者使用。
背景技术
通过增加使用用于进行编程、项目管理和系统集成的面向对象模型,最近几年软件开发过程发生了戏剧性的变化。
企业应用程序是大型的复杂系统,该系统将抽象的商务习惯转变为特定过程和事件驱动交互。这些应用程序形成组织方法的核心。
公司可以以多种方法收集并提取“最切实可行的作法”。在许多情况下,对整个组织创建定制软件既无利益又超出企业的能力。因此,为了获得软件解决方案,这些公司求助企业应用程序软件销售商。可以将各式各样的软件简称企业资源计划(Enterprise ResourcePlanning)(ERP,由如Peoplesoft和ASP的销售商推出)、客户关系管理(Customer Relationship Management)(Vantive、Clarity、Siebel推出)以及职业服务自动化(Professional Services Automation)(Niku、Visto推出),这些系统可以简化商务运作过程。
各公司之间相互不同,然而,这些差别使得各公司之间产生竞争。为了将他们的不同能力转化到电子处理过程,公司必须使他们的企业应用程序适合他们的工作方式。这意味着需要花费时间对应用程序进行调整、改变和生成。
解决此问题的一种方法是公知的“参数化”方法。在参数化过程中,为了使应用程序的操作过程适合商务的实际要求,受过培训的ERP专家配置许多参数和变量。
第二种方法是调整现有企业应用程序,即选择现有通用应用程序然后直接调整其源代码。直到最近,由于其独一无二的商务活动需要高度专业化应用程序的公司仍面临着支付许可费并根据这些通用应用程序重写大量代码的问题。
公司使用源代码定制应用程序,作为对缺少控件和利用现有应用程序对他们提供定制应用程序的响应。同样,他们使用参数化的ERP作为对缺少维护能力和特许软件或内部开发系统的复杂编码的响应。对这两种方法的一种强有力的替换方法是面向对象的框架方法。
应用程序的开发过程总是从一组不完整、不精确而且有时是互相矛盾或互相不一致的要求开始进行的。对于复杂系统的开发者和分析师,从正在建立的应用程序的开头就明确定义是一项困难工作。
面向对象的程序设计方法学力求利用描述现实世界的更准确模型来校正这种不精确。作为编码过程模型的后继,为了容易地对不同的对象进行综合,面向对象技术创建公共词汇表和精确定义的边界。这有助于开发者将应用程序的范围和交互定义为一组分立部件,改善对软件的设计并方便对软件进行后续调整。
开发者和系统分析员使用称为建模工具的高级设计工具以从专用编程语言、操作系统和应用程序在其上运行的硬件的物理实现过程中抽象出来的逻辑方式对应用程序的商务目的进行描述。
有了对应用程序的抽象描述就减少了创建并维持各种软件迭代,软件迭代将在其寿命期内持续进行。如果工作是在百万行的程序中定位一项功能性,则模型提供的引导变得非常宝贵。
为了在建模销售商之间推进一致性方法,业内开发出通用建模语言(UML)以将在应用程序的分析和设计期间使用的单元标准化。UML被广泛接受以及基于部件的开发方法的出现使得可以使用起始指向任意面向对象开发方法的建模工具。
公司开发采用基于框架解决方案的多等级电子商务应用程序,而不根据草稿设计应用程序,基于框架解决方案提供具有类似持续性、安全性和事务性的服务。专用框架即面向对象的抽象,面向对象的抽象提供可扩充的协同操作类库,对给定问题域组成可重复使用的设计方案。实际上,框架提供通用解决方案,对于该解决方案,开发者需要在各部件内实现作为部件到框架综合代码的专用代码以说明其在框架内的特定过程。
比起特许过程源代码非正式迭代来,框架方法是一个显著改进。框架可以通过重新使用影响资本密集软件投资,并提供更高级的应用程序编程界面,因此可以更快地开发应用程序。
当定制商务框架时或当将新功能附加到自身框架时,对于所有参加部件,在部件到框架综合代码中通常需要发生变化。在这种改变的过程中保持代码是一个冗长的、易出错误的过程。虽然可以使用流行的基于框架的解决方案,但是仍需要增加开发者的大部分工作。即使利用代码发生器生成此代码,开发者仍必须人工改变在给定框架内参加的各部件内生成的综合代码,因为不能将代码发生器定制到在框架内部能够适当实现公司要求的程度。此外,大多数框架可以防止公司集中和捕获其共同系统信息中心库数据,因为典型代码生成器很难与建模工具良好集成。
框架不仅可以用于建立任意行业的集成商务应用程序,而且可以建立如下开发过程中的集成商务应用程序用户界面、图形库、多媒体系统以及打印解决方案;诸如驱动器和网络协议的低级服务;诸如由企业JavaBeansTM部件模型和CORBA(通用对象请求代理体系结构的缩写)对象服务的通用设施服务集以及进一步加速创建应用程序的开发工具。
因为框架利用高级通用解决方案链接软件部件,所以框架和部件必须保持同步。这一般是通过人工调整框架和部件实现的。
然而,在某些特定情况下,建模工具内的信息可以用于生成部分综合代码而无需人工干预。这就是代码生成过程。通过使开发者在其设计过程中工作于更抽象的层次,代码生成系统有可能用流线方式描述应用程序开发过程。
不幸地是,典型代码生成器趋向生成必须被人工转换甚或被完全删除的不完全代码。
对于开发者来说,两项最耗时的重复工作是重复编码方法,例如写与被称为“获得”和“设置”选择器的部件的各特征有关的专用软件方法以及以框架调用的特定方法进行接近重复编码。当开发者在框架内扩展功能性时,通过对现存部件中的一个进行二次分类并通过扩展其功能性就可以实现。为了在部件到框架的综合代码中反映这些变化,开发者必须根据新功能性人工进行此变化。接近重复编码易出错误,并且其单调性会降低开发者的满意度和生产量。
建模工具、持续性工具和集成开发环境的销售商提供典型代码生成解决方案的目的在于减少重复编码和接近重复编码的冲击,但是在此过程中,它们减少了框架方法为开发者提供的灵活性。因此,开发者不能改变正在生成的方法名称;不能对特定方法修改正在生成的代码;不能根据上下文信息,对相同的方法名称生成不同的内容;不能对内部开发框架生成个性代码;如果在建模工具内不预定所有有关部件,不能通过一组部件生成方法名称;以及不能利用其对主流解决方案(例如企业JavaBeansTM部件模型)要求的相关代码生成导出部件。
为了保持框架与其共享部件集成,有几种方法生成代码。人工编码维护应用程序的最简单方法是对应用程序的重复部分和接近重复部分进行人工编码。尽管与典型代码生成器比较,这样可以对获得的软件提供更高程度的控制,但是它是一种昂贵的、易出错误的、单调技术,此技术将项目置于危险境地并引起开发者不满意。典型综合代码生成器许多建模工具均包括综合代码生成器。实质上,这些根据方法内容格式引导开发者的各预期方法框架生成少量重复或接近重复代码。不幸地是,不丢失先前插入的任意人工代码,就难于再生获得的代码,在完成应用程序全部功能的大多数情况下仍需要此人工代码。
利用这种编码工具控制代码生成过程可能围绕这些限制工作。有些建模工具销售商以底稿编制语言的形式将他们的代码生成算法公开。
调整这些底稿将进一步使开发过程复杂化,然而,由于开发小组现在必须保持这些底稿以生成有用的代码,因此,与面向对象开发环境要求对特定应用程序和建模工具的理解比较,这样做时需要更深入理解特定应用程序和建模工具。此外,通过调整底稿,可以减少销售商中的代码生成器支持职员,并且象建模销售商推出新软件版本那样,这些职员可以从事升级工作。底稿编制在有些情况下,即使不访问建模工具代码生成算法,开发者仍可以使用底稿编制语言来实际建立特定目标语言的特性源代码生成器。
此方法需要熟练的开发小组,并且增加了开发和维护的负担而不增加人工维护代码的负担,所以开发者必须现在维护生成代码的底稿。不幸地是,由于在底稿编制语言内发现目标源代码被分为段并且必须将它调整为正确顺序,所以难于使用并且难于维护和进化获得的代码。这是扩展超出这些工具的能力太多的问题。此外,改变底稿以将新语言或开发环境作为目标是一种有威胁的挑战。4GL第4代语言(4GL)让开发者完全工作在抽象层次而不是在目标编程语言中直接进行编码。4GL系统或者依赖于UML记数法,一种专用语言或者依赖于可视编程环境以对产生应用程序提供说明。不幸地是,由于生成的代码不能满足不能被优化的给定算法的要求,所以4GL开发者根据代码效率和获得的性能付出代价。
由于与现有系统集成较差并使用了生成的数值变量,所以利用4GL生成的代码势必难于维护。例如,生成的代码含有通用命名变量(labe11、labe12等)而不含有有意义的名称,例如“名称”或“客户号”。静态生成指令静态方法是从创建作为一个参数化目标源代码的静态生成指令集开始的。然后,生成器用包含在建模工具内的信息替代在静态生成指令集内发现的任意变量。这些静态生成指令集是静态的,因为它们仅访问包含在建模工具内的同类信息(例如,特定方法特性)。
静态生成指令集方法并不适合于生成部件到框架集成方法,因为它通常需要放在类、属性或作用内的信息。通常使用静态生成指令集来开发从模型中抽取相关特性,例如前置条件和后置条件,的方法框架。以此方法方式生成的方法要求开发者进行人工干预以完成该方法内容。
利用诸如在1997年10月7日授予Lindsey的第5,675,801号美国专利中说明的系统,采用静态生成指令集的生成器还可以将编程指令从编程语言翻译为另一种编程语言。
可以利用

图1所示的原理框图说明当前的生成技术。开发者使用已知的输入装置,例如键盘36、鼠标37或其它用户界面38来用文本方法或图形方法与可视建模工具或集成开发环境30进行交互并对包含在其应用领域模型内的部件进行描述。工具30自己生成模型说明31的内部表示。通过利用其相应的预定静态生成指令子集32将模型说明31直接映射到目标代码35,或者通过利用类似抽象语法树34的中间代表,大多数剖析器/生成器引擎33产生生成代码。利用此方法,在生成指令集的任意给定步骤,生成器用语法树的当前横向节点预置其生成器上下文。生成器处理与该节点有关的指令。尽管生成处理过程要求改变具有代表将执行的处理的任意未处理的节点的生成器上下文,但是生成器上下文是静态的,因为在与此节点相关的生成指令的执行期间它不发生变化。
模型说明31可以包括类列表,类列表可能按程序包名称、对各类的操作和属性的说明、类之间的关系以及与特定框架有关的可能属性特征分类。
静态生成指令32已包含在代码生成过程以对开发者提供的被表示为不同代表或抽象而未表示为目标源代码35的内容进行翻译。因为它们不能被用于支配生成什么代码而是根据它们与被翻译的模型说明31之间的关系直接包含在内,所以开发者不能为了对它们进行调整容易地访问预定模板库32。
有些应用程序开发工具,象利用称为Smalltalk的编程语言开发的应用程序开发工具,为源代码生成过程提供框架,在源代码生成过程中,通过赋值参数化目标源代码创建目标源代码35,参数化目标源代码被嵌入一次或多次Smalltalk操作中具有工具提供的并被用作应用程序开发工具的输入的代表模型说明31的子集的数值。开发者难于调整此源代码生成过程,因为他必须查找在什么对方进行改变。此外,工具销售商可能也不支持,因为开发者改变了工具的内部源代码。
基于帧的当前技术利用制造软件模型的自动装配线概念生成源代码。软件模型代表部件并且根据帧层次对它进行汇编。帧含有被以任意语言表示的数据单元和/或方法,并且利用帧参数可以将它参数化。对于首先设置其数值的帧,帧参数是本机的。帧通常预置(所有参数)为它为了使源始帧设置需要被代表目标源代码的字符串数值改变的参数的默认值。此技术使得代码生成过程难于实现,因为用户为了设计帧分层必须事先知道生成代码内的重复代码部分。
图2示出当使用现有技术系统时的必需的事件序列。在建模工具中创建模型40。生成如上解释的低可用性的代码41。大量人工代码42必须使此代码输出41有用。例如,可以改变操作名称以清楚表示它们是什么。如果对这些人工代码42进行调整,则最终代码43在系统内备用。
本发明概述因此,本发明的目的是提供一种用于自动重复开发者进行有关部件开发和为了获得要求的功能需要开发者干预最少的源代码生成过程的工作的系统。
本发明的另一个目的是提供一种涉及部件开发过程的源代码生成器,与利用上述生成器生成的源代码文件比较,此源代码生成器生成更完全、更精确满足要求的功能的源代码文件。
另一个目的是通过重新生成操作减少代码维护工作。此外,通过实现更大百分比数的生成代码,可以减少需要维护的代码数量,因为生成的代码永远不需要人工转换。再者,在生成指令集内需要改变的实际数目有明显减少。
本发明的另一个目的是使它可以与所有主要可视建模工具或主要集成开发环境集成以避免在多个工具中捕获相同信息。
本发明的另一个目的是提供一种用户界面工具,它使得开发者可以用文本的方法和图形的方法定义通过使用生成指令集需要生成什么,并且如果对工具指定目标编程语言,它还使得开发者定制源代码生成器选择。如果开发者将生成指令集和生成器选择存储到文件,则可以以成批方式从建模工具或集成环境调用与部件开发过程有关的源代码生成器工具,而无需与开发者进行任何交互。
本发明的又一个目的是提供一种源代码生成器工具,它为任意面向对象的编程语言或支持部件的任意编程语言生成代码。
此外,本发明的另一个目的是提供一种创建在各生成指令集中出现的目标源代码的界面,该界面只需要最少的开发者干预就可以获得要求的生成指令集。
此外,本发明的另一个目的是提供在代码块与其生成指令集之间的可跟踪性。
本发明又一个目的是提供一种生成指令编辑器,它能够满足编辑生成指令集内的源代码的需要,并可以用于诸如基于万维网的服务器、框架环境、代码生成工具等的所有开发环境。
通过对几种特性建立基准,生成指令集可以将高级模型中的概念部件链接到其相应的编码工具和其与给定框架的集成。
生成指令集代表利用上下文变量参数化的目标源代码。各上下文变量指出参考节点(例如类和属性)和标识符(例如超类名称、名称或类型)。超类名称标识符仅可以在参考节点为类时使用,类标识符仅可以在参考节点为属性时使用。此外,根据参考节点是类还是属性,名称标识符可以给出不同的结果。换句话说,由于代码生成器的上下文是动态的,所以,作为参考节点可以改变。
如果生成器上下文含有类属性,则生成指令集仍可以参考其类;根据参考节点被看作类还是属性,称为“名称”的标识符可以返回类名称或属性名称。
因为在生成过程中它们影响模型内的信息,所以动态的、上下文敏感的代码生成技术生成更大量、更可用的代码。如果开发者希望在维护期间变更代码,则他或她可用简单改变生成指令集或建模工具的类图中捕获的信息。
根据本发明的一个方面,该方法将建模信息翻译成上下文数据并将它合并到用户确定的生成指令集。这些生成指令集通过如下描述控制生成过程●生成代码的部件●将生成的代码类型(方法特征和内容,或导出部件,例如界面和类)●利用生成时间指令还原的参数化目标源代码利用此方法,开发者还可用定义一组外部特性,用于将附加的信息类型赋值为模型内的属性和类。外部特性提供待保持到代码内的对特殊情况专用的详细执行信息并允许各种信息与模型集成。生成指令集使用对特定模型定义的外部特性以创建可用扩展项目原模型功能性的代码。利用组将外部特性名称指定到如类子集、属性子集或作用子集的节点,并且其数值对于出现的各指定节点是唯一的。
根据本发明的第一方面,提供了一种在基于部件的语言中生成计算机源代码方法,该方法包括步骤创建至少一个代表至少一个滤波变量和利用至少两个上下文变量参数化的目标源代码的生成指令集;定义上下文变量;以及生成多个代码段。生成指令集涉及一组外部特性及其相关名称。代码段可用定义多个部件。此方法可用进一步包括生成指向被使用的生成指令集的指针数据的步骤。
还提供了生成计算机源代码的另一种方法,在该方法中,说明模型说明,提供一组生成指令集,可以创建、排序或定制生成指令集,并生成计算机源代码。此外,可以生成指针数据以识别在生成过程中使用哪个模板和哪部分给定模型。模型说明可以独立于语言并且在不同于在生成指令集内出现的用于编写参数化源代码段的语言的基于部件的语言中可以使用生成指令集生成计算机源代码。
提供的另一种方法包括步骤利用指针数据检索计算机源代码;查找改变的代码部分;利用指针数据,定位并改变生成指令集、上下文信息或模型说明。并且该方法重新生成计算机源代码。
如果为了减少从生成器引擎咨询,生成器引擎利用其说明的信息将它作为其生成器上下文(系统信息中心库)进行处理,可视建模工具或集成开发环境以可以被生成器引擎剖析并可以以如数据块或抽象语法树的中间码形式存储的格式提供一组具有相关属性和辅助工具细节的部件描述,则在这里广泛描述的本发明意图说明本发明如何实现上述目的。所提供的系统用于剖析各生成指令集以确定需要生成代码的目标部件和待处理的代码生成过程的类型。当所有生成指令集被处理时完成代码生成。
在代码生成器中,利用建模工具,例如可视建模工具,或集成软件开发环境等,根据开发者的输入大量创建的说明数据生成目标源代码。根据本发明的主要方面,说明数据可以包括元数据和生成指令集数据。对于先前利用一个生成器选择规定的特定目标编程语言,生成指令集提供对生成何种类源代码进行描述的完整说明,例如类说明、类定义、程序包定义、操作说明或操作定义。生成指令集数据包括参数化形式的代码说明,正例如在对相同对象或部件的不同生成操作中,或在对不同对象或部件的相同生成操作中或在其它生成指令集数据中的多个实例中允许重新使用一个或多个参数化目标源代码块。为了包括对象上下文数据或部件上下文数据基准,生成指令集数据含有使用滤波变量和上下文变量的参数化代码命令。在代码生成的处理过程中,对说明数据进行剖析和编译以创建系统信息中心库数据。最终目标代码是从系统信息中心库数据中“抽取”的以按目标编程语言要求的正确逻辑结构生成目标代码。因此,可以利用最少的生成指令集数据与元数据一起生成目标代码,这样通过在生成指令集数据中使用参数化,使代码的重新利用率最高。
优先地,所谓说明数据包括模型说明数据(即元数据)和利用适当的开发者界面工具分别创建的生成指令集。模型说明数据包括涉及与各对象或部件有关的上下文的部件编程语言相关信息。生成指令集数据包括响应与各对象或部件有关的当前上下文的参数化代码命令,当前上下文信息存在于系统信息中心库数据中。系统信息中心库数据最初是通过对上述模型说明进行剖析获得的,并且根据由现存对象或部件导出的新生成对象或部件,并根据涉及现存或新创建的对象或部件的新生成操作,系统信息中心库数据不断增长。根据语言要求的参数数据和系统信息中心库数据,在特定编程语言中,抽取字生成面向对象(或部件)的源代码,由在输入模型说明数据和生成指令集数据时接收的生成器引擎建立系统信息中心库数据。生成指令集数据包括源代码命令,源代码命令规定重复语句和/或递归语句并且可以包括依赖于上下文数据的参数化代码。通过提供上下文数据,并通过提供具有变量或响应上下文数据的参数化代码命令的生成指令集数据,在更多的对象或部件中,可以将生成指令集应用于规定源代码。
可以理解生成指令集数据可以规定最初不希望在模型说明数据中规定的部件的创建过程(还有操作或属性)。这可以通过在生成指令集数据内规定与在模型说明数据内出现的部件有关的部件的生成过程来实现。这允许某些生成指令集用于响应特定编程框架要求。
还提供了一种用于以基于部件语言形式生成计算机源代码的装置,该装置包括模板编辑器,用于创建或定制生成指令集;模板管理器,用于选择并排序生成指令集然后设置生成参数;源代码生成器以及源代码输出。该装置可以进一步包括指针数据生成器和用于选择以哪种语言形式生成代码段的语言数据库。
提供另一种装置用于调整生成的计算机源代码,该装置包括用于检索源代码的源代码编辑器、模板管理器、源代码生成器和源代码输出。
为了说明本发明,以下定义了如下术语。
术语“生成指令集”用来表示当其生成指令至少代表一个滤波变量和利用至少一个上下文变量参数化的目标源代码时,源代码生成器使用的模板。
术语“上下文变量”用来表示指出参考节点和标识符的变量。
术语“滤波变量”用来指规定待生成代码的选择部件的变量。
术语“面向对象的编程”用来指一种编程语言,在这种编程语言中,开发者不仅定义数据结构的数据类型,而且定义可以应用于数据结构的操作类型。此外,开发者还可以建立一个对象与另一个对象之间的关系。
术语“部件”用来指具有对象的封装特性和抽象特性的实体。此外,它们还是对其结构、功能性和交互标准进行定义的部分技术框架。
术语“模型说明”用来指,通过显示系统中的部件、部件之间的关系以及表征部件的各类的属性和操作捕获系统的静态结构的代表。
术语“联编”用来指标识符或变量与保持在定义范围内的该标识符或变量的数值之间的关联。
术语“模板”与术语“生成指令集”在本发明说明书通篇中是同义词。
附图的简要说明通过以下说明和附图,本发明的这些以及其它特征、方面和优势将变得更容易理解。其中图1示出说明现有技术的方框图;图2示出说明现有技术的流程图;图3示出关于其开发环境根据本发明的总体方框图;图4示出根据本发明的总体方框图;图5a示出总体说明源代码生成过程的第一流程图;
图5b示出总体说明源代码生成过程的第二流程图;图5c示出常量生成过程流程图;图5d示出变量生成过程流程图;图5e示出多个codeString解析流程图;图5f示出codeString解析流程图;图5g示出参数化codeString解析流程图;图5h示出重复参数化codeString解析流程图;图6示出利用生成指令集和参数的源代码生成过程的流程图;图7示出利用模型说明和生成指令集的源代码生成过程的流程图;图8示出通过调整生成指令集或模型对源代码进行修改的流程图;图9示出源代码生成器的方框图;图10示出修改工具的方框图;图11示出联编应用程序的模型说明;图12示出对VapAccount生成的EJB类;图13示出可以用于实现优选实施例、属于巴纳范式的、模型说明的特定语法;图14示出可以用于实现优选实施例、属于巴纳范式的、生成指令集的特定语法;优选实施例的详细说明在本章中,词部件和类为同义词,因为在所讨论的所有工具语言(JAVATM、C++和Smalltalk)中,部件均具有相同的意义,即部件即类。
在已知的任何一种计算机环境下均可以实现本发明并且可以在图3所示的系统中实施本发明并生成基于部件的源代码,例如C++、JAVATM或Smalltalk。图5至图8示出说明根据本发明优选实施例方法的流程图。
图4示出该方法的全部步骤的流程图。在建模工具50内创建模型65。根据优选实施例,将生成指令66送到代码生成器。获得代码输出67。裁剪并完备此代码输出67。在开发者使用最终代码68之前,不需要对最终代码68进行修改和完备。
开发者使用已知的输入装置,例如键盘53、鼠标54或其它用户接口55,采用文本方法或图形方法与建模工具或集成开发环境50交互并对包含在特定领域模型(图5a所示的步骤75)及其类图内的部件进行描述。类图的两个实例示于图11和图12。
图5所示各图示出根据本发明的优选实施例的特定实施过程。它们示出对模型说明和生成指令集进行的处理过程。图13和图14为代表对应于图5所示的流程图的模型说明和生成指令集的语法的巴纳范式(Backus-Naur)图。所给出的语法仅作为根据本发明的优选实施例的特定实例。显然,本技术领域的其它技术人员可以对它进行多种调整。因此,对流程图和巴纳范式图的描述对本发明仅具有说明而不具有限制意义。
正如图5a的步骤76所示那样,通过在模型内对收集与当前模型有关的所有执行细节的外部特性名称组进行定义,开发者可以扩展典型建模工具内的信息范围。
如步骤77所示,通过使用存在于生成指令集内的codeString,开发者查阅目标语言。例如,利用目标工具语言的有效指令子集,用一个在前、一个在后的两个惊叹号符号“!”对codeString进行包围,来直接表示codeString。
尽管在优选实施例中,codeString可以描述成人可阅读的语法,但是这种符号的使用可以变换成任何符号或字符,甚至图形实现形式,以利用系统的应用程序。
存在两种codeString常量codeString和参数化codeString。生成器引擎52难于分别对它们进行解析。在第一种情况下,如果常量codeString被生成指令引擎47剖析,则生成器引擎52就不需要对常量codeString进行控制。通过删除第一个和最后一个惊叹号符号并返回codeString,就可以利用生成器引擎52解析常量codeString。换句话说,当开发者对它进行编码时,生成器引擎52返回源代码。在第二种情况下,参数化codeString为生成器引擎52需要用提供的数值对字符串具体值%n进行赋值,其中n为1与9之间的整数。然而,在根据本发明优选实施例中,为了方便起见,将codeString设计成具有具体值%n,其中n为1与9之间的整数,开发者可以选择累计其它数字的具体值和具有相同结果的字符。例如,整数n可以在1与99或1a至9z之间。
属于生成器引擎52一部分的递归联编程序48对具体值进行赋值。如果只为codeString设置一个数值,则生成器引擎52将用设置的数值替代所有%1的具体值,或者如果codeString具有字符串%n的任意具体值,其中n为2与9之间的整数,则生成器引擎52将出现错误并停止代码生成。如果对codeString设置了两个数值,则生成器引擎52将用第一设置数值替代所有%1具体值而用第二设置数值替代%2具体值,或者如果codeString具有字符串%n的任意具体值,其中n为3与9之间的整数,则生成器将产生错误并停止代码生成。因此,如果设置数值列表,生成器引擎52将用设置列表内的第n个数值替代所有%n具体值。n的值必须在1至9的范围内。如果参数化codeString的任意部分含有一些%k,其中k为大于设置列表的大小但小于10的整数,则生成器引擎52产生错误。此外,开发者可以对%k选择设置不同数值集。最后,生成器引擎52返回通过用设置数值替代在参数化codeString内存在的所有%n字符串生成的源代码。与常量codeSring相同,解析参数化codeString必须含有在语法上有效的目标工具语言结构子集,并且开发者必须用其设置数值写参数化codeString。模型说明51绝对含有常量codeString,但是生成指令集56可以含有两种codeString。
解析codeString与目标代码之间不需要翻译。换句话说,开发者对对于codeString内要求的目标语言写有效语法语句具有响应能力。它提供了利用开发者的编码方式发送有效代码的优势。
因此,生成器引擎52包括模型说明引擎46、生成指令引擎47以及递归联编程序48。生成指令引擎47从抽象语法树58检索其上下文。递归联编程序48利用抽象语法树用递归方法解析codeString。模型说明引擎46分析模型说明51并对抽象语法树58的创建过程提供信息。
利用工具49,通过对下列信息的部分内容或全部内容进行规定,开发者完成与开发领域和工具编程语言有关的实现细节(步骤76)。
对于各程序包,可以定义下列内容注释给出其描述;其名称;如果当前程序包包含在另一个程序包内,其包含的程序包名称;以及在当前程序包内定义的各类的描述列表。
对于各类或界面,所说明的注释给出其描述、其界面类型值(例如专用、公用、受保护或程序包)、其名称、用于说明类是具体的还是抽象的的数值、其超类名称、超类定义的程序包名称、当前类定义的各属性的描述列表、与当前模型有关的各外部特性的描述列表、以及当前类定义的各操作的描述列表。
对于各属性,注释给出其描述、其界面类型值(例如专用或公用)、受保护或程序包、其用于说明它是实例还是类属性的类型、其名称、其实现类名称、定义实现类的程序包名称、通过使用常量codeString并与如C++的编程语言的其实现类相关的其先决条件类型定义数值、当它像是采集时它自己包含的单元的属性类名称、通过使用常量codeString实现的其默认值、与当前属性有关的各外部特性的描述列表。
对于各关联,注释给出其描述、其名称、其原作用名称、其目标作用名称、前置、后置、作用界面类型、说明作用是否是瞬时的、易失的或最终的的数值。
对于各外部特性,可以规定其名称和通过使用常量codeString实现的定义列表。
对于各操作,其界面类型数值(例如专用、公用、受保护或程序包)、说明它是类或实例操作的数值、其名称、其范畴名称(用于如Smalltalk的编程语言)、通过使用常量codeString利用在codeString内使用的定位类列表实现的其说明代码(用于如C++的编程语言标题文件)、通过使用常量codeString利用在codeString内使用的定位类列表实现的其定义代码。
当处理框架时,开发者需要将实现细节压缩为codeString的定义并将它们并入外部特性。实现所有满足给定框架需要的定义不止需要一个外部特性名称,并且一个外部特性可以用于实现多个框架。在大多数情况下,特性数值绝对含有常量codeString的数字数值或字母数字数值。
然后,通过使用工具50,开发者获得模型说明51。模型说明或者是一种独立语言或者适于与基于部件语言(例如C++、JAVATM或Smalltalk)一起使用。如果选择第一选择,为了使用通用模型说明51,必须写入生成指令集56。如果使用第二选择,则模型说明在三个方面不同实现细节、codeString以及范畴名称和类型定义。程序包名称、类名称、属性名称以及选择名称均为实现细节,实现细节因为命名约定例如在C++中与在Smalltalk中不同而不同。因为不同的语言支持的编程语言语法不同,所以codeString不同。仅当需要时,才使用如(在Smalltalk内使用的)范畴名称信息和定位分类(在C++和JAVATM中用于分别产生包含语句和输入语句)。
对于余下的工作,开发者使用代码生成器用户界面49。一旦开发者调用代码生成器用户界面49,他就装载含有模型说明的文件,然后如果已经完成装载模型说明的文件,他再装载含有生成指令集56的文件。在优选实施例情况下,开发者创建要求数目的生成指令集56以满足他自己的需要(步骤77)。可以创建、调整、定制或排序生成指令集以准备适于生成的生成指令集的集合。
利用代码生成器用户界面49,开发者可以选择目标生成代码的编程语言,当定义存在于模型和生成指令集内的所有codeString时,编程语言可以与开发者使用的编程语言相同,如果需要翻译生成指令集,则编程语言也可以不同。然后,通过使用代码生成器用户界面49,开发者检查影响生成代码的生成选择57(步骤78)从而使下列设置生效属性、类、外部特性、操作和程序包名称的第一个字符可以是小写、大写或两者均有;可以存在于属性、类、外部特性、操作名称或程序包名称内的专用字符列表;当在模型说明中未明确说明时,用于与类、属性或操作有关的界面的默认值;与类、属性或操作有关的有效界面类型数值;有效外部标识符列表;布尔数值,当在模型说明内存在新的外部标识符时,用于说明生成器是否应该附加外部标识符列表。
开发者还检查抽象选择57。这里实例说明对三个基于部件语言的设置。作为生成器的一部分前端工具49的子菜单“选择”,当使用C++作为生成器时,对于生成代码的抽取过程,开发者改变的下列选择
“说明代码目录”用于规定驱动器和根目录名称。利用默认,数值为d:\include。
“定义代码目录”用于规定驱动器和根目录名称。利用默认,数值为d:\source。
“说明代码的文件扩展”用于规定映射到属于当前程序包的类的各文件名称的文件扩展。利用默认,数值为hpp。
“定义的文件扩展”用于规定映射到属于当前程序包的类的各文件名称的文件扩展。利用默认,数值为cpp。
利用默认将“每个文件一个类”设置为真但是可以改变它。
作为前端工具49的生成器选择子菜单的一部分,当使用JAVATM作为生成器时,对生成代码的抽取过程,开发者可以改变下列选择“根目录”用于规定驱动器和根目录名称。利用默认,数值为d:\。
“目录映射程序包名称”用于对在将它设置为真时的两个时长之间存在的各subString创建子目录。默认为真。
“类扩展”用于规定映射到属于当前程序包的类的各文件名称的文件扩展。利用默认,数值为JAVATM。
利用默认将“每个文件一个类”设置为真,但是可以改变它。
作为前端工具49的生成器选择子菜单的一部分,当使用Smalltalk作为生成器时,对生成代码的抽取过程,开发者可以改变下列选择
“定义代码目录”用于规定驱动器和根目录名称。利用默认,数值为d:\。
“定义的文件扩展”用于规定映射到属于当前程序包的类的各文件名称的文件扩展。利用默认,数值为app。
利用默认将“每个文件一个类”设置为假,但是可以改变它。
在步骤79,利用前端工具49,开发者调用生成器引擎52。引擎52通过剖析第一模型说明51(步骤80)开始并创建其系统信息中心库数据(步骤81),将系统信息中心库数据存储到抽象语法树58。换句话说,利用模型剖析器剖析的信息,生成器引擎52在抽象语法树58内对存在于模型说明51内的各程序包、类、属性、外部特性、关联、作用和操作以及上述描述的各程序包、类、属性、外部特性、关联、作用和操作之间的所有关系创建节点(步骤81)。
代表程序包、类、属性或操作的各节点具有被称为definitionText的属性,该属性含有与其有关的生成定义源代码。此外,类、属性和操作节点具有被称为delarationText的属性,该属性含有与其有关的用于如C++编程语言的生成说明源代码。
在步骤81,存在与模型说明51内的任何说明的操作或属性变成与其说明类节点有关的操作或属性节点。在进行此步骤期间,通过从它们各自的常量codeString抽取它,生成器引擎52用设置的定义源代码和说明源代码预置属性definitionText和delarationText。
在确定之前,如果存在另一个待被生成器引擎52处理(步骤82)的模型说明并且在对它进行剖析前(步骤83),则引擎52停止对存在的第一错误进行剖析并调用前端工具49利用有关错误记号在模型说明内用上下文方法显示错误。当引擎52对当前模型说明确认生成器和抽取字选择57时或当它在对相同类两次定义的相同程序包或相同属性名称内发现相同类名称时,会产生错误(主要因为从超类继承相同的属性名称)。
在步骤85,生成器引擎52剖析第一生成指令集56以确定需要生成代码(步骤86)的目标类或程序包以及待处理的代码生成类型(步骤89)。
目标类(步骤86)是存在于抽象语法树58上的说明类的子集或者它们由子集导出。为了在生成指令集56的接收机说明部分规定说明类子集,开发者规定选择与类本身或其属性、其节点或其外部特性有关的判据。例如,通过规定关键字&classes,开发者可以选择所有类;通过规定关键字abstract之后的关键字&classes,开发者可以选择所有抽象类;通过规定关键字concrete之后的关键字&classes,开发者可以选择所有具体类;通过规定给定类名称之后的关键字&classessubclassOf,开发者可以选择属于给定类的子类的所有类;或者通过规定给定类名称之后的关键字&classes having attribute of type,开发者可以选择具有给定类型属性的所有类。
为了在步骤88对导出类进行检索,一创建导出类就将99附加到抽象语法树58。
因为当抽取与其一个包含的类相关的生成代码时,直接使用与程序包有关的生成代码,所以通过规定关键字&packages,目标程序包(步骤86)总是指所有程序包(详细情况请参考步骤97)。
在步骤87,处理第一目标节点并且在步骤88根据目标节点是绝对分别含有类还是绝对分别含有程序包,该目标节点变成当前类上下文或当前程序包上下文。仅当当前生成指令集56产生程序包定义节点时,目标节点代表程序包,并且所使用的剖析关键字为将在以下说明的packageDefinition。
在步骤89,生成器引擎52区分代码类型以根据下列由生成指令集56产生的剖析关键字产生。
operation关键字对生成器引擎52指出生成器引擎52必须处理生成代码作为对当前类上下文的一步或多步操作。生成器引擎52将与选择declaredAs关键字有关的生成代码附加到新创建操作节点的declarationText属性。引擎52将与选择definedAs关键字有关的生成代码附加到相同的新创建操作节点的definitionText属性。生成器引擎52将新创建的操作节点附加到当前类上下文。
classDeclaration关键字使得产生器引擎52将生成代码作为当前类上下文的类说明进行处理。这可以用于包装位于标题文件内的代码的如C++的编程语言。引擎52将生成代码附加到与当前类上下文关联的declarationText属性(步骤92)。
classDefinition关键字指示生成器引擎52将生成代码作为当前类上下文的类定义进行处理。任何一种编程语言均可以使用此将属性和属于此类的操作定义组合(如在C++和JAVATM内)。有些编程语言使用classDefinition仅将其属性名称与其关联类组合(如在Smalltalk)。生成器引擎52将生成代码附加到与当前类上下文关联的definitionText属性(步骤92)。
packageDefinition关键字指示生成器引擎52将生成代码作为当前程序包上下文的程序包定义进行处理。如C++的编程语言不使用程序包定义,因为,代码被抽取到对每个文件仅使用一类的文件。如JAVATM或Smalltalk的编程语言使用它。生成器引擎52将生成代码附加到与当前程序包上下文相关的definitionText属性(步骤92)。
开发者必须以下列顺序写他的生成指令集56。首先,可以规定使用关键字classDeclaration或classDefinition的生成指令集为任意顺序,但是它们必须优先于具有关键字operation或packageDefinition的生成指令集。然后,使用关键字packageDefinition的生成指令集必须优先于使用关键字operation的生成指令集。最后,包含使用关键字operation的生成指令集。
如果上述关键字出现错误,则生成器引擎52产生错误。
在步骤98,生成器校验待生成的代码是否创建新部件。如果创建新部件,则创建新节点99。可以创建三种类型的节点导出类的新节点、导出界面的新节点以及导出属性的新节点。对于这些新节点,可以包含注释说明,还可以包括界面类型、具体数值或抽象数值和最终值。对于导出类和导出界面,可以定义类定位子句、超类定位子句、界面子句。对于导出属性,可以包含瞬时数值、易失数值、属性类型、属性内容子句以及属性类名称。
如果待生成的代码不创建新节点,则在步骤90对待生成的代码类型进行校验。根据剖析关键字,生成器引擎52区分不同类型的生成指令集。
如果在步骤91,生成器引擎52确定,对于每个类它是否根据缺少的操作名称变量必须创建一个且仅创建一个操作。操作名称变量与类名称变量相同,因为用设置的数值替代操作名称变量内的字符串%1的任何具体值。我们将分别根据图5c和图5d更详细说明单个变量创建过程。
在步骤92,生成器引擎52存储在当前上下文节点的高速缓存内的生成源代码。当利用图5e描述变量操作的解析时,将更详细说明在高速缓存内用于生成源代码的过程。如果当前生成指令集具有packageDefinition关键字,则当前上下文加宽为程序包节点。如果当前生成指令集具有classDefinition或classDeclaration关键字,则当前上下文节点为类节点。
在步骤93,生成器引擎52确定是否存在另一个待利用当前生成指令集处理的目标节点并在步骤95对它进行处理。
在步骤94,生成器引擎52确定是否存在另一个待处理的生成指令集并在步骤96对它进行处理。
在发现第一错误时,引擎52停止代码生成并调用前端工具49利用有关错误记号在生成指令集内用上下文方法显示错误。当引擎52对当前生成指令集或对一个设置的数值确认生成器和抽取字选择57时,会产生错误并且该结果无效。
如果生成器引擎52成功完成代码生成,则为了检索由抽象语法树58定义的节点生成的源代码60,前端工具49调用源代码抽取字59。各源代码抽取字59用自己的方法将代码输出到文件,并且在开始进行抽取处理之前,它读取生成器和抽取字选择57(步骤97)。
现在利用C++、JAVATM和SmallTalk内的三个实例来说明由生成器完成的步骤。
为了抽取生成代码,C++源代码抽取字59执行下列步骤。首先,根据在生成器和抽取字选择57内规定的数值,它创建包含子目录。该目录将含有标题文件(文件名称以扩展名hpp结束)。第二,根据对生成器和抽取字选择60规定的数值,它创建源子目录。该目录将含有定义文件(文件名称以扩展名cpp结束)。然后,对于存在于抽象语法树58的各类节点,只有当其declarationText属性不是空时,它才在包含目录内创建称为<className>.hpp的文件并将其内容写入该文件。只有当其definitionText属性不是空时,它才在源目录内创建称为<className>.cpp的文件并将其内容写入该文件。
JAVATM源代码抽取字59抽取各类的属性definitionText的非空内容并将它放入与类具有相同名称并具有文件扩展名.java的文件。首先,它创建根据在生成器和抽取字选择57内规定的数值定义类的子目录。其次,它抽取其程序包名称的属性definitionText的内容并将它写入该文件。然后,它抽取类的属性definationText的内容并将它放入文件。
重要的是,我们知道通过读取具有称为file out格式的特定格式的文本文件,任何Smalltalk环境均支持类定义和操作定义,并且当抽取源代码时Smalltalk抽取字使用它。
Smalltalk源代码抽取字59进行如下步骤。首先,根据在生成器和抽取字选择57内规定的数值,它创建file out目录。其次,根据生成器和抽取字选择57内规定的数值,它对每个程序包创建一个文件或创建一个总文件。然后,对于各类,如果它与先前处理的类不同,抽取字写其程序包的属性definitionText的内容,写存在于类属性declarationText内的类说明,将第二时间迭代到各类以写入各操作组的内容,最后,Smalltalk抽取字将写入惊叹号“!”以定界Smalltalk代码和一些标题从而规定是否将操作定义为类或实例和公用或专用。
参考图5c,现在将说明常量的创建过程。当开发者要对每个目标类生成一个操作时,开发者需要写入下列信息。必须规定的内容是利用如下关键字数值public、private、protected或package的界面类型数值;利用关键字数值&instance或&class之一的操作类型数值;操作名称;用于如Smalltalk的编程语言并由开发者利用declareAs关键字规定然后通过仅使用一个具有在codeString内用于定位类的选择列表的codeString实现的选择范畴名称;以及开发者利用definedAs关键字规定的、并通过利用一个或多个具有有关各codeString的定位类的列表的codeString实现的选择说明子句。
生成器引擎52得到剖析信息(步骤100)并创建新操作节点(步骤101),在步骤108,将该新操作节点附加到当前类上下文。如果说明子句和定义子句被删除,则生成器引擎52不发出错误。然而,如果不需要无用的生成指令集56,则必须设置说明子句和定义子句之一。在大多数情况下,仅对如C++的编程语言设置说明子句,而始终设置定义子句。从维护的观点出发,可以决定反映在说明节点进行的改变而对于特定场景,只有所设置的说明子句有意义,而无需设置定义子句。
在步骤102,如果设置说明子句,那么生成器引擎52解析设置的codeString,正如在对图5f所示的codeString解析进行解释所说明的那样,引擎52获得生成源代码并将它存储到新创建操作的declarationText属性(步骤104)。
在步骤105,如果设置定义子句,那么生成器引擎52解析所设置的codeString,正如在对图5e所示的多个codeString解析进行解释所说明的那样,引擎52获得生成源代码并将它存储到新创建操作的definitionText属性(步骤107)。
对于操作创建过程处理的各生成指令集56,根据剖析结果,系统对各目标类创建一项操作,或对各目标类的各限定属性创建一项操作。
生成器引擎52得到下列剖析信息(步骤111)界面类型数值,利用下列关键字数值之一public、private、protected或package进行操作;操作类型数值,利用下列关键字数值之一&instance或&class;操作名称变量,其后是关键字repeatForEach,接着是其相关属性滤波变量,接着是关键字using,接着是属性上下文变量(在步骤116说明);选择范畴名称,用于如C++编程语言、由开发者利用declaredAs关键字进行规定的,并通过使用仅一个具有在codeString内使用的定位类选择列表的codeString实现;以及选择定义子句,由开发者利用definedAs关键字规定的并通过使用一个或多个具有涉及各codeString的定位类的选择列表的codeString。
利用当前类上下文节点和作为选择判据的设置属性滤波变量,生成器引擎52获得属性子集(步骤112)。对于具有与被称为defaultValue、having typedef的选择特性有关的定义数值的属性,对于具有与其后为设置的类名称的、被称为typedef、of type的选择特性有关的定义数值的属性,将下列关键字进行组合构成属性滤波变量关键字&attribute,其后是根据当前属性界面类型数值的选择判据关键字,例如数值all、private、protected或package,接着是根据属性类型的当前数值的选择判据关键字,例如数值instance、class或classAndlnstance,接着是利用下列关键字之一的选择判据havinfdefaultValue。
由生成器引擎52实现的获得属性子集包括0个或多个满足设置的选择判据的属性。
生成器引擎52检测属性子集是否空(步骤113),并且如果为空,则不对当前类上下文创建操作。如果不空,则它处理第一属性节点(步骤114)并将它作为当前节点上下文进行处理(步骤115)。
在步骤116,通过用与设置属性上下文变量和当前节点上下文有关的特性数值替代操作名称变量内的字符串%1的所有具体值,生成器引擎52获得操作名称。属性上下文变量被其后具有下列描述其标识符之一的关键字属性之一的关键字&attribue表示name为代表属性名称的字符串;interfaceType为字符串public、private、protected或package;attributeClassName或className为同义词并且它们为代表属性类型名称的字符串;commentDescription为代表属性描述的字符串;defaultValue为代表用于实现属性默认值的解析codeString的字符串;nameAsClassName与第一字母为超类的name相同;typedef为代表用于实现先决条件typedef结构的解析codeString的字符串;defaultValueOrSpace除了如果它代表空格如果不存在对属性定义的defaultValue之外与defaultValue相同;attributeContentsClassName为代表当选择属性时包含在属性内的单元的className的字符串;typeAsStaticOrSpace为当属性为类属性时代表数值static的字符串并且当它为实例属性时代表数值space的字符串;declaredClassName为代表属性所属的类名称的字符串。
通过抽取当前属性节点上下文的表示符的值,得到属性上下文变量的值。
显然,所示的所有保留字仅作为实例。只要不改变本发明优选实施例的实质内容还可以使用其它保留字。
生成器引擎52将先前的节点上下文用作当前节点上下文(步骤117)。当前节点上下文为在图5b实现的当前类上下文。
为了清楚起见,步骤118至步骤125分别与步骤101值步骤108相同,因为如果生成器引擎52对操作名称变量进行处理(步骤116),则它等于出现常量产生过程。
在步骤125,生成器引擎52检测是否存在属性子集的另一个属性节点。如果存在另一个属性节点,则它对另一个属性节点进行处理(步骤126)。如果不存在另一个属性节点,则它返回它在图5b中的位置。
生成器引擎52以图5e所示的方式生成与程序包、类或操作节点的defintionText属性有关的源代码。
在步骤130,生成器引擎52从当前剖析生成指令集规定的codeString列表获得第一个codeString。然后,正如在图5f所示的那样,与单个codeSttrng解析相同,它对此codeString进行处理。
它将解析的codeString附加到高速缓存(步骤131)并检测在列表内是否存在另一个待处理的codeString(步骤132)。如果存在另一个codeString,则生成器引擎52获得它并将它作为单个codeString解析进行处理。如果不存在codeString,则它从高速缓存返回生成源代码。
图5f至图5h示出codeString解析的流程图。
在图5f中,生成器引擎52通过查看codeString目录检测当前codeString是否已经被解析以检验是否存在具有指定到其它的设置codeString名称项(步骤135)。当开发者对codeString进行定义时,开发者可以对使用其后跟着名称的关键字&blockOfCode的codeString设置名称。如果对它进行解析,则生成器从codeString目录获得其数值(步骤136)。如果不对它进行解析,则它通过检测上下文变量缺席确定codeString是否是常量codeString(步骤137)。
为了分别从类变量名称和操作变量名称获得导出类名称或导出操作名称,所以包括类上下文变量和属性上下文变量。利用参数化的codeString,可以以相同的方式应用它们。
以下列出所存在的全部五种上下文变量类上下文变量、属性上下文变量、操作上下文变量、程序包上下文变量、codeString上下文变量。
用其后是下列描述其标识符之一的关键字的&operation关键字来表示操作上下文变量definitionText为代表与操作有关的definitionText属性内容的字符串;declarationText为代表与操作有关的declarationText属性内容的字符串。
用其后为用于描述其标识符之一的下列关键字之一&package关键字来表示程序包上下文变量name是代表程序包名称的字符串,parentName是代表其父程序包名称的字符串,commentDescription为代表程序包描述的字符串。
codeString上下文变量是另一种codeString,为了用作与当前codeString联编的设定值,需要对它解析。
在步骤138,生成器引擎52检测是否对上下文变量设置with。如果设置with,则参数化codeString的解析是必须的,如图5g所示。如果不设置with,则意味着,对上下文变量设置关键字repeatForEach并且它将详细包括图5h所示的重复参数化codeString解析。
如果解析codeString,生成器引擎52确定当前codeString是否具有设置名称(步骤139)。如果存在设置名称,则利用作为密钥的设置codeString名称和作为数值的解析codeString,生成器引擎52附加codeString目录内的项目(步骤140)。
在步骤141,生成器引擎52检测是否存在为当前codeString设置的定位类。如果存在(步骤142),则它将定位类附加到当前节点上下文。在步骤143,它检测当前节点上下文是否是类节点。如果是类节点,则它将定位类递归附加到其父节点,直到父节点成为类节点(步骤144)。
我们现在将说明的问题是图5g所示的参数化codeString的解析过程。生成器引擎52获得用逗号与其它变量隔开的第一上下文变量(步骤150)。它检测当前上下文变量是否是另一个codeString(步骤151)。如果是,它就利用图5f所示的方法对它进行解析并将解析codeString作为设置数值进行处理(步骤152)。如果上下文变量是另一个codeString,则它通过从当前节点上下文抽取其标识符数值获得上下文变量的设置数值(步骤153)。生成器引擎52用其上述设置数值给字符串%n的具体值赋值,其中n为1和9之间的整数(步骤154至步骤156)。当存在多个上下文变量时,则用分号将它们分开。
在图5h中,对当前节点上下文对于规定滤波变量产生多少结果节点,自身就重复多少次的codeString的解析处理过程进行了说明。唯一条件是在对当前节点上下文滤波变量不返回空集时,当所需要的即插入codeString时,这种codeString有用。
在步骤160,生成器引擎52可以对下列滤波变量进行剖析属性滤波变量、外部特性滤波变量、操作滤波变量、超类滤波变量、定位类滤波变量。
外部特性滤波变量由下列其后是概念名称的关键字组合构成operation of&dependentConcept。
操作滤波变量由下列关键字组合构成关键字&operation,根据操作界面类型的当前数值,例如数值all、private、public、protected、package之后为选择判据关键字的,以及根据操作类型的当前数值,例如数值instance、class或classAndInstance,之后为选择判据关键字。
超类滤波变量由符号&superclass构成。
定位类滤波变量由下列关键字组合构成&referredClassnotKnownByCurrent之后为关键字package或class。
在步骤161,根据变成当前节点上下文选择判据的设置滤波变量,生成器引擎52获得结果节点分集。在步骤162,它检测它是否不需要产生节点,并且如果不需要产生节点,则它返回空字符串。它将第一节点作为新节点上下文进行处理(步骤163)并将解析codeString附加到高速缓存(步骤164)。它检测是否存在结果选择(步骤165)产生的另一个结果节点并对它进行处理(步骤166)。它从高速缓存返回结果产生代码。
图6示出了根据本发明优选实施例的方法。在步骤170创建新生成指令集。在步骤171对产生过程必需的参数进行定义,并且在步骤172产生代码段。可以对这些代码段进行组合以产生完整程序。
图7示出根据本发明优选实施例的另一种方法。在步骤175规定模型说明。通过表示系统中的对象,对象之间的关系以及表征对象的各类的属性和操作,这样可以对系统结构建模。此模型对产生过程提供必要参数。在说明模型说明期间可以创建下列实体程序包、界面、类、超类、外部特性、与其共享作用的关联、属性、操作以及子类。在步骤176,利用一组生成指令集定制创建或排序可以生成指令集。最后,在步骤177产生完整计算机源代码而无需用户进行调整或修改。
图8示出根据本发明优选另一个实施例的方法,在该方法中,用户可以对利用优选实施例产生的源代码进行调整并重新生成但无需做过多处理。在步骤180,既可以以文本编辑器的形式进行检索代码,也可以以用户界面的形式进行代码检索。在步骤181,用户估计在源代码中需要进行那种调整。在步骤182,获得指向生成指令集的指针。必要时,还可以获得指向模型说明和生成参数的指针。然后,在步骤183,至少对生成指令集、模型说明以及生成参数(滤波变量、上下文变量以及使用的各类代码块数目)之一进行改变。这种改变可以自动完成也可以由用户人工完成。所做这种改变可以改变生成指令集的顺序或对生成指令集进行重新排序。最后,在步骤184,当进行适当改变时,可以生成计算机源代码。
图9示出根据本发明优选实施例的装置的方框图。编辑器185用于创建或调整生成指令集。管理器186管理这些指令集,管理器186可以将它们重新排序。还包括上下文相关信息编辑器193。将生成指令集和上下文相关信息送到源代码生成器187,源代码生成器187利用上下文相关信息对生成指令集进行处理并在源代码输出端188产生源代码。为了支持编程语言,选择语言数据库189可以提供一组选择以定制生成器187。还可以包括产生指针数据191的选择指针数据生成器190,指针数据191识别在生成期间使用哪个生成指令集。指针数据191还可以识别在生成期间使用哪部分上下文相关信息。可以产生组合指针和源代码输出192。可以包括指针数据作为生成源代码内的注释行或作为独立咨询文件。
图10生成根据本发明优选实施例的另一个装置。设置组合指针显示器和源代码编辑器195。当必须改变以前生成的源代码时,生成指令管理器196可以检索指向的生成指令并将它们显示到生成指令编辑器197。必要时,指向模型说明的指针还可以用于检索模型编辑器201内的模型说明。通过改变先前生成的源代码可以自动或人工改变生成指令和模型说明。然后,将生成指令集和模型说明送到源代码生成器198,源代码生成器198产生源代码输出199。然而,重要的是,对源代码进行的所有直接改变在生成指令集和模型说明内均可以得到反映,必要时,为了保证随时可以利用生成指令集和模型说明的最新版本重新生成所使用源代码的最新版本。此外,可以包括选择语言数据库200。可以附加选择指针数据生成器202以产生组合指针数据和源代码输出203。
为了使语法与本发明优选实施例完全一致,所以图13和图14所示的涉及语法的进一步细节必不可少。
在图13中,在packageNameClause的定义中,packageNamel必须完全合格。packageName2切勿用于JAVATM。
在interfaceClause和classClause的定义中,interfaceName和className不能含有周期符号。
在superclassesClause的定义中,“;”符号表示在界面内可以包括不止一个超类。
在operationName的定义中,操作特征选择器(操作名称)必须含有全部操作特征,全部操作特征包括下列信息●interfaceType●静态(可选择)●同步的(可选择)●本机(可选择)●重调类型或空隙(如果不存在)●操作名称●‘(’●由参数类型起始之后是参数名称的参数列表●‘)’在图14中,在generationInstruction的定义中,当生成任何存在于建模工具的现存classReceiverExpression时,使用needToBeGenerated关键字。利用默认值,就不会生成现存节点(类或界面)而是生成新节点。
在attributedSubExpresion的定义中,不附加其它内容使用的含有&attribute的attributedSubExpresion意味着,如果界面或类含有属性,我们需要处理生成指令集。在singleConstantCreationDeclaration的定义中以及在variableCreationDeclaration的定义中,当创建界面和类时,使用definitionClause定义超类名称,并当创建属性时,定义其默认值。
在variableCreationDeclaration的定义中,请务必注意,当分别与“with”子句或“repeatForEach-using”子句一起使用时,variableCreationDeclaration将仅创建一个或多个项目。variableNameClause的操作名称必须包括全部操作特征,操作特征含有下列信息● interfaceType●静态(可选择)●同步的(可选择)●本机(可选择)●重调类型或空隙(如果不存在)●操作名称●‘(’●由参数类型起始之后是参数名称的参数列表●‘)’在variableNameClause的定义中,groupContextVariable可以使用的只有codeStringStatementClause。
variableName不必含有空格,但可以表示多个上下文变量。
interfaceNameFilter可以返回多个界面。
constantName必须含有全部操作特征,操作特征含有下列信息●interfaceType●静态(可选择)●同步的(可选择)
●本机(可选择)●重调类型或空隙(如果不存在)●操作名称● (’●由参数类型起始之后是参数名称的参数列表●‘)’在filterVariable的定义中,请务必注意,生成器的默认上下文总是referencesNode,referencesNode属于derivedClass的basedClass并且其本身可以作为basedClass使用。&superclass和&subclass仅离开默认上下文一层。&subclass可以返回不止一类。&inplementedInterface仅用于定义类。
在groupOfFilterVariable的定义中,此滤波变量产生与称为&group的上下文变量有关的代码块。
在associationFilterVariable的定义中,使用具有作用而没有其它内容的&Association意味着如果界面或类含有关联则对生成指令进行处理。
在externalPropertyContextVariables的定义中,“+”号将与BlockOfCode有关的baseIncrement与外部特性值相加。“++”号与“+”做同样事情,但是“++”保持相加的结果作为baseIncrement的新数值。
在communContextVariable的定义中,字符“#”将与上下文变量内容有关的程序包位置添加到与BlockOfCode有关的referredLocation子句。
在filterVariableContextVariables的定义中,因为numberOfltem是不必对与当前滤波变量表达式相关的各结果节点迭代的唯一上下文变量,所以当使用numberOfltem时,用户必须创建独立的BlockOfCode。索引的初始值是其包含迭代codeString的有基增量。实例1通过具体参考如下实例,将更加容易理解本发明,此实例仅用于说明本发明而对本发明范围没有限制意义。本例中所说明的代码不足以运行应用程序,但是可以对生成的这类代码有所了解。
根据本发明优选实施例,JAVATM生成器允许生成任意规定框架的JAVATM代码。本例说明在应用程序部件与其存储在数据库内的关联数据之间实现的具有持久性业务的企业JavaBeansTM的生成过程。本例所说明的模型和应用程序代码取自用JAVATM2.0编写的IBMVisualAge,IBM VisualAge生成的代码可以实现EJB说明。不幸地是,因为JAVATMVisualAge本身具有图形用户界面可以捕获实现性数据,所以JAVATMVisualAge使得公司不能将建模工具用作生成代码的唯一源数据。
根据本发明优选实施例的生成器可以根据模型生成相同的代码,因此由于根据本发明优选实施例的生成器产生的代码一旦生成就不需要人工干预,所以可以减少维护工作。生成器利用生成指令集生成并调节需要生成的类和方法。
利用Rational Rose 98i Enterprise Edition产生的如下简单模型定义银行业务应用程序的核心业务。该模型示于图5g,并将其相应的说明示于表1。利用与外加Rational Rose 98i相同方式实现的根据本发明优选实施例的生成器使用的特征,上述模型含有外部特性定义,在这种情况下,允许将各种属性映射到包含在应用程序数据库内的字段。开发者可以创建外部特性组并将它们指定到类集或属性集。如果定义了外部特性,开发者通过创建生成指令集就可以访问与这些特性有关的数值。
表1.模型说明




生成EJB类模型中包含的类将被分别用于产生实现企业JavaBeansTM说明的相应类集。对于从模型内取出的每个类,JAVATM生成器生成如下导出类●EJB类和界面列表●NAMEBean(用于EJB Bean)●NAME(用于EJB远程界面)●NAMEHome(EJB起始界面)●NAMEKey(用于EJB密钥类或密钥字段)●以及实现上述EJB界面的如下类●NAMEImpl(用于实现EJB远程界面)●NAMEHomeImpI(用于实现EJB起始界面)其中NAME代表从模型EJB BEAN内取出的各类的名称。
表2列出用于生成这些导出类的一些生成指令集。
表2.模板1

实体bean类的商业方法定义如何使用示例。EJB Bean类为VapEntityBeanImpl的子类,VapEntityBeanImpl为用作EJB Bean实体、实现下列标准方法的类●ejbActivate●ejbCreate●ejbLoad●ejbPassivate
●ejbPostCreat●ejbRemove●setEntityContext●unsetEntityContext请注意,由于利用VapEntityBeanlmpl类实现上述方法,所以生成类不必实现这些方法。
JAVATM生成器生成EJB Bean类的下列方法●对于各属性,生成属性的Get与Set方法的生成指令集。
●对于可导航的并且具有上限为“1”的基数的关联的各目标作用,生成作用的Get与Set方法的生成指令集。
●对于可导航的并且具有上限为“n”的基数的关联的各目标作用,生成作用的Get与Set方法生成指令集以及导出类Link和Key(即在Branch作用情况下的setBranchLink和setBranchKey)的Get与Set方法的生成指令集。
●用于初始化包装作用的对象的initializeRelationships方法。
●用于实现EJBObject的NAMEEImpl类。
表3和表4列出这些生成部分中的一些的生成指令集。
表3.模板2

表4.模板3

EJB远程界面客户通过实体bean远程界面访问实体对象。远程界面定义客户使用的商务方法。JAVATM生成器生成必须在远程界面定义的方法。
因此,存在●对于各种属性,将生成属性的Get与Set方法的生成指令集。
●对于可导航的并且具有上限为“1”的基数的关联的各目标作用,生成作用的Get与Set方法的生成指令集。
●对于可导航的并且具有上限为“n”的基数的关联的各目标作用,生成作用的Get与Set方法生成指令集以及导出类Link和Key(即在Branch作用情况下的setBranchLink和setBranchKey)的Get与Set方法的生成指令集。EJB起始界面起始界面定义客户使用的方法以创建并删除企业bean示例并获得示例的元数据。对于JAVATM生成器,存在●生成指令集,利用作为参数并代表主密钥的属性产生Creat
●生成指令集,利用作为参数并代表主密钥的属性产生Creat方法。
●生成指令集,利用作为参数并代表主密钥的属性产生Find方法。
●生成指令集,产生具有上限为W的基数的目标作用getROLELiteCollection访问方法。
●生成指令集,产生实现起始界面的类,完全产生与上述起始界面内的任意方法特征关联的索引方法内容而无需开发者人工干预。EJB密钥类此类用于创建并管理EJBObject的主密钥。利用如下内容产生与密钥类相关的生成代码●生成指令集,产生默认构造函数。
●生成指令集,产生具有作为自变量的primaryKey和lastName的构造函数。
●生成指令集,产生等同方法。
●生成指令集,产生散列方法。实现EJB远程界面的类要求生成指令集生成被称为NAMEImpl的类所需的任意方法。例如,产生示于图5h类图内的VapAccountlmpl类的所有方法,并将方法firePropertyChange()的生成代码列于表10。在表5中示出了用于生成一些firePropertyChang()代码的生成指令集。
表5.模板4

实现EJB起始界面的类要求生成指令集以生成被称为NAMEHomelmpl的类所需的任意方法。例如,产生示于图5h类图内的VapAccountHomelmpl类的所有方法,并将方法initializeRelatedHome()的生成代码列于表11。对VapAccount生成的EJB类图5h示出类集以及对VapAccount类生成的界面。对于建模工具内包含的各类,根据JAVATM的优选实施例的生成器产生等效于依赖于相关属性和作用的方法与类集。
表6至表11列出利用模型说明生成的代码以及生成指令集的完全集合。








尽管具体参考以实例说明的实施例对本发明进行了说明,很明显,对于本技术领域的技术人员来说,可以对它们进行许多调整。因此,上述说明以及附图对于本发明仅具有说明意义而没有限制意义。尽管这里使用的编程语言为JAVATM,但是本生成器还可以与其它语言一起使用,例如C++和SmallTalk。
尽管结合本发明的特定实施例对本发明进行了说明,但是很明显,可以进一步进行调整,总之,包括本发明旨在覆盖在所附权利要求范围内遵循本发明原理所做出的各种变换、使用或改进,并包括在本发明技术领域内应用上述基本特征的已知的或习惯使用的各种变形。
权利要求
1.一种用于在基于部件语言中生成计算机源代码的方法,该方法包括步骤创建至少一个生成指令集,所述生成指令集代表至少一个滤波变量和利用至少两个上下文变量参数化的目标源代码,其中各个所述至少一个滤波变量用于指示生成过程的动态上下文,各个所述至少两个上下文变量指出参考节点和参考节点标识符,并且所述至少两个上下文变量至少指出两个不同参考节点;对于所述至少一个生成指令集,定义所述参考节点以及所述至少两个上下文变量的所述参考节点标识符;在所述基于部件的源代码语言中,对于部件单元,通过在所述生成指令集内用在由所述至少一个滤波变量定义的动态上下文内找到的参考节点标识符的值替代所述至少两个上下文变量生成多个代码段。
2.根据权利要求1所述的方法,其中根据生成器当前上下文参考节点获得所述参考节点标识符的所述值。
3.根据权利要求1所述的方法,其中根据生成器当前上下文参考节点的父节点获得所述参考节点标识符的所述值。
4.根据权利要求1所述的方法,其中所述生成多个代码段包括生成新部件。
5.根据权利要求1所述的方法,其中所述生成多个代码段包括生成新方法。
6.根据权利要求1所述的方法,其中重复所述步骤直到获得定义多个部件的代码段集。
7.根据权利要求1所述的方法,其中所述基于部件语言为面向对象语言。
8.根据权利要求1所述的方法,其中所述参考节点为类。
9.根据权利要求1所述的方法,其中所述参考节点为属性。
10.根据权利要求1所述的方法,其中所述标识符为名称。
11.根据权利要求1所述的方法,其中所述标识符为类型。
12.根据权利要求1所述的方法,其中所述生成步骤包括为所述代码段选择编程语言。
13.根据权利要求1所述的方法,进一步包括生成指针数据,对于各所述代码段,该指针数据指向在所述代码段生成步骤使用的所述生成指令集。
14.根据权利要求1所述的方法,进一步包括从上下文变量列表内选择所述至少一个上下文变量的步骤。
15.根据权利要求1所述的方法,其中利用将上下文变量标识为上下文变量参数的前导符号字符,以所述至少一个生成指令集的形式来表示所述至少一个上下文变量。
16.根据权利要求13所述的方法,其中将所述指针数据从所述多个代码段存储到独立文件内。
17.根据权利要求13所述的方法,其中将所述指针数据显示为贯穿所述代码段的注释行。
18.一种用于在基于部件语言中生成计算机源代码的方法,该方法包括步骤规定各部件的模型说明;提供一组生成指令集,所述生成指令集代表至少一个滤波变量和利用至少两个上下文变量参数化的目标源代码,其中各个所述至少一个滤波变量用于指示生成过程的动态上下文,并且各个所述至少两个上下文变量指出参考节点和标识符;创建生成指令集、排序生成指令集以及定制生成指令集中至少一个与所述组集成;在所述源代码语言中,根据所述模型说明和所述生成指令集生成全部计算机源代码;其中所述模型说明被翻译为上下文相关数据,并利用所述生成指令集的集合与所述模型说明联编以生成全部计算机源代码。
19.根据权利要求18所述的方法,其中所述生成步骤包括为所述计算机源代码选择编程语言。
20.根据权利要求18所述的方法,其中创建生成指令集、排序生成指令集以及定制生成指令集中至少一个与所述组集成的所述步骤至少包括创建。
21.根据权利要求18所述的方法,其中创建生成指令集、排序生成指令集以及定制生成指令集中至少一个与所述组集成的所述步骤至少包括排序。
22.根据权利要求18所述的方法,其中创建生成指令集、排序生成指令集以及定制生成指令集中至少一个与所述组集成的所述步骤至少包括定制。
23.根据权利要求18所述的方法,进一步包括生成指针数据,对于各所述代码段,该指针数据指向在生成步骤使用的所述生成指令集。
24.根据权利要求23所述的方法,进一步包括生成指针数据,对于各所述代码段,该指针数据指向在生成步骤使用的部分模型说明。
25.根据权利要求23所述的方法,其中将所述指针数据从所述全部计算机源代码存储到独立文件。
26.根据权利要求23所述的方法,其中将所述指针数据显示为贯穿所述代码段的注释行。
27.根据权利要求18所述的方法,其中所述模型说明包括自描述树结构,并且利用映射表将所述生成指令集与所述模型说明联编,所述映射表为各参考节点和存在于所述生成指令集内的上下文变量的标识符指出存在于所述模型说明内的相应子结构。
28.根据权利要求18所述的方法,其中所述模型说明一般地用于多个基于部件语言。
29.根据权利要求28所述的方法,进一步包括将以第一基于部件语言编写的所述至少一个生成指令集翻译为第二基于部件语言的步骤,其中在第二基于部件的语言中生成计算机源代码。
30.根据权利要求29所述的方法,其中所述第一基于部件语言为JAVATM,所述第二基于部件语言为C++。
31.根据权利要求29所述的方法,其中所述翻译是自动完成的。
32.一种用于修改计算机源代码的方法,所述计算机源代码利用一组包括代表至少一个滤波变量和利用至少一个上下文变量参数化的目标源代码的生成指令的动态生成过程生成,其中各个所述至少一个滤波变量用于指示生成过程的动态上下文,并且各个上述上下文变量指出参考节点和标识符以及一个生成参数和模型说明,该方法包括检索所述生成的计算机源代码,包括从所使用的生成指令集和模型说明中检索指针数据;查找至少一部分要求改变的所述源代码;利用从所述部分检索的所述检索指针定位并改变生成指令集、上下文信息以及模型说明中的至少一个;根据所述生成指令集和一个所述参数以及模型说明生成全部计算机源代码。
33.根据权利要求32所述的方法,其中将所述指针数据显示为贯穿所述代码段的注释行。
34.一种用于在基于部件的语言中生成计算机源代码的装置,该装置包括模板编辑器,用于创建或定制至少一个生成指令集,所述生成指令集包括代表至少一个滤波变量和利用至少一个上下文变量参数化的目标源代码的生成指令,其中各个所述至少一个滤波变量用于指示生成过程的动态上下文,并且各个所述上下文变量指出参考节点和标识符;模板管理器,用于选择所述至少一个生成指令集并对所述至少一个生成指令集排序,然后设置生成参数;源代码生成器,使用所述至少一个生成指令集、所述至少一个滤波变量以及所述至少一个上下文变量以所述源代码语言形式为部件单元生成多个代码段。
35.根据权利要求34所述的装置,该装置进一步包括一组用于为生成器选择源代码的源代码语言数据库。
36.根据权利要求34所述的装置,该装置进一步包括指针数据生成器,用于生成标识用于各生成代码段的生成指令集的指针数据。
37.根据权利要求36所述的装置,其中所述指针数据生成器将所述指针数据作为生成代码段的注释行引入。
38.一种用于修改基于部件语言中的计算机源代码的装置,所述计算机源代码利用包括代表至少一个滤波变量和利用至少一个上下文变量参数化的目标源代码的生成指令的生成指令集生成,其中各个所述至少一个滤波变量用于指示生成过程的动态上下文,并且各个所述上下文变量指出参考节点和标识符,该装置包括源代码编辑器,用于检索所述生成计算机源代码,包括为各生成代码段检索指针数据和查找待实现的变更,所述指针数据用于标识所使用的生成指令集;模板管理器,将所述指针数据用于生成指令集以查找变更的存储单元;模板编辑器,用于实现所述改变;源代码生成器,使用所述生成指令集集合、所述滤波变量以及所述至少一个上下文变量以在所述源代码语言中对部件单元生成多个代码段。
39.根据权利要求38所述的装置,该装置进一步包括一组源代码语言数据库,用于为生成器选择源代码语言。
40.根据权利要求38所述的装置,该装置进一步包括指针数据生成器,用于生成标识用于各生成代码段的生成指令集的指针数据。
41.根据权利要求40所述的装置,其中所述指针数据生成器产生所述指针数据作为生成代码段内的注释行。
全文摘要
基于部件的源代码生成器利用生成指令集和参数集生成接近重复的和重复的源代码。通过使用生成指令,开发者规定源代码生成器生成什么。在生成指令集中,开发者规定目标部件和应该生成的代码。生成过程使用建模工具内的信息。因此,开发者不必对生成的代码进行调整,显著减少了维护时间,使差错最少并提高了代码的一致性。
文档编号G06F9/44GK1323415SQ99812093
公开日2001年11月21日 申请日期1999年10月12日 优先权日1998年10月13日
发明者米歇尔·布拉萨德 申请人:加拿大柯达根技术公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1