1、第二章 高级语言及其语法描述,第二章 高级语言及其语法描述,本章概述高级语言的结构和主要的共同特征,并介绍程序语言的语法描述方法。要学习和构造编译程序,理解和定义高级语言是必不可少的。 2.1 程序语言的定义 任何语言实现的基础是语言的定义。在定义方面,编译程序研制者与一般用户有所不同,他们对那些构造允许出现更感兴趣。即使一时不能看出某种构造的实际应用,或者判断实现该结构会导致严重的困难,但仍必须严格根据语言的定义实现它。 程序语言主要由语法和语义两方面定义。,第二章 高级语言及其语法描述,2.1.1 语法:任何语言程序都可以看成是一定字符集(称为字母表)上的字符串(有限序列)。但是什么样的字
2、符串才算是一个合适的程序呢?所谓一个语言的语法是指这样的一组规则,用它可以形成和产生一个合适的程序。这些规则一部分称为词法规则,另一部分能称为语法规则(或产生规则)。,第二章 高级语言及其语法描述,注意这里提到三个概念:a.一个程序只是用一个有限字符集作为字母表;b.词法规则是指单词符号的形成规则。单词符号一般包括:各类型的常数、标识符、基本字、算符和界符等。C.语言的语法规则规定了如何从单词符号形成更大的结构(即语法单位),换言之,语法规则是语法单位的形成规则。一般程序语言的语法单位有:表达式、语句、分程序、函数、过程和程序等。,第二章 高级语言及其语法描述,2.1.2 语义: 对于一个语言
3、来说,不仅要给出它的词法、语法规则,而且要定义它的单词符号和语法单位的意义。这就是语义问题。 语义是指这样的一组规则,使用它可以定义一个程序的意义。 我们采用的方法为:基于属性文法的语法制导翻译方法。,第二章 高级语言及其语法描述,一个程序语言的基本功能是描述数据和对数据的运算。所谓程序,从本质上来说是描述一定数据的处理过程。在现今的程序语言中,一个程序大体可以视为下面所示的层次结构,程序,子程序,或,分程序,语句,表达式,数据引用,算符,函数调用,第二章 高级语言及其语法描述,自上而下看上述层次结构:顶端是程序本身,他是一个完整的执行单位。一个程序通常是由若干个子程序或分程序组成的,他们常常
4、含有自己的数据(局部名)。子程序或分程序是由于语句组成的。而组成语句的成分是个种类型的表达式。表达式是描述数据运算的基本结构,它通常含有数据引用、算符和函数调用。,第二章 高级语言及其语法描述,自下而上看上述层次结构:我们希望通过对下层成分的了解掌握上层成分,从而掌握整个程序。 在学习编译原理的过程中特别注意:程序语言的每个组成成分都有(抽象的)逻辑和计算机实现两方面的意义。当从数学上考虑每一个组成成分时,我们注重它的逻辑意义,当从计算机这个角度来看时,我们注重他在机内的表示和实现的可能性与效率。,第二章 高级语言及其语法描述,2.2 高级语言的一般特性2.2.1 高级语言的分类; a.强制式
5、语言过程式语言(命令驱动、面向语句,如PASCAL C等) b.应用式语言函数式语言( 如LISP) c.基于规则的语言 -逻辑型设计语言(如PROLOG) d.面向对象语言 -支持封装、多态、继承 2.2.2 几种程序的典型结构;,第二章 高级语言及其语法描述,FORTRAN MAINEND SUBROUTINE SUB1 END SUBROUTINE SUBn END,一. FORTRAN 一个FORTRAN 程序有一个主程序段和若干个(可以是0个)辅助程序段组成。(如右侧),第二章 高级语言及其语法描述,辅助程序段可以是子程序、函数段或数据。每程序段由一系列说明语句和执行语句组成。各程序
6、段可以独立编辑。这对模块设计甚为方便。 一个FORTRAN 程序个程序段所定义的各种名字通常是彼此独立的。同一个标识符在不同的程序段中一般都可以代表不同的名字,即代表不同的存储单元,个程序段对它们的引用或赋值是彼此无关的。但是,不同程序段里的同名公用块(Common Block)却代表同一个存储区域。因此,出现在COMMON语句中的名字所代表的单元在其他程序块中也可以引用。所以说,公用区具有全局性。不出现在COMMON中的名字所代表的单元具有局部性。,第二章 高级语言及其语法描述,二. Pascal Pascal 是一个允许子程序嵌套定义的语言。一个Pascal程序可以看作是操作系统调用的一个
7、子程序,而子程序中又可以定义别的子程序。,program main procedure P1; procedure P11; begin end; begin end; procedure P2; begin end; begin end .,第二章 高级语言及其语法描述,Pascal这种嵌套结构中允许同一标识符在不同的子程序段中表示不同的名字。关于名字的作用域的规定是: a.一个在子程序B1中说明的名字X只在B1中有效(局部于B1)。 b.如果B2是B1的一个内层子程序,且B2中对标识符X没有新的说明,则原来的名字X在B2中仍然有效。如果B2对X重新作了说明,那么,B2中对X的任何引用都是指
8、重新说明过的这个X。,第二章 高级语言及其语法描述,2.2.3 数据类型与操作; 一个数据类型通常包括以下三种要素: a.用于区别这种类型的数据对象的属性 b.这种类型的数据对象可以具有的值 c.可以作用于这种类型数据对象的操作 一、初等数据类型 常见的初等数据类型有: a.数值数据 b.逻辑数据 c.字符数据 d.指针类型,第二章 高级语言及其语法描述,指针是指这样一种类型的数据,他们的值指向另一些数据。一般意义是,假定P是一个指针,P: = addr(X) 意味着P将指向X,或说P的值将是变量X的地址。有些语言用P表示指针P的内容。在P:=addr(X)的情况下,如令P:= 0.3,则意味
9、着X的值是0.3,第二章 高级语言及其语法描述,用计算机术语来说,名字可以看成是代表一个抽象的存储单元,这个单元可包含一位、一字节、一字或相继的许多个字。而这个单元的内容则认为是此名字的值。名字的值就是它所表示的对象。此外,我们还必须指出名字的属性。 一个名字的属性包括类型和作用域。名字的类型决定了它能具有什么样的值,值在计算机内的表示方式,以及对他能施加什么运算。名字的作用域规定了他的值存在范围。,第二章 高级语言及其语法描述,二、数据结构 许多程序语言提供了一种由初级数据定义复杂数据的手段。下面我们将概述其中常见的定义方式: a. 数组 从逻辑上说,一个数组是由同一类型数据所组成的某种n维
10、矩形结构。沿着每一维的距离称为一个下标。数组的每个元素是矩形结构中的一个点,它的位置可通过给出每维的下标来确定。,第二章 高级语言及其语法描述,数组的每个元素 (也称为下标变量)是由数组名连同各维的下标值命名的。如A(i1,i2,in) 。根据数组的类型,每个数组元素在计算机中占有同样大小的存储空间。如果一个数组所需的存储空间大小在编译时就已知道则称此数组是一个确定数组;否则称为可变数组。,第二章 高级语言及其语法描述,数组的存储表示有多种形式,最简单的一种是把整个数组按行(或按列)存放在一片连续存储区中。 数组元素的地址计算和数组的存储方式密切相关。关于数组元素的地址计算公式,数据结构教材中
11、有详细的介绍。编译程序要做的就是实现地址计算公式,使数组元素得到正确的引用。 在编译过程中,当碰到数组说明时,必须把数组的有关的信息记录在一个“内情向量”之中,以便以后计算数组元素的地址时引用这些信息。每个数组的内情向量必须包括:维数,各维的上下限,首地址,以及数组元素的类型等。,第二章 高级语言及其语法描述,b.记录 从逻辑上说,记录结构是由已知类型的数据组合起来的一种结构。 记录结构是许多程序语言的一类重要的数据结构。不同语言定义记录结构的方式也不同。如:Pascal语言采用下面形式定义记录:CARD: record NAME: array120 of char; AGE:integer;
12、 MARRIED:boolean end;,第二章 高级语言及其语法描述,这说明定义了一个记录CARD.它是一个含有三个分量的记录结构:NAME,字符数组;AGE,整型量;MARRIED,布尔量。 记录结构的每个分量(域)所需占用的存储单元(字节)数,成为该域的长度。当知道一个记录的地址后,通过每个域的长度就可算出个域的地址,因为我们容易推出每个域相对于记录结构起点的相对数OFFSET:此域之前各域长度的总和。,第二章 高级语言及其语法描述,如: 就CARD而言,NAME,AGE,MARRIED 的相对数OFFSET分别为0、20、24。于是,假定CARD的首地址为a,那么, CARD.NAM
13、E 地址为 a CARD.AGE 地址为 a+20 CARD.MARRIED 地址为 a+24,第二章 高级语言及其语法描述,2.2.4 语句与控制结构一、表达式:一个表达式是由运算量(亦称操作数,即数据引用或函数调用)和算符组成的。 对于大多数程序语言来说,表达式的形成规则可概括为:(1)变量(包括下标变量)、常数是表达式;(2)若E1、E2为表达式,为二元算符,则 E1 E2为表达式;(3)若E为表达式, 为一元算符,则E为表达式;(4)若E为表达式,则(E)是表达式。,第二章 高级语言及其语法描述,在多数语言中算术算符和逻辑算符的优先顺序一般规定如下:乘幂 ( * 或 )一元负 ( -
14、)乘、除 ( * , /, )加、减 ( + , - )关系符 ( , , = ) 非 ( , not, 或 .NOT. )与 (, &, and 或 .AND. )或 ( , or 或 .OR . )隐含 ( 或 imp )等值 ( , 或 equi ),第二章 高级语言及其语法描述,算符的代数性质(交换率、结合率和分配率)常常可用来优化目标程序的质量。但是必须注意两点: (1) 代数性质引用到什么程度视具体语言的不同而不同。如在ALGOL中把 A*B+C*D 处理成C*D+A*B, 则至少是对ALGOL不够忠实。 (2)数学上成立的代数性质在计算机上未必完全成立。如:(A+B)+C=A+(
15、B+C)在计算机上并不普遍成立。,第二章 高级语言及其语法描述,二、语句 不同程序语言含有不同形式和功能的各种语句。从功能上说语句大体可分执行性语句和说明性语句两大类,说明性语句旨在定义不同数据类型的变量或运算。执行性语句旨在描述程序的动作。执行性语句又可分赋值语句、控制语句和输入/输出语句.从形式上说,语句还可分为简单句、复合句和分程序等。,第二章 高级语言及其语法描述,1、赋值语句 我们知道,每个名字有两方面的特征:一方面它代表一定的存储单元,另一方面它又以该单元的内容作为值。赋值语句A:=B的意义是:“把B的值送入A所代表的单元”也就是说:在赋值句中,赋值号:=左右两边的变量名扮演着两种
16、不同的角色。对赋值号右边的B我们需要的是它的值;对于左边的A我们需要的是它们的所代表的存储单元(的地址)。为了区分一个名字的这两种特征,我们把一个名字所代表的那个存储单元(地址)称为该名字的左值;把一个名字的值称为该名字的右值。,第二章 高级语言及其语法描述,2、控制语句多数语言中所含的控制语句有:无条件转移语句: goto L条件语句: if B then S if B then S1 else S2循环与句: while B do S repeat S until B for i:=E1 step E2 until E3 do S过程调用语句: call P( X1,X2,Xn)返回语句:
17、 return(E) 重要的是我们必须了解这些语句在不同语言中的不同含义。,第二章 高级语言及其语法描述,3、说明语句 说明语句旨在定义名字的性质。编译程序把这些性质登记在符号表中,并检查程序中名字的引用和说明是否相一致。许多说明语句没有相应的代码。但有些语句,如过程说明语句,和可变数组说明语句则有相应的目标代码。4、简单句和复合句 简单句是指那些不含其它语句成分的基本句,如赋值句、 goto句等。 复合句则指那些句中有句的语句。,第二章 高级语言及其语法描述,本节内容是对高级语言中为编译原理课程所关心特性的总结,第二章 高级语言及其语法描述,2.3 程序语言的语法描述 对于高级程序语言及编译
18、程序而言,语言的语法定义是非常重要的。本节将介绍语法结构的形式描述问题。首先引入几个概念: 设是一个有穷字母表,它的每个元素称为一个符号。 上的一个符号串是指由中的符号所构成的又穷序列。不包含符号的序列称为空字,记为。用*表示上的所有符号串的全体,空字也包括在其中。如:若=a,b则*=,a,b,aa,ab,bb,aaa,。表示不含任何元素的空集。这里要注意、和的区别。,第二章 高级语言及其语法描述,*的子集U和V中的(连接)积定义为: UV=U & V 即集合UV中的符号串是由U和V的符号串连接而成的。注意,一般UVVU,但(UV)W=U(VW).V自身的n次(连接)积记为: Vn = V V
19、V (n个V)规定 V0 = . 令: V* = V0V1V2 称 V*是V的闭包。记V+ = VV*, 称 V+是V的正则包。 闭包V*中的每个符号都是由V中的符号串经有限次连接而成的。,第二章 高级语言及其语法描述,2.3.1 上下文无关文法: 文法是描述语言的语法结构的形式规则(即语法规则)。 所谓上下文无关文法是这样一种文法,它所定义的语法范畴(或语法单位)是完全独立于这种范畴可能出现的环境的。 请仔细阅读课本P27页的英文分析的例句,定义英文句子的规则可以说是一个上下文无关文法。其中He, me, book, gave,a 等,称为终结符号;、等为非终结符号;这个文法最终是要定义的语
20、法结构,所以在这里成为开始符号; 这种书写形式称为产生式。,第二章 高级语言及其语法描述,归纳起来,一个上下文无关文法G包括四个组成部分:一组终结符号,一组非终结符,一个开始符号,以及一组产生式。所谓终结符号乃是组成语言的基本符号,即在程序语言中以前屡次提到的单词符号,如基本字,标识符,常数,算符和界符等所谓非终结符号(也称语法变量)用来代表语法范畴。如“算术表达式”、“布尔表达式”、“过程”等。一个非终结符代表一个一定的语法概念。因此非终结符是一个类(或集合)记号,而不是个体记号。,第二章 高级语言及其语法描述,开始符号是一个特殊的非终结符号,它代表所定义的语言中我们最感兴趣的语法范畴,这个
21、语法范畴通常称为“句子”。但在程序语言中我们最终感兴趣的是“程序”这个语法范畴,而其他的语法范畴都只不过是构造“程序”的一块块砖石。产生式(也称为产生规则或简称规则)是定义语法范畴的一种书写规则。一个产生式的形式是 A ,其中箭头左边的A是一个终结符,称为产生式的左部符号;箭头右边的是终结符号或与非终结符号组成的一符号串,称为产生式的右部。,第二章 高级语言及其语法描述,产生式是定义语法范畴的。如要定义一类含+、*的算术表达式,这个定义可以这样给出:“变量是一个算术表达式;若E1和E2是算术表达式,则E1+E2、E1*E2和(E1)也是算术表达式。 对于这个定义,用产生式描述: Ei ()其中
22、代表“算术表达式”,代表“变量”,第二章 高级语言及其语法描述,形式上定义一个上下文无关文法是一个 四元式(,)其中是一个非空有限集,它的每一个元素 称为终结符号;是一个非空有限集,它的每一个元素称为非终结符号,;是一个非终结符号,称为开始符号;是一个产生式(有限)集合,每个产生式形式是,其中, ()开始符号S至少必须在某一产生式的左部出现一次。,第二章 高级语言及其语法描述,假定G是一个文法,S是它的开始符号。如果S*(表示从S出发,经0步或若干步可推出),则称是一个句型。仅含终结符号的句型是一个句子。文法G所产生的句子的全体是一个语言,将它记为L(G). L(G)=|S + & VT 例如
23、:终结符号串(i*i+i)是文法 EE+E|E*E|(E)| (2.1) 的一个句子。是因为有 E(E)(E+E) (E*E+E) (i*E+E) (i*i+E) (i*i+i)从开始符号E至 (i*i+i)的一个推导。而E,(E),(E*E+E)等是文法的句型。,第二章 高级语言及其语法描述,下面介绍几个简单文法的例子: 例2.1考虑一个文法G1: SbA AaA|a 它定义了一个什么语言呢?从开始符S出发,我们可以推出如下句子: SbA ba SbA baA baa SbA baA baaa可以写为:L(G1)=ban|n1,第二章 高级语言及其语法描述,第二章 高级语言及其语法描述,为了
24、对句子结构进行确定性分析,我们往往只考虑最左推导或最右推导。所谓最左推导是指:任何一步都是对中的最左非终结符进行替换的。同样,可定义最右推导。,第二章 高级语言及其语法描述,2.3.2 语法分析树与二义性 前面我们提到过可以用一张图表示一个句型的推导,这种表示称为语法分析树,或简称语法树。 语法树的根结由开始符号所标记。随着推导的展开,当某个非终结符被它的某个候选式所替换时,这个非终结符的相应结就产生了下一代新结。每个新结和其父亲结间都有一条连线。在一棵语法树生长过程中的任何时刻,所有那些没有后代的端末结自左至右排列起来就是一个句型。,第二章 高级语言及其语法描述,例如对于文法(2.1)关于(
25、i*i+i)的推导形成语法树如图2.2,图 2.2 语法树,第二章 高级语言及其语法描述,一个句型是否只对应唯一的一棵语法树呢?也就是说它是否只有唯一的一个最左(最右)推导呢?不尽然。 如文法2.1,关于(i*i+i)就存在一个与2.2非常不同的推导: E(E) (E*E) (i*E) (i*E+E) (i*i+E) (i*i+i)其对应语法树:,第二章 高级语言及其语法描述,图2.2与图2.3的不同之处在于从第二代三代过渡开始。对于前者,我们选用规则EE+E,而后者我们选用EE*E。这里不是同代兄弟生儿子的先后次序的不同而是生什么儿子的不同,后面的这个不同是本质上的的差异。这意味着我们可以用
26、两种完全不同的办法产生同一个句子。,第二章 高级语言及其语法描述,如果一个文法存在某个句子对应两棵不同的语法树,则称这个文法是二义的。也就是说,若一个文法存在某个句子,它有两个不同的最左(最右)推导,则这个文法是法是二义的。 最后,作为描述程序语言的上下文无关文法,我们对它有几点限制。 (1)文法中不含任何下面形式的产生式: PP因为这种产生式除了产生二义性外没有任何用处。,第二章 高级语言及其语法描述,(2)每个非终结符P必须有用处。这一方面意味着,必须存在含P的句型;也就是,从开始符号出发,存在推导 S*P. 另一方面意味着,必须存在终结符串VT*,使得P+;也就是,对于P不存在永不终结的
27、回路。 我们以后所讨论的文法均假定满足上述两条件。,第二章 高级语言及其语法描述,2.3.3 形式语言鸟瞰: 乔姆斯基把文法分为四种类型即0型、1型、2型、3型。0行强于1型,1行强于2型,2型强于3型。这几文法的差别在于对产生式施加不同的限制。 我们说G=(VT ,VN ,S ,) 是一个0型文法,如果它的每个产生式 是这样的结构 (VNVT)* 且至少有一个非终结符,而(VNVT)* 。0型文法也称短语文法。,第二章 高级语言及其语法描述,如果对0型文法分别施加以下的第i条限制,则我们就得到第i型文法: (1)G的任何产生式 均满足 | |(其中|和|分别为和的长度;仅S例外,但S不得出现
28、在任何产生式的右部。 (2)G的任何产生式为A, AVN , (VN VT)* 。 (3) G的任何产生式为AB或 A,其中VT*,A、B VN 。 其中1型文法也称上下文有关文法。这种文法意味着,对非终结符进行替换式务必考虑上下文并且一般不允许替换成空串。,第二章 高级语言及其语法描述,2型文法也称上下文无关文法,注意其语言定义: G的任何产生式为A,AVN, (VNVT)*表明凡出现在产生式左边的符号都是非终结符。 3型文法也称右线性文法。3型文法还有另一种形式,称左线性文法:一个文法G为左线性文法,如果G的任何产生式为 AB 或A ,其中VT* , A、B VN 由于3型文法等价于正规式
29、所以也称正规文法。,第二章 高级语言及其语法描述,例题与习题解答,例2.1: 试构造生成语言L=anbnci|n1, i 0的文法 解:G(Z): ZAB A aAb|ab B cB|例2.2: 已知语言L=anbbn| n 1, 写出产生L的文法。,第二章 高级语言及其语法描述,解: GS: S aAb A aAb|b例2.3: 已知文法G=(A,B,C,a,b,c,A,P)其中产生式P由以下组成: A abc A aBbc Bb bB Bc Cbcc bC Cb aC aaB aC aa 问:此文法表式的语言是什么?,第二章 高级语言及其语法描述,解:由于A为开始符。 由于AaBbc abBc abCbcc aCbbcc aabbcc 语言为: anbncn, n0 例2.4:试构造语言L=anbnci | n=1, i=0的文法。 解: G(Z): Z AB A aAb|ab B cB|,第二章 高级语言及其语法描述,例2.5:试写一文法,使其描述的语言L(G) 是能被5整除的整数集合。 解: G(Z): Z (+|- )A(0|5) A 0|1|2|3|4|5|6|7|8|9|AA例2.6: 已知语言L=x | xa,b,c*,且x重复排列是对称的(aabcbaa,aabbaa,等) 写出该语言的文法。 解: G(Z): Z aZa|bZb|cZc|a|b|c|,