用于脚本语言编译器的扩展机制的制作方法

文档序号:6384473阅读:141来源:国知局

专利名称::用于脚本语言编译器的扩展机制的制作方法
技术领域
:本申请一般涉及编译器的领域,并且,在一个具体的示例中,涉及用于编译器的扩展机制。
背景技术
:编译器传统上编译编程语言并将其变换为可执行代码。编译器对编程语言执行句法(syntactic)、语义(semantic)分析以及代码生成。编译器可以实现在前端(frontend)或在后端(backend),并且形成复杂的系统来检查编程语言的语法定义。由形成该语言的范围的关键字组成的编程语言。语言本身可在影响语言行为的不同的上下文中使用。然而,在一些编程语言中,不能通过引入新关键字来添加新的功能。因此,需要允许不同的组在相同的编译器实施上工作,并且支持编程语言的核心开发团队未必了解的不同上下文中的编程语言的使用。
发明内容根据本发明的一个方面,提供一种计算机实施的方法。该方法包括:在机器的编译器处接收源代码,该源代码包括对编译器的脚本语言的新关键字;使用机器的处理器,用配置为支持所述新关键字的扩展编译器模块来处理所述源代码;并且基于扩展编译器模块和编译器的进程生成可执行机器代码。根据本发明的另一个方面,提供一种系统。该系统包括:机器的编译器,被配置为接收包括对所述编译器的脚本语言的新关键字的源代码;扩展编译器模块,耦合到所述编译器,该扩展编译器模块被配置为支持所述新关键字并处理所述源代码,编译器和扩展编译器模块,被配置为基于所述源代码生成可执行机器代码。根据本发明的再一个方面,提供一种非瞬时机器可读介质,体现一组指令,当该组指令由一个或多个处理器执行时,使得所述处理器执行一种方法。该方法包括:在机器的编译器处接收源代码,该源代码包括对所述编译器的脚本语言的新关键字;用扩展编译器模块处理所述源代码,该扩展编译器模块被配置为支持所述新关键字,而不必修改所述源代码的句法和语义;以及基于所述扩展编译器模块和编译器的进程生成可执行机器代码。在附图中示出了一些实施例,作为示例而非限制,在附图中:图1是描绘其中可以配置扩展编译器模块的示例机器的框图;图2是描绘扩展编译器模块的示例实施例的框图;图3是描绘扩展方法模块和后端编译器的示例实施例的框图;图4是描绘用于扩展编译器模块的方法的示例实施例的流程图;图5是描绘用于扩展编译器模块的方法的另一个示例实施例的流程图;图6是其上可以执行这里描述的方法的计算机系统的示例实施例的框图。具体实施方式在以下描述中,为了解释的目的,阐述了许多具体细节以便提供对本发明主题的各种实施例的理解。但是本领域技术人员很清楚,这些实施例可以在没有这些具体细节的情况下实施。而且,为了避免以不必要的细节模糊本发明主题,并未详细示出熟知的指令实例、协议、结构和技术。如这里所使用的,术语“或”可以以包含的意义或排他的意义来解释。术语“用户”可以被解释为包括人或机器。术语“接口”可以被解释为包括应用程序接口(API)或用户界面。术语“数据库”可以被解释为包括数据库或NoSQL或非相关数据存储(例如,Google的BigTable或Amazon的Dynamo)。术语“业务对象”可以意味这样一个对象,该对象代表软件应用内部的业务的实体。例如,业务对象可以代表企业信息管理软件应用内部的人(例如,公司的雇员)或概念(例如,公司内的进程)。公开了形成脚本语言编译器的扩展的方法。机器的编译器接收具有对编译器的语言的新关键字的源代码。扩展编译器模块处理源代码以支持新关键字。编译器和扩展编译器模块基于扩展编译器模块和编译器的进程生成可执行机器代码。脚本语言可以编译为二进制码用于运行。脚本语言可以遵循保留(reserving)关键字的原则(principal)。因此,所有将来计划的关键字(key-word)都应当预先已知和保留。然而,即使新关键字将来需要以专门的方式引入,通过脚本语言语法规则的精选(well-chosen)结构可以避免与已有脚本语言片断中的标识符冲突。图1是描绘其中可以配置扩展编译器模块的示例机器的框图。在一个示例实施例中,机器102具有编译器104、扩展编译器模块108和运行时模块106。编译器104将以源语言编写的代码变换为不同的目标语言,通常是二进制对象代码以便由运行时模块106执行。在交叉编译器的情况下,更高级的(higherlever)源语言(例如,脚本语言)被翻译为更低级的目标语言(例如,高级业务应用编程(ABAP)代码片断),该目标语言自身在随后的步骤中再次被编译为可执行代码,利用已有目标语言基础结构,并因此避免了生成依赖于平台的二进制代码的需要。在一个实施例中,编译器104编译脚本语言(例如,高级业务脚本语言(ABSL))。为此,编译器从后端读取关于ByDesign(ByD)编程模型的元数据(例如,业务对象描述)。SAP业务ByDesign是作为来自SAP的服务提供的软件。该解决方案可以在具有互联网连接和网络浏览器的PC上运行,同时软件和数据被存储在主机服务器上。经由安全互联网连接和标准网络浏览器以按请求式服务递送的业务应用可以被称为软件即服务(software-as-a-service,SaaS)到后端的无状态HTTP通道可以是单方向的,并且从位于后端的储存库服务(RepositoryService)读取元数据。所生成的ABAP代码也可以通过使用在前端的储存库客户端而存储在后端。编译器104可以包括词汇分析模块110、句法分析模块112、语义分析模块114和代码生成模块116。本领域的普通技术人员将认识到,其他组件也可以包括在编译器104中,比如预处理模块和代码最优化阶段(codeoptimizationphase)模块。词汇分析模块110(也称为词汇分析器(lexer))将源文件的输入序列字符转换为标志(token)序列,并且可以内部组织成扫描器和分词器(tokenizer)。结果得到的标志可以是分类的文本块,像符号、标识符、操作符、分隔符(delimiter)、以及语言关键字本身。在一个实施例中,标志通过由工具解释的正则表达式来描述,生成词汇分析器代码。句法分析模块112(也称为解析器)解析由词汇分析模块110提供的标志,来确定源程序的句法结构。在一个实施例中,解析器根据描述语言句法的形式语法的规则,通过将(从词汇分析模块110取得的)线性输入标志序列变换为树形结构,来构建解析树(parsetree)(抽象句法树(AbstractSyntaxTree)_AST)。句法错误可以在编译器104的这个阶段报告。语义分析模块114将语义信息添加到在先前的句法分析期间产生的解析树。而且,符号表可以被填写,并且执行诸如静态类型检查(statictypecheck)的语义检查,潜在地拒绝语义地不正确的输入。代码生成模块116将中间表示(AST)变换为输出语言。在目标平台二进制代码生成的情况下,可能需要附加的最优化,以执行复杂的CPU寄存器和存储器分配。在一个实施例中,所描述的交叉编译器可以不生成机器语言,而是另一种高级语言。代码生成可以是到具有与源语言几乎相同粒度的目标语言指令的变换。扩展编译器模块108允许不同的组在相同的编译器实施上工作,并且支持核心开发团队未必知道的不同上下文中的语言的使用。因此,本公开引入了以在下面更详细描述的扩展编译器模块108来扩展编译器104的概念。扩展编译器模块从编译器104中的新关键字生成新功能,而无需修改源代码的句法和语义。运行时模块106被配置为执行由编译器104和扩展编译器108生成的二进制代码。图2是描述扩展编译器模块108的示例实施例的框图。扩展编译器模块108可以包括扩展方法模块202、片断上下文模块204、访问路径模块206、属性处理模块208、元数据访问模块210和类型扩展模块212。在一个示例实施例中,扩展方法模块202提供对图1的编译器104(也称为核心编译器)的新扩展方法实施。扩展方法模块202使得能够将各种方法绑定到任意类型。例如,这允许将诸如“创建”、“删除”之类的核心服务绑定到BO节点或者对集合数据类型工作。扩展方法架构负责注册(registration),并且如果已经对当前处理的类型找到了匹配方法,则回调到方法实施中。实施者可以将附加的功能添加到语言,而无需修改语法。扩展方法实施将语义分析和代码生成集中化到分开的类中,其中通过分开的关注,新功能可以由若干开发者并行地提供。这增加了开发者的效率,并支持对于一个实施标题的端对端责任。例如,扩展方法(ExtensionMethods)允许由任何扩展器(extender)引入新的本机语言(nativelanguage)方法,而无需改变ABSL编译器(中间编译器)的核心部分。扩展方法经由实体方法组(MethodGroup)捆绑(bundled)。前端编译器已经通过面向对象的手段支持了扩展方法的封装(encapsulation),通过为每种方法引入自己的实施类,负责编译器阶段语义分析和代码生成。本公开引入ABSL后端编译器的使用,如图3中所示。图3示出了ABAP中的ABSL+扩展方法以及集成到ABSL+核心后端编译器中的体系结构的示例。体系结构包括扩展方法定义302、扩展方法实施304和ABSL+后端编译器306。扩展方法定义302包括若干对象类:方法组注册表(Registry)308、方法组310、抽象方法组312、抽象方法314、方法签名316、方法参数318和编译器上下文320。方法组注册表308是提供用于包含扩展方法的方法组的注册机制的中心登录点(entrypoint)。方法组注册表308将注册的方法组从注册表格(系统表格(registrationtable))静态地装载到其单实例(singleton)构造器(constructor)中。这个S表格由两个列构成,一个列存储方法组名作为主键(primarykey),而第二列存储代表方法组实施的ABAP类。在另一个实施例中,可以添加附加的列(isActive)来启用去激活(deactivation)机制,而无需去除注册条目(registrationentry)。与静态注册相反,方法组注册表308的消费者能够在运行时期间动态地注册附加的方法组。这种注册在注册表格中可以不持久(persist),而是在当前运行事务(transaction)内生存(live)。方法组注册表308提供以下方法:#-constructor从S表格装载方法组注册。#+getlnstanceO:MethodGroupRegistry获得对MethodGroupRegistry单实例的访问。静态注册被装载到构造器中。#+registerMethodGroup(methodGroup:MethodGroup)在运行时期间动态地注册不反映在注册表格中的附加的方法组。#+getMethodGroupForType(astNode:ASTNode,qualified_id:Qualifiedldentifier):MethodGroup[]返回对匹配当前类型信息的所有注册的方法组的引用(reference)。类型信息可以从传递的(passed)AST节点导出,该节点是SymbolTableEntry子类(sub-class)的实例,其表示扩展方法应当被绑定到的AST中的实体。这种方法的实施调用方法组的appliesToType方法来确定类型匹配。还可以传入(passedin)合格的标识符来避免名称冲突的情况。#+getMethodGroupByName(name:String):MethodGroup返回对匹配名称的方法组的引用。方法组310用作扩展方法模块202的编组机制。关于扩展方法是否适用于某类型(SymbolTableEntry)的判定并不是在方法级而是在方法组级(level)做出。方法组(MethodGroup)310用作扩展方法模块202的编组机制。关于扩展方法是否适用于某类型(SymbolTableEntry)的判定在方法级和方法组级二者做出。在方法组级上,对于某类型执行共同的绑定检查,而在方法级上,则对于个别的方法执行更加具体的绑定检查。例如,方法组310提供以下方法:#+getMethodGroupName():String返回方法组名称。#+addMethod(method:AbstractMethod)注册用于方法组的扩展方法实施类。这种方法可以在方法组实施类的构造器中调用。#+getMethodNamesO:String[]返回全部注册的扩展方法的名称。#+getMethod(method:String):AbstractMethod通过名称取得注册的扩展方法。#+getMethodsO:AbstractMethod[]返回当前方法组的所有注册的扩展方法。#+appliesToType(astNode:ASTNode,qualified—id:Qualifiedldentifier):Boolean确定方法组是否应用到当前类型。类型(SymbolTableEntry)可以经由传递的AST节点来访问。SymbolTableEntry不直接用作方法参数,因为可能不仅需要当前的AST节点来确定方法组匹配。父类(Ancestor)或子类AST节点可经由节点层级(nodehierarchy)访问。#+findCompatibleMethod(method:String,qualified_id:Qualifiedldentifier,baseNode:ASTNode,parameters:ASTNode[],parameterData:SymbolTableEntry[],context:CompiIerContext,(E)Signaturelndex:1nt,(E)FailedReason:1nt):AbstractMethod搜索方法组中的扩展方法,尝试匹配兼容的方法签名。#getGroupErrorCollector():MessageCollector返回错误消息收集器(collector)用于分析。抽象方法组312实施方法组310的基本功能,用于处理在方法组310内的扩展方法。因此,一般所有方法都期望AppliesToType方法已经被实施。AppliesToType方法是实施类中特有的,并且可以在实施类中定义的方法组实施。在另一个实施例中,抽象方法组312实施方法组的基本功能,用于处理在方法组内的扩展方法。因此,一般所有方法都期望appliesToType方法已经被实施。只有AppliesToType方法是实施类中特有的,并且必须在实施类中定义的方法组实施。抽象方法314定义扩展方法的基本类,并提供用于支持实施的基本功能。只有扩展方法特有的代码必须在实施类中提供。AbstractMethod通过附着于AST节点的PrimitiveFunction(SymbolTableEntry)来弓丨用。AbstractMethod可以提供以下方法:#+initContext(context:CompilerContext)在调用实例方法之前设置编译器上下文。#+isActive(currentType:SymbolTableEntry,qualified_id:Qualifiedldentifier):Boolean如果扩展方法在当前上下文中激活,则返回信息。用例(use-case)用来限制例如具体片断类型的使用。方法被定义用于方法组,但是如果方法处于未激活(inactive)状态,则不提供给消费者。此外,错误可以经由消息收集器被返回给消费者,解释方法为什么不可用。#+getMethodName():String返回方法的名称。#+deriveReturnType(signaturelndex:1nt,currentType:SymbolTableEntry):SymbolTableEntry返回用于匹配传递的类型和签名索引的扩展方法的导出的返回类型(SymbolTableEntry)。如果扩展方法过载,签名索引指示准确的参数定义。当前类型表示扩展方法调用的上一次路径项目(item)。这被用作包括错误处理的方法模板(final),请求将被委托给可以由方法实施的getReturnTypeO。#+getReturnType(signaturelndex:1nt,currentType:SymbolTableEntry):SymbolTableEntry在具体扩展方法实施类中重新定义以返回扩展方法的返回类型。#+generateCode(generator:ABSL+CodeGeneratorinterface,calINode:ASTNode,signaturelndex:1nt,parameters:ASTNode[],isStatic:Boolean)由代码生成器使用以生成表示方法扩展实施的ABAP代码。再次,如果扩展方法过载,则签名索引指示准确的参数定义。此外,ABAP代码可以根据方法是被静态地调用或基于实例调用而不同。参数(AST节点)可用来访问方法参数的语义分析。调用结点可以提供调用本身所需的信息。对ABSL+代码生成器公共接口的引用可以用来消耗由代码生成器提供的公共服务。#+getSignatureDefinitions(typelnfo:SymbolTableEntry):MethodSignature[]返回扩展方法的全部参数签名定义。在方法签名对于一个方法名称过载的情况下,可以存在若干不同的(distinct)参数签名。需要Typelnfo以用于这个方法内部的动态签名定义。#+checkParameters(typelnfo:SymbolTableEntry,parameters:ASTNode[],signaturelndex:1nt):Boolean检查扩展方法的参数。这种方法不必在每种情况下都被实施,因为匹配一般基于从签名定义取回(retrieved)的信息以及从传递的参数取回的信息来实施。在参数不能被一般地检查的情况下,这种方法允许实施特有的检查扩展方法。用例是引入为用于集合扩展方法的参数的λ(lambda)表达式。#+getMatchSignature(currentType:SymbolTableEntry,parameters:ASTNode[],parameterData:SymbolTableEntry[]):MethodSignature返回当前参数类型匹配期望的参数类型的签名。语义分析必须准确匹配一个参数签名定义以匹配扩展方法。转发到MethodSignaturecheckConformance。#+checkLHS(baseNode:ASTNode):Boolean检验左手侧(方法本身之前的最后一个路径项目)以进行特定方法的绑定检查。原因在于即使在相同的方法组中,个别的方法可以具有具体的绑定标准。最好具有较少的方法组,并将特殊的检查放在每个方法中。在其他的实施例中,可能需要额外的方法以便覆盖附加的编译器方面以及从属物。方法签名316表示参数的有序列表(orderedlist),其定义了扩展方法的签名。方法签名316也提供了方法checkConformanceO来检查参数列表的一致性(conformance)。其将每个参数检查委托给MethodParameter->checkConformance()。例如,MethodSignature提供了以下方法:#+checkConformance(snippetContext:ABSLSnippetContext,parameters:ASTNode[],parameterData:SymbolTableEntry[],messageCollector:MessageCollector):Boolean检查当前参数类型匹配期望的参数的签名。方法参数318定义扩展方法的签名定义。其指定名称、描述和期望的类型(SymbolTableEntry),并且还指示哪个参数被用于基于实例的访问。其定义方法checkConfirmanceO来检查传递的类型(SymbolTableEntry)是否可被分配给定义的期望的类型(SymbolTableEntry)。例如,MethodParameter提供了以下方法:#+checkConformance(snippetContext:ABSLSnippetContext,parameter:ASTNode,typelnfo:SymbolTableEntry):Boolean检查参数类型以匹配期望的参数。编译器上下文320为扩展方法的实施给出了对分析器的访问,并且特别是元数据访问(MDRS高速缓冲存储器)。在第一扩展方法调用之前其经由initContext方法来设置。在一个实施例中,上下文包括对分析器本身的引用和对当前块环境的引用。扩展方法实施304包括方法组实施322和扩展方法实施324。方法组和方法定义可以具有在方法组注册表处、在注册S表格中静态地或者使用方法组注册表单实例处的注册方法动态地注册的若干实施。在方法组实施322类的构造器中,具体的方法实施可以使用AddMethod方法添加到方法组。大多数方法组方法可能已经在AbstractMethodGroup312中实施,从而只有方法appliesToType必须被编码,以确定方法组是否应用到当前类型。这个确定基于当前AST节点,可以由此访问附上的SymbolTableEntry以及父类和子类AST节点。在AbstractMethodGroup312中实施的方法可以被推翻(overridden)以涵盖更具体的实施。方法组的一个示例是集合,提供扩展方法来访问和修改节点的集合和节点元素。扩展方法实施324实施以下方法:isActive、getReturnType、generateCode、getSignatureDefinitions、checkLHS、等等,因为它们是扩展方法所特有的。方法实施经由一般的AbstractMethod引用通过原函数符号表条目来引用。实施可以访问由UtilityLibrary提供的重用编码。方法组的一个示例是Collection.Add,其允许将节点或节点元素添加到节点或节点元素的集合。ABSL+后端编译器306在包括以下后端编译器阶段的运行时期间访问扩展方法实施。例如,ABSL+后端编译器306包括ABSL+分析器326(语义分析器)和ABSL+代码生成器328。ABSL+分析器326访问MethodGroupRegistry308的单实例,使用getMethodGroupForType方法找到用于当前处理的AST节点的类型(SymbolTableEntry)的匹配方法组310。已经编译了一列方法组引用,分析器检查匹配的方法组之一中可能表示方法的当前处理的标志。如果可以识别通过名称匹配的方法,则分析器尝试找到AST中的可用参数与方法的签名定义也匹配的一个匹配方法。为此,方法的第一参数被递归地分析,从而它们的代表AST节点具有附上的类型(SymbolTableEntry)。通过调用getSignatureDefinition方法,从识别的方法中取回签名定义。期望的参数的类型信息(SymbolTableEntry)被尝试与实际参数AST节点的类型信息(SymbolTableEntry)进行匹配。如果只能识别一个扩展方法,则创建新类型(子类型PrimitiveFunction的SymbolTableEntry),其具有对扩展方法的引用。使用getReturnType方法确定返回类型(SymbolTableEntry)并链接到AST节点中。对识别扩展方法的引用及其返回类型信息被附接到这个新的PrimitiveFunction,从而可以稍后经由AST由代码生成访问。基于加强的(enriched)AST节点和返回SymbolTableEntry,对子类AST节点递归地处理语义分析。ABSL+代码生成器328从分析器326得到加强的AST,因此可以访问附上的类型/数据(SymbolTableEntry)。AST节点是按层级遍历的,如果AST节点具有对类型PrimitiveFunction的SymbolTableEntry的引用,则其具有类型AbstractMethod的分配的扩展方法。代码生成可以使用扩展方法实施的generateCode方法来执行。用于代码生成的输入是可以经由AbstractMethod引用和用于调用的AST节点访问的信息。在扩展方法本身的代码生成之前,评估扩展方法参数和基础路径的代码生成。结果得到的ABAP代码必须被上推(pushedup)到代码序列中。所生成的代码被附加到生成器中先前生成的代码中。ABSL+代码生成器328可以经由公共接口提供以下方法:#+appendToCodeline(code:String,noGap:Boolean,positionAST:ASTNode)修改当前代码行:输入字符串+当前代码行。noGap指示是否需要空格作为中间的分隔符。positionAST用来得到位置信息。#+concatToCodeline(code:String,noGap:Boolean,positionAST:ASTNode)修改当前代码行:当前代码行+输入字符串。noGap指示是否需要空格作为中间的分隔符。positionAST用来得到位置信息#+createlnlineABAP(code:String,sourcePositionSRCP0S)创建AST节点用于内联的(inIine)ABAP,并将其放在前缀声明表中用于将来清除(flush)。sourcePosition是这样的AST节点的相应的源位置。#+createVarDeclaration(name:String,typelnfo:SymbolTableEntry,value:ASTNode,flush:Boolean):ASTNode如果提供了值,则以该值在ABAP片断中创建新变量。清除标志指示前缀声明清除是否应当被立即触发。#+generateExpression(expressionNode:ASTNode,writeAccess:Boolean,extendBool:Boolean,declarative:Boolean,deref:Boolean)生成用于表达式的ABAP代码。#+newCodeline(genPrefixStatBefore:Boolean,genPrefixStatAfter:Boolean,positionAST:ASTNode)将当前代码行插入ABAP片断的表格中,然后清空并开始新的代码行。#+refactorExpression(expressionNode:ASTNode,writeAccess:Boolean)重构(refactor)表达式,并之后清除前缀声明。#+fIushPrefixStatement()清除前缀声明。#+increaselndent()/decreaselndent()增加/减少ABAP代码缩进(indent)。#+setGlobalVariables(kind:1nt)设定ABAP片断中的全局变量。#+createABAPName(ABSLName:String):String基于ABSL名称生成唯一的ABAP名称。当调用方法generateCode时,扩展方法实施可以访问ABSL+代码生成器328,因为它是作为参数传递的。如果模板机制被引入到代码生成中,generateCode方法组必须被调整,给予对模板机制的访问,提供消费者预填参数串模板实例并返回填写的串模板实例的手段。返回到图2,片断上下文模块204对不同片断元数据和片断签名的定义进行建模。脚本语言在一些特定上下文中运行。默认的,上下文可以是业务对象节点实例,绑定“这个(this)”关键字到相同的实例。编译器104和语言被增强,以便通过指定描述了所述语言在其中使用的上下文的明确定义的片断元数据来支持各种上下文。通过这个其它上下文,可以启用BO实施上下文,例如,进程集成条件评估、表单消息类型扩展、UI控制器实施、应用特有的程序库。这可能要求从不同的运行时上下文中定义不同的片断签名。在一个实施例中,片断具有附上的、存储为xRepositoryAttributes的元数据信息。所有片断类型共享一组相同的信息,如工程命名空间、BO名称、节点名称、定制文件名和大量处理指示符。额外的元数据作为上下文特有的信息存储。服务集成类型PIConditionEvaluation的片断存储以下元数据〇出站BO名称/命名空间〇服务集成名称(PIName)〇条件类型(SnippetSubType).Β0扩展类型XBODetermination的片断存储以下元数据〇扩展的BO名称/命名空间〇扩展性标志表单消息类型扩展类型FMTExtension的片断存储以下元数据OFMT名称OFMT类型OFMT数据类型OFMT根元素为了允许ABSL的新的上下文的无缝增强和集成,扩展性机制将被引入以支持附加信息的存储。由于脚本文件总是创建在ByDesignStudio前端,而且片断元数据在那里被指定并存储在xRepository中。没有用于在创建之后改变脚本文件元数据的用例。根据处理的片断类型,ABSL+后端编译器(图3的306)必须在编译期间评估这个信息,以便建立ABSL代码生存于其中的正确的上下文。当前的ABSL片断大多没有签名定义,类似于例如BO动作和事件实施。有两个引入参数的用例,但是当前这些参数定义或多或少对于片断类型是硬编码的。这两个用例当前是:服务集成类型PIConditionEvaluation的片断具有以下参数OImporting:1nReconciliationiBooleanOReturning:1sActiveiBoolean表单消息类型扩展类型FMTExtension的片断具有以下参数OImporting:FormData:FMTType从这些用例中,可以导出两个不同类型的签名:每个片断类型的静态签名(服务集成用例)〇签名被定义为变换定义,变换定义的名称被存储为脚本文件元数据。每个片断实例的特定签名(表单消息类型扩展用例)〇每个表单消息类型扩展具有一个参数FormData,但是根据表单消息,这个参数可以总是具有扩展的不同的类型。〇因此签名不能静态地存储为变换定义,而是签名本身必须被建模为脚本文件元数据〇作为混合模式,签名的静态部分可以建模为变换定义,其中动态部分由任何类型(typing)来表达。任何类型然后被具体化(concretized)在片断元数据中。ABSL运行时间动态地调用片断实施,之前从MDRS对象变换定义读出签名定义。这个调用应当确切地如已对也由变换定义来表示的库函数进行的那样进行。访问路径模块206访问在脚本语言体系结构(例如,德国SAP的ByDesign)中定义的不同的数据路径。脚本语言基于编程模型。主要的制造物是定义用于业务数据的模型的实体B0。因此,语言中的主访问路径是BO实例,BO实例可以被访问,并且可以由此导航到另外的数据。不同片断上下文也可以要求不同的访问路径。例如,在表单消息类型扩展中,也可以访问深结构数据类型(deeplystructuredatatypes)。在UI控制器实施中,UI模型需要被访问。在一个实施例中,默认访问路径是BO节点路径。类型FMTExtension的片断引入具有参数FormData的新类型的路径。这个路径基本上表示由消息节点和信息元素构成的消息类型相关的路径。为了在将来容易地启用新路径(例如在Π控制器的数据模型中的路径……),需要扩展机制以便支持编译器阶段的无缝集成、语义分析和代码生成。用于代码完善的额外的支持也应当是可能的,虽然代码完善当前在后端编译器的范围之外,并且仍然由前端编译器处理。新的路径将引入新的子类型的SymbolTableEntry,表示在分析和代码生成期间在编译器中的上下文特有的路径表达式。涵盖以下特征:用于路径存在和错误处理的语义检查当前处理的AST节点和相应的SymbolTableEntry的消耗确定结果得到的SymbolTableEntry代码完善支持(当前在范围之外)代码生成代码生成应该与标准代码生成尽量对齐(aligned)。在例外情况下,如果需要不同的代码生成,则代码生成的实施应该基于上下文被形象化(externalized)。这意味着上下文特有的生成将不被包括在核心代码生成中,而是委托在上下文特有的实施类中。无论如何在这种情况下新的SymbolTableEntry被引入,代码生成可以使用这个对象委托。属性处理模块208通过指定评估属性和限制对ByD平台的访问来控制语义分析。ByD体系结构定义用于企业服务构架和用于其它的公共方案模型的属性。这些属性需要被有效地评估并且对应于定义的片断上下文。代替对评估进行硬编码,可以实施参观者模式,以允许在查询时对属性值做出贡献。例如,当查看只读属性时,有很多贡献者(contributors)能够判定元素或节点是否是只读的。ByD体系结构定义关于业务对象建模实体的若干属性来控制消费者的访问。示例是ESI属性和PSM属性,ESI属性如对元素的只读、对节点和关联的创建启用和删除启用,而PSM属性如释放和写启用。访问属性根据它们的语义编组,从而例如,ESI只读和PSM不写启用被解释为一个只读信息。只读属性在其他的访问属性中具有非凡的角色,因为其具有对具体值做出贡献的各种源。以下访问限制就地形成ABSL+后端编译器已知的只读标志:.ESI属性〇只读属性公共解决方案模型〇如果非PSM写启用则只读(BO、节点、节电元素)一次性模式(用于消费者个别解决方案的限制模式)〇仅对ByDBO的只读访问(incl.actions)O对伙伴BO的写访问服务集成类型PIConditionEvaluation的片断具有以下限制〇只有对伙伴BO和ByDBO的只读访问表单消息类型扩展类型FMTExtension的片断具有以下限制O对伙伴的消息类型扩展的写访问〇对在核心ByD中定义的消息类型元素的只读访问〇对伙伴BO和ByDBO的只读访问使用前端编译器中的各自的isAssignable标志先前实现的语义地表达ByD内容的“只读”分类的所有情形都将因此被加上标志,并通过语义分析集中评估。扩展实施可以通过将其设定为真(true)来贡献这个“只读”。一旦被设定则不能返回到假(false)。访问属性需要在语义分析期间通过ABSL+后端编译器来解释。如果属性禁止对ByD内容的写访问,编译器将与各自的编译器错误起反应。PSM释放的信息也应当在分析器中得到尊重。可能已经在MDRS访问类中对其进行了分析,从而消费者不需要知道关于这个标志,如在前端编译器中进行的那样。然后缺点是不再可能区分不存在和未释放的内容。元数据访问模块210访问集中化的元数据,并增强与额外的数据的访问。为了避免重复取回元数据,中心元数据访问器(accessor)可以负责读取和缓冲逻辑。额外的扩展器能够插入(pluginto)元数据的取回中,自动地参与到缓冲和取回逻辑中,从而所有的消费者都受益于它。性能最优化可以通过例如将MDRS(元数据储存库)高速缓冲存储器放到共享存储器中来进行。这个抽象忽略了那些消费者的细节,但是允许他们专注于如何装载元数据。不同的访问路径需要不同的元数据。当前所有的元数据在MDRS中可用,因此ABSL+后端编译器可以访问MDRS高速缓冲存储器。为了支持在MDRS高速缓冲存储器中还未可用的元对象信息的访问,MDRS高速缓冲存储器需要扩展。由于这只有根据访问路径的上下文才需要,所以元数据的读取也应当是可扩展的。为了支持这种新的元数据的供应(),内容需要经由能够实施的接口是可用的。根据数据MO类型、命名空间和名称,一般可以实施对所提供的内容的搜索。类型扩展模块212用额外的类型来扩展语言。这种更深的集成支持扩展编译器模块108包括新的类型,允许其定义语义检查以及新的类型将被如何变换为ABAP。在一个实施例中,类型扩展模块212在ABSL中弓丨入新的功能可能需要弓I入新的类型,这在之前并不需要或者完全没有意义。例如,类型说明集合在集合处理启用的上下文中可能是有用的。类型扩展的引入包括:类型的创建〇创建类型口显式类型创造:显式数据类型的说明□隐式类型创造:从另一个建模实体中导出数据类型(例如,BO节点)〇自身类型定义□当前不在ABSL内。各自的实体定义,如BO语言和FMT类型可用于创建数据类型可分配性〇默认是新的类型不可分配到任何其他的类型□这一般在语义分析中检查□程序库可以提供以允许转换,例如ToStringO〇默认可以被推翻以使得类型对于其他已有类型是可分配的/可塑的(assignable/castable)□这需要在退出实施中检查代码生成〇需要在对在来自不同的上下文的代码生成期间使用的创建的类型的退出实施中实现。图4是描绘用于扩展编译器模块的示例方法的流程图400。在操作402,在机器的编译器接收源代码。源代码包括对编译器的脚本语言的新关键字。例如,脚本语言可以是被配置为创建和/或建模业务对象的语言。在操作404,被配置为支持新关键字的扩展编译器模块处理源代码。在一个实施例中,扩展编译器模块在编译器中从新关键字生成新的功能,而无需修改源代码的句法和语义。在操作406,可执行的机器代码基于扩展编译器模块和编译器的进程而生成。图5是描绘用于扩展编译器模块的另一个示例方法的流程图500。在操作502,扩展方法模块处理源代码的脚本语言。在操作504,片断上下文模块处理源代码的脚本语言。在操作506,访问路径模块处理源代码的脚本语言。在操作508,属性处理模块处理源代码的脚本语言。在操作510,元数据访问模块处理源代码的脚本语言。在操作512,类型扩展模块处理源代码的脚本语言。如先前描述的,代替直接修改编译器扩展的核心编译器,本公开允许通过引入明确定义的接口来去耦(decouple)实施。这种职责的隔离使得新的语言扩展和特征的实施更加容易。额外的更多的组可以被启用以便对那些扩展和特征独立地工作,而不会在开发对象中互相干扰或锁定。因为存在明确定义的接口,编译器也更容易理解。一个特征的实施可以被集中到一个实施类中,而不是像现有技术中进行的那样,在整个编译器中传播一个特征的实施。一个特征实施的扩展可以一眼看出,并且也不会迷失在编译器代码中,不知道哪部分属于哪个特征实施。此外,语言可以更容易地支持更多的上下文,因为所有上下文相关部分可以被形象化为建模部分或明确定义的接口。模块、组件和逻辑某些实施例在这里被描述为包括逻辑或一些组件、模块或机制。模块可以构成软件模块(例如,实现在机器可读介质上或实现在传输信号中的代码)或硬件模块。硬件模块是有形的单元,能够执行某些操作,并且可以以某一方式来配置或安排。在示例的实施例中,一个或多个计算机系统(例如,单机、客户端或服务器计算机系统)或计算机系统的一个或多个硬件模块(例如,处理器或一组处理器)可以通过软件(例如,应用或应用部分)来配置,作为操作来执行在这里描述的某些操作的硬件模块。在各种实施例中,硬件模块可以机械地或电子地实施。例如,硬件模块可以包括专用的电路或逻辑,被永久配置(例如,作为特殊用途的处理器,诸如现场可编程门阵列(FPGA)或专用集成电路(ASIC))来执行某些操作。硬件模块还可以包括可编程逻辑或电路(例如,如包围在通用处理器或其它可编程处理器之内),其临时由软件配置来执行某些操作。应当理解,判定在专用的和永久地配置的电路中或者在临时配置的电路(例如,由软件配置)中机械地实施硬件模块可以基于成本和时间的考虑而被驱动。因此,术语“硬件模块”应当被理解为包含有形的实体,可以是物理构建的、永久配置的(例如,硬布线)、或临时配置的(例如,编程的)的实体,用来以某种方式进行操作和/或执行某些这里描述的操作。考虑其中硬件模块是临时配置的(例如,编程的)实施例,硬件模块中的每一个不需要在任何一个实例及时的配置或实例化。例如,其中硬件模块包括使用软件配置的通用处理器、通用处理器可以在不同时间被配置为相应的不同的硬件模块。软件可以相应地配置处理器以便例如在一时间实例构成特定硬件模块,而在不同的时间实例构成不同的硬件模块。硬件模块可以向其它硬件模块提供信息和从其它硬件模块接收信息。因此,所描述的硬件模块可以被认为是可通信地耦合。在同时存在多个这样的硬件模块的情况下,可以通过连接硬件模块的信号传输(例如,通过适当的电路和总线)来达成通信。在其中在不同的时间配置或实例化多个硬件模块的实施例中,可以达成这样的硬件模块之间的通信,例如,通过所述多个硬件模块可以访问的存储器结构中的信息的存储与取回。例如,一个硬件模块可以执行操作,并将操作输出存储在其通信地耦合的存储设备中。而且,另外的硬件模块可以在稍后的时间访问存储设备,以便取回并处理所存储的输出。硬件模块还可以启动与输入或者输出设备的通信,并且可以对资源(例如,信息的集合)进行操作。这里描述的示例方法的各种操作可以由被临时配置(例如,由软件)或永久配置来执行相关操作的一个或多个处理器执行(至少部分地执行)。无论是临时配置还是永久配置,这样的处理器可以构成处理器实施的模块,其被操作来执行一个或多个操作或功能。在一些示例实施例中,这里所说的模块可以包括处理器实施的模块。类似地,这里描述的方法可以至少部分地是处理器实施的。例如,方法的至少一些操作可以由一个或多个处理器或者由处理器实施的模块来执行。某些操作的执行可以分布在一个或多个处理器中,不仅在单一的机器之内,而是配置在多个机器中。在一些示例实施例中,一个或多个处理器可以位于单一位置(例如,在家庭环境中、在办公环境中,或者作为服务器场(serverfarm)),而在其他实施例中,处理器可以分布在多个位置。一个或多个处理器还可以操作以支持相关操作在“云计算”环境中的执行或者作为“软件即服务”(SaaS)执行。例如,至少一些操作可以由一组计算机(作为包括处理器的机器的示例)执行,这些操作可经由网络访问以及经由一个或多个适当的接口(例如,API)访问。电子装置和系统示例实施例可以以数字电子电路或者计算机硬件、固件、软件、或它们的组合来实施。示例实施例可以使用计算机程序产品来实施,例如,有形地体现在例如机器可读介质的信息载体中的计算机程序,用于由数据处理装置运行或控制数据处理装置的操作,所述数据处理装置例如可编程处理器、计算机或多个计算机。计算机程序可以以任何形式的编程语言来编写,包括编译或解释语言,并且可以以任何形式来配置,包括作为独立程序或作为模块、子例程、或适于在计算环境中使用的其它单元。计算机程序可以被配置为在一个计算机上或在一个地点或跨过多个地点分布并通过通信网络互连的多个计算机上运行。在示例实施例中,操作可以由一个或多个执行计算机程序的可编程处理器执行,以便通过对输入数据进行操作以及生成输出来执行功能。方法操作还可以由专用逻辑电路(例如,FPGA或ASIC)来执行,并且示例实施例的装置可以实施为专用逻辑电路(例如,FPGA或ASIC)。计算系统可以包括客户端和服务器。客户端和服务器一般彼此远离,并且典型地通过通信网络进行交互。客户端和服务器的关系根据运行在各自计算机上并且彼此具有客户端-服务器关系的计算机程序而产生。在配置可编程计算系统的实施例中,应当理解,硬件和软件两者的体系结构都要考虑到。具体地说,应当理解,关于是否以永久配置的硬件(例如,ASIC)、临时配置的硬件(例如,软件和可编程处理器的组合)、或者以永久和临时配置的硬件的组合来实施某一功能的选择可以是一种设计选择。以下陈述可以在各种示例实施例中配置的硬件(例如,机器)和软件体系结构示例的机器体系结构和机器可读介质图6是计算机系统600的示例形式中的机器的框图,在计算机系统600中可以执行指令,所述指令使得机器执行这里所讨论的一个或多个方法。在替换的实施例中,机器操作为独立的设备,或者可以连接到(例如,联网到)其它机器。在联网的配置中,机器可以作为在服务器-客户端网络环境中的服务器或客户端机器来操作,或者作为在对等(或分布的)网络环境中的对等机器来操作。机器可以是PC、平板PC、机顶盒(STB)、个人数字助理(PDA)、蜂窝式电话、网络用具、网络路由器、开关或桥,或者是能够执行指定将由那个机器执行的动作的指令(顺序地或非顺序地)的任何机器。而且,虽然示出了单一的机器,但是术语“机器(machine)”还应当被认为包括任何机器的集合(collection),所述机器的集合个别地或联合地执行一组(或多组)指令,以执行任何一个或多个这里所讨论的方法。示例的计算机系统600包括处理器602(例如,中央处理单元(CPU)、图形处理单元(GPU)、或两者)、主存储器604和静态存储器606,它们经由总线608互相通信。计算机系统600还可以包括视频显示单元610(例如,液晶显示器(IXD)或阴极射线管(CRT))。计算机系统600还包括字母数字输入设备612(例如,键盘)、用户界面(UI)导航(或光标控制)设备614(例如,鼠标)、盘驱动单元616、信号生成设备618(例如,扩音器)和网络接口设备620。机器可读介质盘驱动单元616包括机器可读介质622和数据结构(例如,软件)624,一组或多组指令存储在机器可读介质622上,数据结构624通过任何一个或多个这里描述的方法或功能来体现或利用。指令624在由计算机系统600执行期间还可以完全地或至少部分地居于主存储器604和/或处理器602内,并且主存储器604和处理器602也构成机器可读介质。指令624还可以完全地或至少部分地居于静态存储器606内。虽然机器可读介质622在示例实施例中被示出为单一的介质,术语“机器可读介质”可以包括存储一个或多个指令或数据结构的单一介质或多个介质(例如,集中的或分布的数据库、和/或相关联的高速缓冲存储器和服务器)。术语“机器可读介质”还应当被认为包括任何有形的介质,所述介质能够存储、编码、或携载用于由机器执行的指令,并且使得机器执行本实施例的任何一个或多个方法,或者能够存储、编码、或携载由这样的指令利用或与这样的指令相关联的数据结构。术语“机器可读介质”因此应当被认为包括但不限于固态存储器、以及光介质和磁介质。机器可读介质的具体示例包括非易失性存储器,包括举例来说的半导体存储器件(例如,可擦除可编程只读存储器(EPR0M)、电可擦除可编程只读存储器(EEPR0M)、以及闪存器件);磁盘,诸如内部硬盘和可移动盘;磁光盘;以及光盘只读存储器(CD-ROM)和数字多功能盘(或数字视频盘)只读存储器(DVD-ROM)盘。传输介质指令624还可以使用传输介质通过通信网络626传送或接收。指令624可以使用网络接口设备620以及许多熟知的传输协议(例如,HTTP)中的任何一个来传送。通信网络的示例包括LAN、WAN、互联网、移动电话网络、POTS网络、以及无线数据网络(例如,WiFi和WiMax网络)。术语“传输介质”应当被认为包括任何能够存储、编码、或携载用于由机器执行的指令的无形介质,并且包括数字或模拟通信信号或其它无形介质以帮助这样的软件的通信。虽然已经参考具体示例实施例描述了实施例,很明显可以对这些实施例做出各种修改和改变,而不脱离本公开的更宽的精神和范围。因此,说明书和附图应当以说明性而非限定性的意义来对待。作为其一部分的附图作为例示而非限制示出了其中可以实践本主题的具体实施例。示出的实施例被足够详细地进行了描述,使得本领域技术人员能够实践在这里公开的教导。可以由此利用和导出其它的实施例,以便可以进行结构和逻辑上的替换和改变,而不脱离本公开的范围。因此,这个详细的描述不应被认为是限定性的,并且各种实施例的范围仅由所附权利要求以及对这样的权利要求给予的等效物的完整范围来定义。本发明主题的这样的实施例在这里被称为(个别地和/或共同地)术语“发明”仅仅是为了方便起见,而并非意图主动地将这个申请的范围限制到任何单一的发明或发明概念,如果实际公开了超过一个。因此,虽然已经在这里示出和描述了具体的实施例,应当理解,任何被计算为达成相同目的的配置都可以用来替换所示出的特定实施例。本公开意图涵盖各种实施例的任何以及全部适配或变化。在阅读上述描述之后上述实施例以及在这里没有具体描述的其它实施例的组合对于本领域技术人员将是清楚的。权利要求1.一种计算机实施的方法,包括:在机器的编译器处接收源代码,该源代码包括对编译器的脚本语言的新关键字;使用机器的处理器,用配置为支持所述新关键字的扩展编译器模块来处理所述源代码;并且基于扩展编译器模块和编译器的进程生成可执行机器代码。2.如权利要求1所述的计算机实施的方法,其中所述编译器被配置为:分析所述源代码的句法;分析所述源代码的语义;并且基于所述源代码的句法和语义来生成可执行机器代码。3.如权利要求2所述的计算机实施的方法,其中所述扩展编译器模块被配置为在所述编译器中从新关键字生成新功能,而没有修改所述源代码的句法和语义。4.如权利要求1所述的计算机实施的方法,其中所述扩展编译器模块被配置为用扩展方法模块将方法绑定到任意类型。5.如权利要求1所述的计算机实施的方法,其中所述扩展编译器模块被配置为用片断上下文模块对元数据和签名的片断的定义进行建模。6.如权利要求1所述的计算机实施的方法,其中所述扩展编译器模块被配置为用访问路径模块使得能够访问对脚本语言体系结构中定义的多个访问路径。7.如权利要求1所述的计算机实施的方法,其中所述扩展编译器模块被配置为用属性处理模块通过指定评估属性和限制对脚本语言体系结构的访问来控制语义分析。8.如权利要求1所述的计算机实施的方法,其中所述扩展编译器模块被配置为用元数据访问模块以从集中的元数据储存库缓冲取回数据的方式来访问集中的元数据储存库。9.如权利要求1所述的计算机实施的方法,其中所述扩展编译器模块被配置为用类型扩展编译器模块将编译器的脚本语言扩展到新的类型。10.如权利要求1所述的计算机实施的方法,其中所述源代码包括业务对象。11.一种系统,包括:机器的编译器,被配置为接收包括对所述编译器的脚本语言的新关键字的源代码;扩展编译器模块,耦合到所述编译器,该扩展编译器模块被配置为支持所述新关键字并处理所述源代码,编译器和扩展编译器模块,被配置为基于所述源代码生成可执行机器代码。12.如权利要求11所述的系统,其中所述编译器被配置为:分析所述源代码的句法;分析所述源代码的语义;并且基于所述源代码的句法和语义生成可执行机器代码,所述源代码包括业务对象。13.如权利要求12所述的系统,其中所述扩展编译器模块被配置为在所述编译器中从新关键字生成新功能,而没有修改所述源代码的句法和语义。14.如权利要求11所述的系统,其中所述扩展编译器模块还包括:扩展方法模块,被配置为将方法绑定到任意类型。15.如权利要求11所述的系统,其中所述扩展编译器模块还包括:片断上下文模块,被配置为对元数据和签名的片断的定义进行建模。16.如权利要求11所述的系统,其中所述扩展编译器模块还包括:访问路径模块,被配置为使得能够进行对在脚本语言体系结构中定义的多个访问路径。17.如权利要求11所述的系统,其中所述扩展编译器模块还包括:属性处理模块,被配置为通过指定评估属性和限制对脚本语言体系结构的访问来控制语义分析。18.如权利要求11所述的系统,其中所述扩展编译器模块还包括:元数据访问模块,被配置为以从集中的元数据储存库缓冲取回数据的方式来访问集中的元数据储存库。19.如权利要求11所述的系统,其中所述扩展编译器模块还包括:类型扩展编译器模块,被配置为将所述编译器的脚本语言扩展到新的类型。20.一种非瞬时机器可读介质,包含一组指令,当该组指令由一个或多个处理器执行时,使得所述处理器执行一种方法,该方法包括:在机器的编译器处接收源代码,该源代码包括对所述编译器的脚本语言的新关键字;用扩展编译器模块处理所述源代码,该扩展编译器模块被配置为支持所述新关键字,而不必修改所述源代码的句法和语义;以及基于所述扩展编译器模块和编译器的进程生成可执行机器代码。全文摘要公开了用于形成脚本语言编译器的扩展的方法。机器的编译器接收具有对编译器的脚本语言的新关键字的源代码。扩展编译器模块处理源代码以支持新关键字。编译器和扩展编译器模块基于扩展编译器模块和编译器的进程生成可执行机器代码。文档编号G06F9/45GK103164249SQ20121054831公开日2013年6月19日申请日期2012年12月17日优先权日2011年12月15日发明者A.卡巴拉,O.克莱门兹,A.米勒,Z.赵申请人:Sap股份公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1