> 教育经验 > 什么是编译器生成器介绍

什么是编译器生成器介绍

什么是编译器生成器介绍

所谓编译器生成器即对于一段给定的单词正则表达式,自动构造一个能进行词法分析的词法分析器;对于一段给定的文法,自动构造一个能进行语法分析的语法分析器:能自动加上必要的语义分析,并能给出面向用户的语义程序接口的程序。

编译器生成器定义

信息时代到来的今天,计算机网络以资源共享、数据通信特性,已日益渗透到了人们生活的许多领域,所以保持网络的良好可靠性和较高的效率是至关重要的,这就出现了网络管理。网络管理是对组成网络的资源和设备的规划、设计、控制,使网络具有最高的效率和生产力,从而为用户提供高效的服务。

所谓编译器生成器即对于一段给定的单词正则表达式,自动构造一个能进行词法分析的词法分析器;对于一段给定的文法,自动构造一个能进行语法分析的语法分析器:能自动加上必要的语义分析,并能给出面向用户的语义程序接口的程序。

编译器生成器多是单个分开的,即它是单个的词法分析器生成器,或者单个的语法分析器生成器,语义分析器生成器还只能完成抽象语义分析。集编译器各个阶段为一体的编译器生成器还要需要进一步的研究。

编译器生成器重要性

编译器的自动生成器能够针对一种新型的处理器体系结构,产生相应的优化编译器。编译器的自动生成器于是构成了可重构软件中的重要一环。对于一种新型的硬件结构,它的汇编指令系统和机器资源是特定的,应该提供给设计人员一个配置接口,使他们能够方便的定义这些特定资源来描述和指定一种特定的硬件结构,利用自动生成器生成面向于这种机器的编译器,实现可重定目标。

编译器生成器发展历史

编译,代表从面向人的源语言表示的算法到面向硬件的目标语言表示的算法的一个等价变换。通常情况下,人们将能够完成一种语言到另一种语言变换的软件称为“翻译器”,而编译器就是其中的一类。

编译器是程序员将命令翻译成可以在计算机上执行的代码的软件开发工具。编译器的工作可以分成若干阶段,每个阶段把源程序从一种表达形式变换成另一种表达形式。编译程序的典型工作流程为:词法分析、语法分析、语义分析、转换、规范化、程序码选择、控制流分析、数据流分析、寄存器分配、代码生成、汇编和联结器。在前端编译技术中,词法分析、语法分析、语义分析被作为讨论的重点,而在所有的前端技术中,最具研究价值的就是语法分析。

1975年Lesk第一次提出基于正则表达式的词法分析器概念。1986年Ahoet al,提出了更有效计算若闭包和压缩DFA状态矩阵豹方法。1988年Gray建立了行词法分析方法。993年Bumbulis和Cowan提出了单遍遍历DFA状态就能够完成词法分析的算法。而词法分析器生成器的工作要晚得多,1995年,Paxson开发出第一个词法分析器生成器Flex。

1963年Conway描述了基于FIRST集合的语法分析器。1968年Lewis和Steams第一次提出了LL(k)文法理论。1965年Knuth提出LR(k)理论,SLR和LALR理论则是由DeRemer在1971年提出。

1975年,第一个语法分析器生成器YACC问世。1987年,Burke和Fisher提出了错误回溯问题。1996年,JavaCup问世,它是第一个基于Java的编译器生成器。

在国内,研究编译器实现的比较少。在1998年进行“九五”国家重点科技攻关项目中,由中国科学院进行了有关Java编译器的研究。而编译器生成器方面,则刚刚开始进一步的研究。

编译器生成器相关技术

编译器生成器的工作就是在前端,需要将用户对新语言的词法、语法、语义信息的直观描述(形式文法)转换成分析程序的内部处理形式;在后端,需要将用户对新机器物理特性到逻辑特性映射的直观描述转换成生成程序使用的数据和算法。

