• 沒有找到結果。

r e a d和w r i t e开始。read 语句一次只读出一个变量,而 write 语句一次只写出一个表达式。

在文檔中 第1章 概 论 (頁 97-102)

程序清单3-1 BNF中的T I N Y的文法

T I N Y表达式有两类:在 if 语句和 repeat 语句的测试中使用比较算符 =和<的布尔表达式,

以及包括标准整型算符 +、-、*和/(它代表整型除法,有时也写作 d i v)的算术表达式(由文 法中的 s i m p l e - e x p指出)。算术运算是左结合并有通常的优先关系。相反地,比较运算却是非 结合的:每个没有括号的表达式只允许一种比较运算。比较运算比其他算术运算的优先权都 低。

第 3章 上下文无关文法及分析

9 7

下载

T I N Y中的标识符指的是简单整型变量,它没有诸如数组或记录构成的变量。 T I N Y中也没 有变量声明:它只是通过出现在赋值语句左边来隐式地声明一个变量。另外,它只有一个(全 局)作用域,且没有过程或函数(因此也就没有调用)。

还要注意 T I N Y的最后一个方面。语句序列必须包括将语句分隔开来的分号,且不能将分 号放在语句序列的最后一个语句之后。这是因为 T I N Y没有空语句(不同于 P a s c a l和C)。另外,

我们将s t m t - s e q u e n c e的B N F规则也写作一个左递归规则,但却并不真正在意语句序列的结合性,

这是因为意图很简单,只需按顺序执行就行了。因此,只要将 s t m t - s e q u e n c e编写成右递归即可。

这个观点也出现在 T I N Y程序的语法树结构中,其中的语法序列不是由树而是由列表表示的。

现在就转到这个结构的讨论上来。

3.7.2 TINY编译器的语法树结构

T I N Y有两种基本的结构类型:语句和表达式。语句共有 5类(i f语句、r e p e a t语句、a s s i g n 语句、 r e a d语句和 w r i t e语句),表达式共有 3类(算符表达式、常量表达式和标识符表达式)。

因此,语法树节点首先按照它是语句还是表达式来分类,接着根据语句或表达式的种类进行再 次分类。树节点最大可有 3个孩子的结构(仅在带有 e l s e部分的i f语句中才需要它们)。语句通 过同属域而不是使用子域来排序。

必须将树节点中的属性保留如下(除了前面所提到过的域之外):每一种表达式节点都需 要一个特殊的属性。常数节点需要它所代表的整型常数的域;标识符节点应包括了标识符名称 的域;而算符节点则需要包括了算符名称的域。语句节点通常不需要属性(除了它们的节点类 型之外)。但为了简便起见,在 a s s i g n语句和r e a d语句中,却要保留在语句节点本身中(除了作 为一个表达式子节点之外)被赋予或被读取的变量名。

前面所描述的三个节点结构可通过程序清单 3 - 2中的C说明得到,该说明还可在附录 B(第 1 9 8行到第2 1 7行)的g l o b a l s . h文件的列表中找到。请注意我们综合了这些说明来帮助节省空间。

它们还可帮助提醒每个节点类型的属性。现在谈谈说明中两个未曾提到过的属性。第 1个是簿 记属性l i n e n o;它允许在转换的以后步骤中出现错误时能够打印源代码行数。第 2个是t y p e域,

在后面的表达式(且仅是表达式)类型检查中会用到它。它被说明为枚举类型 E x p Ty p e,第6 章将会完整地讨论到它。

程序清单3-2 一个T I N Y语法树节点的C声明

9 8

编译原理及实践

下载

现在需要将语法树结构的描述用图形表示出来,并且画出示例程序的语法树。为了做到这 一点,我们使用矩形框表示语句节点,用圆形框或椭圆形框表示表达式节点。语句或表达式的 类型用框中的标记表示,额外的属性在括号中也列出来了。属性指针画在节点框的右边,而子 指针则画在框的下面。我们还在图中用三角形表示额外的非指定的树结构,其中用点线表示可 能出现也可能不出现的结构。语句序列由同属域连接(潜在的子树由点线和三角形表示)。则 该图如下:

if 语句(带有3个可能的孩子)如下所示:

repeat 语句有两个孩子。第 1个是表示循环体的语句序列,第 2个是一个测试表达式:

assign 语句有一个表示其值是被赋予的表达式的孩子(被赋予的变量名保存在语句节点中):

write 语句也有一个孩子,它表示要写出值的表达式:

第 3章 上下文无关文法及分析

9 9

下载

算符表达式有两个孩子,它们表示左操作数表达式和右操作数表达式:

其他所有的节点(r e a d语句、标识符表达式和常量表达式)都是叶子节点。

最后准备显示一个 T I N Y程序的树。程序清单 3 - 3中有来自第 1章计算一个整型阶乘的示例 程序,它的语法树在图3 - 6中。

图3-6 程序清单3 - 3中T I N Y程序的语法树 程序清单3-3 TINY语言中的示例程序

1 0 0

编译原理及实践

下载

练习

3.1 a. 写出一个生成串的集合

{ s ; , s ; s ; , s ; s ; s ; , . . . }

的非二义性的文法。

b. 利用你的文法为串s ; s ;给出一个最左推导和最右推导。

3.2 假设有文法A → A A | (A) a. 描述它生成的语言。

b. 说明它有二义性。

3.3 假设有文法

exp → exp addop term | t e r m addop →

+

|

-term → -term mulop factor | f a c t o r mulop →

*

factor →

(

e x p

)

| n u m b e r 则为下面的表达式写出最左推导、分析树以及抽象语法树:

a . 3 + 4 * 5 - 6 b . 3 * ( 4 - 5 + 6 ) c . 3 - ( 4 + 5 * 6 )

3.4 下面的文法生成字母表之上的所有正则表达式(以前曾在算符前后加上了引号,这是 因为竖线既是一个算符又是一个元字符):

rexp → rexp "|" re x p

| rexp re x p

| rexp "*"

| "(" rexp ")"

| l e t t e r

a. 利用这个文法为正则表达式

( a b | b ) *给出一个推导。

b. 说明该文法有二义性。

c. 重写该文法以使算符建立正确的优先关系(参见第 2章)d. (c)的答案给二进制算符带来怎样的结合性?为什么?

3.5 为包括了常量

t r u e和f a l s e、算符 a n d、o r和n o t,以及括号的布尔表达式编写一

个文法。确保给予

o r比a n d低的优先权,而 a n d的优先权比n o t低,并允许n o t重复使

用,如在布尔表达式中的not not true。另外还需保证该文法没有二义性。

3.6 考虑以下表示简化的类L I S P表达式的文法:

lexp → atom | l i s t

atom → n u m b e r | i d e n t i f i e r list →

(

lexp-seq

)

lexp-seq → lexp-seq lexp | l e x p

a. 为串(a 23 (m x y))分别写出一个最左推导和一个最右推导。

第 3章 上下文无关文法及分析

1 0 1

下载

b. 为a部分中的串画出一个分析树。

在文檔中 第1章 概 论 (頁 97-102)

相關文件