专利名称:编译器生成系统和方法
技术领域:
本发明涉及计算系统,更确切地说,涉及由形式描述到源代码和可执行代码的生成。
背景技术:
对于很多应用,可以用例如正则表达式(regular expression)的形式语言和上下 文无关语法,对要被处理的数据的结构进行数学描述。这些数据描述可以在编译器构造中 找到应用。另外,这些结构可以用于操作或评测数学表达式、以及诸如计算机游戏及搜索引 擎的具有一般文本输入的程序中。这些表达式还可以用于高速缓冲存储器和网络协议中。
分析这些结构化数据的计算机程序可以由形式描述自动生成。这种工具通常被称 为编译器生成器。编译器的编译器(compiler-compiler)或编译器生成器是从某种形式的 形式描述来创建扫描器、分析器(parser)、解释器或编译器的一种工具。最早且仍然是最常 见的形式的编译器的编译器是分析器生成器,它的输入是编程语言的语法(通常是巴科斯 诺尔形式(Backus-NaurForm, BNF)),它生成的输出是分析器的源代码。
理想的编译器的编译器采用编程语言和对象指令集架构的描述,并由它们自动生 成有用的编译器。实际上,该技术的状态还没有达到如此复杂的程度,并且,大多数编译器 生成器还不能处理语义或目标架构信息。 编译器生成器一般包括扫描器生成器和分析器生成器,且自从20世纪60年代后 期以来,在一些简单的形式上就已经可用了。扫描器生成器一般处理正则表达式,而分析器 生成器处理上下文无关语法。 在计算中,正则表达式提供了一种简明且灵活的识别感兴趣文本的字符串的方 法,这些字符串例如为特定字符,词或字符样式。通过可以由正则表达式处理器(即,可 以用作分析器生成器、或检查文本并识别与所提供的规范相匹配的部分的程序)解释的 形式语言,来编写正贝U表达式(简称为regex或regexp,复数形式是regexes, regexps或 regexen)。在形式语言理论中,上下文无关语法(CFG)是这样的语法,其中,每个产生式规 则是V — w形式,其中V是单个的非终结符符号,且w是终结符和/或非终结符的字符串 (可能为空)。术语"上下文无关"表示非终结符可以不考虑它们出现过的上下文而被重写 的事实。如果某种上下文无关语法生成形式语言,则形式语言是上下文无关的。上下文无 关语法在编程语言和编译器的描述与设计中起到了核心的作用。它们也用于分析自然语言 的句法。 正则表达式和上下文无关语法可以选择性地包含分散的(interspersed)C代码 段。总之,编译器生成器一般由扫描器生成器和分析器生成器的输入(具有附加的C代码) 生成源代码(作为可执行文件),之后由编译器翻译该源代码。
发明内容
根据本发明的一个实施例的系统包括扫 和分析模块,用于接收统一的输入描述,所述统一的输入描述包含用于正则表达式和上下文无关表达式两者的句法规则、以及 分散代码,该扫描和分析模块被配置用于将所述统一的输入描述翻译成公共内部表示;与 该扫描和分析模块连接的正则表达式检查器,其被配置用于检查在公共内部表示中的正则 表达式;与该正则表达式检查器连接的上下文无关表达式检查器,其被配置用于检查在公 共内部表示中的上下文无关表达式;与该上下文无关表达式检查器连接的代码检查器,其 被配置用于检查所述分散代码;以及与该代码检查器连接的代码优化器和代码生成器。
本发明的另一个实施例是针对一种方法,包括接收统一的输入描述,所述统一的 输入描述包含用于正则表达式和上下文无关表达式两者的句法规则、以及分散代码;从所 述统一的输入描述生成公共内部表示;检查在公共内部表示中的正则表达式;检查在公共 内部表示中的上下文无关表达式;检查所述分散代码;以及基于所述统一的输入描述,输 出可执行程序,该可执行程序作为编译器操作。 本发明的另一个实施例是针对一种系统,包括扫描和分析模块,用于接收统一 的输入描述,所述统一的输入描述包含用于正则表达式和上下文无关表达式两者的句法规 则、以及分散代码,该扫描和分析模块被配置用于将所述统一的输入描述翻译成公共内部 表示;与该扫描和分析模块连接的表达式检查器,其被配置用于检查在公共内部表示中的 表达式;与该表达式检查器连接的代码检查器,其被配置用于检查所述分散代码;以及与 该代码检查器连接的代码优化器和代码生成器。 另外的特征和优势通过本发明的技术得以实现。本发明的其他实施例和方面将在 这里详细描述并作为发明申请的一部分。为了更好的理解本发明的优势和特征,请参阅说 明书和附图。
本发明的主旨在说明书结论的声明中被特别地指出并清楚地声明。从下面的与附
图相一致的详细描述可以明显看出本发明的前述的和其他特征以及优势。
图1显示了现有技术的编译器生成器; 图2显示了本发明实施例可以操作的系统; 图3是显示了本发明的一个实施例的数据流图; 图4显示了图3所示的编译器生成器/编译器的更加详细的描述。
具体实施例方式
现在参考图1,显示了现有技术的编译器生成器系统的示例。编译器生成器系统利 用形成编译器102的编程语言来生成源代码。这种编程语言的一个示例是C语言。当然, 也可以使用其他语言类型,如0++^(^或》^。编译器生成器系统包括生成编译器102的 编译器104。编译器104可以是为所利用的特定语言而编写的预先存在的编译器。
编译器104接收来自源文件存储器106的预先存在的源文件、由分析器生成器108 创建的分析器源代码、以及由扫描器生成器IIO创建的扫描器源代码。扫描器生成器IIO接 收扫描器输入文件112,分析器生成器108接收分析器输入文件114。由扫描器生成器110 创建的扫描器源代码包含用特定编程语言(如C)编写的语义行为,且可能包含尚未报告的 错误。由分析器生成器108创建的分析器源代码包含用特定编程语言(如C)编写的语义行为,且可能包含尚未报告的错误。编译器104接收分析器源代码和扫描器源代码,并创建 可执行编译器102。这个可执行编译器可能包含源自尚未报告的分析器和扫描器源代码中 的错误的错误。 所有编译器生成器(如图l所示的编译器生成器系统)都接受由形式语言的形式 描述构成的输入语言。系统随后将这种描述翻译成某种编程语言源代码(如用C编写的)。 在几乎所有情形中,形式描述是与源代码段分散的,其中系统将把该源代码段复制到所生 成的源代码中。这种分散的代码意图在从形式描述生成的代码运行的同时执行一些行为。
考虑下面的代码段 ASM—param :char—string' (' expression')'
{ tree constraint—list = make—node(TREE—LIST); TREE_VALUE(constraint—list) = $1 ; $$ = make_node(TREE_LIST); TREE—PURPOSE($$) = constraint—list ; TREE—VALUE ($$) = $3 ; } I /女epsilon女/ {$$ = NULL_TREE ;} ; 在大括号{}中包含的行是C代码,其被系统复制而无任何检查。任何在此引入的 错误仅当编译器104之后在生成的分析器的环境下翻译这些行时才可能被发现,或者,它 们仍然不被检测出。 若没有这些分散代码,则生成的程序将仅能报告向其呈现的某个输入在形式描 述方面是否正确。例如,如果形式描述是编程语言PL8,则没有分散代码的所生成的编译器 仅能辨别文本是否为有效的PL8程序。然而,为了还触发机器代码的生成,分散代码是必要 的。这几乎适用于所有编译器生成器的应用,且所有这种系统都支持该分散代码的使用。
但是,C代码不是被逐字复制的,作为复制步骤的一部分,名称为以美元符号$开 头的伪变量被编译器生成器替换。这些变量在编译器生成环境中被命名为"属性",其非常 重要。它们用于累积在分析输入数据(这里指的是PL8程序源代码)时确定的值,还用于 在不同句法规则之间传递这些值。所有编译器生成器都有用于属性的某种表示法,然而,由 $符号打头的名称的使用对生成器如yacc、 bison和它们的派生来说都是专用的。因为属 性在操作中就像常规变量一样被涉及,所以,需要有与这些属性相关联的数据类型。不幸的 是,正确性检查由于以下几个原因而困难。第一,系统检查句法规则和相关声明。然而,系 统并不理解如何检查分散代码。由于分散代码是C代码的片段,所以,由于它们尚未出现在 它们的最终上下文中,在生成步骤中不能检查分散代码。另外,系统不检查在分散代码内的 属性的使用是否正确。而且,之后翻译由编译器生成器生成的源代码的编译器104并不能 访问或理解在输入描述中发现的句法规则和属性。 另外,分析器生成器108通常为属性创建某种实现。假定通常使用堆栈来管理递 归句法规则的属性,则生成器经常用这样的方式实现属性值所有堆栈条目只需一个大小,而与可能的属性值和属性数据类型无关。在yacc和bison的情况下,例如,所有属性类型 被概括为C联合类型。这避免了编译器的任何类型检查。 本发明的实施例可以解决这些问题的一些或全部,并支持分散代码的类型检查, 包括对属性的正确性检查。 所述技术状态的缺点涉及几个重要领域,如使用编译器生成器的开发者的生产 率、编译器生成器所需要的执行时间、所生成的代码的效率、以及(最后强调的)最终产品 的可靠性。问题是编译器生成器不能检查分散代码。另外,很多应用程序需要将所谓的 "数据属性"与形式描述的一些元素相关联。这些数据属性被分配值,并由分散代码读取。 当前的编译器生成器不能在此做任何检查。尤其是,不能对属性作类型检查。另外,编译器 生成器不能检查分散代码本身,也不能检查它与属性之间的相互作用。 开发者在编写分散代码、尤其是使用属性在不同规则之间传递值时可能产生的一 些错误仍然未被检测出,于是产生有错误的代码。注意到,这类问题会在实际中出现。当编 译器对编译器生成器的输出进行编译时,一些其他类型的问题会被检测出。在这种情形下, 编译器的错误消息与编译器生成器的输出相关,且其需要被映射回到在编译器生成器的输 入中发现的源代码行。这需要附加的工作量。如果映射不精确地完成,则可能会耗费大量 的工作用于定位输入文件中的错误。由于必须先运行编译器生成器、然后再次编译所生成 的代码,所以,修正这样的缺陷可能很耗时。对于在Li皿x和GCC中的现有技术的状态的组 合,情况更糟糕,这是因为,典型的安装涉及不仅仅一个编译器和一个编译器生成器,而是 至少两个不同的彼此交互的编译器生成器(一个扫描器生成器,其处理正则表达式;以及 一个分析器生成器,其处理LALR(l)语法),并与编译器交互。更糟糕的是,一些错误仍然完 全不被检测出,并被带入到最终产品中。 图2显示了用于实现这里的教导的计算系统200的实施例。在这个实施例中,系 统200具有一个或多个中央处理单元(处理器)201a、201b、201c等(共同地或一般地被称 为处理器201)。在一个实施例中,每个处理器201可包括精简指令集计算机(RISC)微处 理器。处理器201通过系统总线213与系统存储器214和各种其他部件相连接。只读存储 器(ROM) 202连接到总线213,并可包括基本输入/输出系统(BIOS),其控制系统200的某 些基本功能。 所述系统也可包括连接到系统总线213的输入/输出(I/O)适配器207和网络适 配器206。 1/0适配器207可以是小型计算机系统接口 (SCSI)适配器,其与硬盘203和/ 或磁带存储驱动器205或任何其他类似的部件通信。I/O适配器207、硬盘203和磁带存储 驱动器205在此共同被称为大容量存储器204。在一个实施例中,大容量存储器可以包括数 据库,或者以数据库的形式实现,该数据库用于存储企业架构信息。网络适配器206将总线 213与外部网络216相互连接,使得数据处理系统200可以与其他这类系统通信。屏幕(例 如,显示监视器)215通过显示适配器212与系统总线213相连接,显示适配器212可以包 括用于提高图形密集应用程序和视频控制器的性能的图形适配器。在一个实施例中,适配 器207、206和212可以与一个或多个I/O总线相连,所述I/O总线通过中间总线桥(没有 显示)与系统总线213相连接。用于连接诸如硬盘控制器、网络适配器和图形适配器等的 外围设备的适当的I/0总线通常包括公共协议,如外围部件接口 (PCI)。另外的输入/输 出设备被显示为通过用户接口适配器208和显示适配器212连接到系统总线213。键盘209、鼠标210和扬声器211都通过用户接口适配器208与总线213相互连接,例如,用户接 口适配器208可以包括将多个设备适配器集成到单个集成电路中的超级I/O芯片。
因此,如图2中所配置的,系统200包括处理器201形式的处理部件;包括系统存 储器214和大容量存储器204的存储部件;诸如键盘209和鼠标210的输入部件;以及包括 扬声器211与显示器215的输出部件。在一个实施例中,系统存储器214和大容量存储器 204的一部分共同存储操作系统,如IBM公司的AIX敷作系统,用于协调图2所示的各种部 件的功能。 将理解,系统200可以是任何适合的计算机或计算平台,并可包括终端、无线装 置、信息设备、装置、工作站、微型计算机、大型计算机、个人数字助理(PDA)或其他计算设 备。可以被系统200支持的操作系统示例包括Windows 95、 Windows 98、 Windows NT 4.0、 Windows XP、 Windows 2000、 Windows CE、 Windows Vista、Macintosh、Java、 LINUX禾口 UNIX,或其他任何合适的操作系统。当然,上面列的操作系统可以在虚拟化环境中执行。
系统200也包括网络接口,用于在网络上通信。该网络可以是局域网(LAN)、城域 网(MAN)或广域网(WAN),例如因特网或万维网。 系统200的用户可以通过任何合适的网络适配器206连接到网络216,例如标准 电话线、数字用户线、LAN或WAN链路(如T1、T3)、宽带连接(帧中继,ATM)、以及无线连接 (如802. 11 (a) ,802. ll(b),802. ll(g))。 正如在此揭示的,系统200包括存储在机器可读介质(如硬盘204)上的机器可读 指令,用于捕获和交互显示在用户的屏幕215上显示的信息。正如在此讨论的,所述指令被 称为"软件"220。可以使用在现有技术中所知的软件开发工具生成软件220。软件220可 以包括不同的工具和特征,用于提供现有技术中所知的用户交互功能。 如上讨论的,存在很多与当前编译器生成器相关的问题。本发明的实施例涉及能 改善编译器生成器中的信息流的新的系统和方法。特别地,本发明的实施例可以利用包含 完整信息的一个公共内部表示(IR)。现有技术的分析器和扫描器生成器的输入文件被翻译 成单个IR。在一个实施例中,IR可以包括有关句法规则、属性和属性数据类型的信息、分散 C代码及其属性使用。这样可以允许在句法规则和分散C代码之间的接口上的有效检查。 在一个实施例中,可从IR生成可执行编译器。 或者说,本发明的实施例可以围绕包含所有相关信息的一个公共内部表示规划所 有处理步骤。这与现有技术的一个不同点在于现有技术包括几个步骤,这些步骤都有它们 自己的内部表示。并且,那些内部表示都没有包含完整信息,因此没有步骤可以执行完整的 错误检查。 根据本发明的一个实施例的输入描述是一种新类型的输入语言,其由编程语言 (如C)中出现的所有元素、加上实现描述形式语言所需的规则的一些附加结构而组成。这 些附加结构被完全集成到编程语言中。实现本发明的工具也可以比现有技术状态的编译器 生成器更有效率,这是因为,中间文本表示被省略了。 应该理解,尽管在此示例中使用了编程语言C,但本发明的讲解可以适用于任何编 程语言。例如,讲解可以适用于C++, Ada和Java编程语言。 图3显示了根据本发明实施例的编译器生成器300的数据流图。输入由统一 的输入描述302组成,统一的输入描述302包括句法规则和它们的分散代码。在一个实施例中, 句法规则将包括正则表达式和上下文无关语法。相应地,输入描述302可以采用现有技术 的扫描器与分析器生成器输入文件的联合版本的形式。选择性地,输入也可以由其他源代 码304以及不需要形式语言描述的库组成。由作为本发明实施例的实现的编译器生成器/ 编译器306处理所述输入。如果所述输入是正确的,则编译器生成器/编译器306生成可 执行代码310。否则,生成器/编译器306产生适当的错误消息308。 图4显示了图3所示系统的更详尽的版本。特别地,图4包含了图3所示的编译 器生成器/编译器306的更详尽版本。编译器生成器/编译器306包括合适的编译器前端 402,用于读取统一的输入描述302,并将其翻译成公共内部表示404。在一个实施例中,这 个编译器前端可以由编译器的一部分形成,其包括扫描和分析算法或者子例程,其可以被 称为扫描和分析模块。作为这个翻译处理的一部分,也检查输入,以满足在形式上必须如何 编写句法规则以及分散代码的规则。任何违犯都会作为适当的IR生成错误消息406被报 告。例如,缺少")"会在这个步骤中被检测到。 内部表示404是表示在输入文件302中出现的所有相关信息的数据结构。简而言 之,存储在内部表示中的信息是用于编写分散代码的语言的编译器将存储的内容、以及根 据现有技术的扫描器和分析器生成器将存储的内容的超集(superset)。更精确地说,内部 表示404可反映用于输入的形式语言部分的描述的结构,例如,正则表达式包含什么元素、 哪些部分以哪个因子重复、哪些部分相互替换,等等。内部表示404也可以存储有关在语法 规则中使用的每个属性的信息。内部表示404也可以包含程序语言中出现的声明等。这些 使用现有技术的某种状态来表示,如,静态单个分配形式的某些变体。 正则表达式检查器408检查公共内部表示404的正则表达式部分是否正确。任何 违犯都会作为正则表达式错误410被报告。例如,合法范围之外的迭代因子在这个步骤中 会被检测出。 上下文无关表达式检查器412检查上下文无关部分或内部表示404是否正确。任 何违犯都会作为错误信息414被报告。例如,如果应用的语法类是LL(l),则任何对LL(l) 条件的违犯在这个步骤中会被检测出。 代码检查器416检查分散代码和属性使用的正确性。代码检查器使用存储在内部 表示404中的信息。任何违犯都会作为适当的错误消息418被报告。对于属性,代码检查 器416提供全类型检查,这是因为它通常对于编译器实现的语言而被执行。对于分散代码, 代码检查器416执行相应语言的编译器会执行的所有检查。只有由于内部表示404提供所 有必须的信息,这种检查才是可能的。特别地,分散C代码(或依赖于编程语言的其它代码 类型)出现在包含所有声明的环境中,即,在可以检查正确性的上下文中。此外,在输入的 形式语言部分中使用的所有属性现在出现在允许执行类型检查的上下文中。
在一个实施例中,内部表示404随后被用作现有技术状态下的代码优化和代码生 成模块420的输入,从而产生可执行代码422。 在此使用的术语仅仅是为了描述特殊的实施例,不是为了限制本发明。正如在此 所使用,单数形式"一""一个"和"该"意指也包括复数形式,除非上下文明确相反地表示。 可以进一步了解,在本说明书中使用的术语"包含"和/或"组成",指定了所述特征、整体 (integer)、步骤、操作、元素和/或部件的存在,但并不排除一个或多个其他特征、整体、步
9骤、操作、元素、部件和/或其组合的存在。 相应的结构、材料、行为和所有方法或步骤的对等物,加上以下声明中的功能元 素,意指包括任何结构、材料,或行为,该行为用于执行与明确声明的其他被声明元素相结 合的功能。本发明的说明书已经用于说明和描述的目的,但并非穷举性的、或限于所披露的 形式的本发明。对于本领域普通技术人员来说,在不脱离本发明的精神和范围的情况下,很 多修改和变化是显而易见的。选择和描述本实施例是为了更好地解释本发明和实际应用的 概念,并使本领域的其他普通技术人员能理解本发明,因为做不同修改的不同实施例适用 于预期的特定用途。 在此描绘的流图只是一个例子。在不脱离本发明精神和范围的情况下,对这个图 或步骤(或操作)可以有很多变更。例如,可以用不同的顺序执行步骤,或者步骤可以被添 加、删除或修改。所有这些变更都作为本发明所声明的一部分。 虽然本发明优选的实施例已经被描述,但应该理解,不管现在或将来,本领域技术 人员都可以在后面声明的范围内进行不同的改进和增强。权利要求应该被理解为保持对首 次描述的本发明的适当保护。
权利要求
一种系统,包括扫描和分析模块,用于接收统一的输入描述,所述统一的输入描述包含用于正则表达式和上下文无关表达式两者的句法规则、以及分散代码,该扫描和分析模块被配置用于将所述统一的输入描述翻译成公共内部表示;与该扫描和分析模块连接的正则表达式检查器,其被配置用于检查在公共内部表示中的正则表达式;与该正则表达式检查器连接的上下文无关表达式检查器,其被配置用于检查在公共内部表示中的上下文无关表达式;与该上下文无关表达式检查器连接的代码检查器,其被配置用于检查所述分散代码;以及与该代码检查器连接的代码优化器和代码生成器。
2. 如权利要求1所述的系统,其中,该正则表达式检查器和该上下文无关表达式检查 器被连接在该扫描和分析模块以及该代码优化器和代码生成器之间。
3. 如权利要求1所述的系统,其中,该正则表达式检查器和该上下文无关表达式检查 器都被配置用于在检测到错误的情况下,创建错误消息。
4. 如权利要求3所述的系统,其中,该扫描和分析模块以及用于检查所述分散代码的 代码检查器都被配置用于在检测到错误的情况下,创建错误消息。
5. 如权利要求1所述的系统,其中,该代码优化器和代码生成器被配置用于创建可执 行的编译器程序。
6. —种方法,包括接收统一的输入描述,所述统一的输入描述包含用于正则表达式和上下文无关表达式 两者的句法规则、以及分散代码;从所述统一的输入描述生成公共内部表示; 检查在公共内部表示中的正则表达式; 检查在公共内部表示中的上下文无关表达式; 检查所述分散代码;以及基于所述统一的输入描述,输出可执行程序,该可执行程序作为编译器操作。
7. 如权利要求6所述的方法,还包含 在不存在错误消息的情况下,优化所述公共内部表示。
8. 如权利要求6所述的方法,还包含在检测到正则表达式错误的情况下,生成正则表达式的错误消息;以及 在检测到上下文无关表达式错误的情况下,生成上下文无关错误消息。
9. 一种系统,包括扫描和分析模块,用于接收统一的输入描述,所述统一的输入描述包含用于正则表达 式和上下文无关表达式两者的句法规则、以及分散代码,该扫描和分析模块被配置用于将 所述统一的输入描述翻译成公共内部表示;与该扫描和分析模块连接的表达式检查器,其被配置用于检查在公共内部表示中的表 达式;与该表达式检查器连接的代码检查器,其被配置用于检查所述分散代码;以及与该代码检查器连接的代码优化器和代码生成器。
10. 如权利要求9所述的系统,其中,该表达式检查器是正则表达式检查器,其被配置 用于检查正则表达式。
11. 如权利要求9所述的系统,其中,该表达式检查器是上下文无关表达式检查器,其 被配置用于检查上下文无关表达式。
12. 如权利要求9所述的系统,其中,该表达式检查器包括被配置用于检查上下文无 关表达式的上下文无关表达式检查器、以及被配置用于检查正则表达式的正则表达式检查 器。
13. 如权利要求12所述的系统,其中,该正则表达式检查器和该上下文无关表达式检查器都被配置用于在检测到错误的情况下,创建错误消息。
全文摘要
公开了编译器生成系统和方法,该系统包括输入编译器,用于接收统一的输入描述,该输入描述包含正则和上下文无关表达式的句法规则、以及分散代码,第一编译器被配置用于将统一的输入描述翻译成公共内部表示。所述系统还包括正则表达式检查器、上下文无关表达式检查器、代码检查器和与代码检查器相连接的第二编译器。
文档编号G06F9/45GK101751281SQ20091022207
公开日2010年6月23日 申请日期2009年11月13日 优先权日2008年12月10日
发明者安德烈亚斯·克雷贝尔, 沃尔夫冈·盖勒里克 申请人:国际商业机器公司