编译器前端包括词法分析和语法分析语义分析,生成中间代码,它主要依赖于源语言,和目标机体系结构无关。所以该部分可以作为构件完全重用。编译器后端包括代码优化部分、代码选择,代码生成、寄存器分配等。后端是编译器中与目标机相关的部分。一般来说,这些部分独立于源语言,而仅仅依赖于中间表示和目标机器。

分层

自动生成器的分层如下图1所示。

结构

编译程序生成器的一般结构是如下图2。

实际上,这种程序自动生成结构是将问题求解的表示与操作分离。生成器将元语言表示的信息转换成驱动程序直接访问的数据结构,多数情况下这些数据结构以程序形式存放,然后经编译与驱动程序链接,尽管这样会比直接生成表低效,但允许用户修改所生成的内容,以调整驱动程序的输入。

词法分析程序自动生成

词法分析程序生成器的结构如下图3所示。生成词法分析程序的过程类似于编译过程本身,它使用的是如下方法:将一个文法的正则表达式转化为一个NFA,再转化为一个DFA,最后用DFA化简的方法将该DFA简化。

语法分析程序的自动生成

语法分析程序生成器的结构如下图4所示。上下文无关文法用BNF或EBNF表示,生成的表既可以是LL语法分析表,也可以是LR语法分析表。

语义分析程序生成器

语义分析程序生成器的结构如下图5所示。

属性文法起源于语法制导翻译技术,1968年Knuth对属性文法做了规范化说明。一个

属性文法是在BNF上附加属性(如数据结构、值、机器码等)和语义函数(定义如何给属性赋值)。LL语法分析适于L—属性文法(用继承属性),LR语法分析适于S—属性文法(用合成属性)。

元语言包括属性文法的翻译工具出现于七十年代末到八十年代初,如GAG(Kastens等,1982)、HLP(Rai等,1978)、VATS(Berg等,1984)和MUG-2(Ganapathi等,1982)都是基于属性文法的描述。

后端技术

后端接受中间表示,生成等价的目标代码。一般过程为:

1、)中间代码优化

优化的最终目的是:使用户充分利用一个语言的特色来描述他/她的算法,而不必关心实现的效率,即不能要求编程者写出精巧、高效的代码。他们应关心程序的可读性和可维性。

优化应针对那些最常被执行的代码段,以及那些最常被书写的代码段来进行。优化既企图缩短代码执行的时间,又企图减少生成的代码量,通常是在两者之间折衷。最根本的原则是:对中间代码是等语义的变换。如果程序不被运行多次,或其生成代码的时/空效率不是很重要,则不必优化。有很多优化策略,多数系统只是因具体要求选择若干种优化算法。

使用流图描述所有可能的执行路径。控制流分析使数据流分析简单。控制流分析分两步:首先划分基本块,然后建立流图。数据流分析提供数据项的定义和使用方面的信息,既有助于优化,又有助于调试,作用主要有:提供一个数据项被定义之前被使用的路径:检测冗余或无用代码。数据流分析也检测循环不变式和己被计算出的表达式等信息。

2、)代码生成

代码生成包括两部分:寄存器分配、代码选择。最简单的代码生成可以仅是代码选择,即:将中间表示转换为汇编代码。现代编译系统追求代码生成程序的自动生成。寄存器分配和代码选择是“鸡生蛋—蛋生鸡”问题。好的寄存器分配算法可以极大地提高生成代码的执行速度,因此可以被划为优化处理。

3、)目标代码优化

对生成代码的优化策略有:前面介绍的各种对中间表示的优化、寄存器优化和窥孔优化。窥孔优化(peephole optimization):检查一小段生成代码,用更快更短的序列代替它。被检查的指令短序列被称为窥孔。它的一般步骤为:

①消除不必要的取数,

②消除不可达代码,

③消除间接跳转,

④算术处理,

⑤识别特殊指令或模式。