结合性,优先级,声明

0.引子

int* arr[10];
arr是一个数组,其中的元素是int*类型的。

int (*ptr)[10];
ptr是一个指针,指向的元素是具有10个int元素的的数组。

1+2*3
大家知道先乘除后加减,如果要先算1+2的话,就要写成
(1+2)*3

1.结合性

文法 (1):
A := A+i | i
对应的语言具有i+i+i的形式。

其规约也毫无压力:
i+i+i->A+i+i->A+i->A.

再看个类似的文法(2):
A := i+A | i
对应的语言和上面的相同,规约:
i+i+i->i+i+A->i+A->A

再看个文法(3):
A := A+A | i
对应的语言没有变,但是存在如下规约:
i+i+i->A+i+i->A+A+i->A+i->A+A->A
i+i+i->i+i+A->i+A+A->i+A->A+A->A
于是有歧义。

如果给一个i+i+i这样的句子,是有歧义的,于是规定+具有左结合性,
于是就可以消歧了,换句话说,指定了文法(1)。

由于加法具有结合律,所以,歧义并不影响结果,但是,如果是减法或者除法
就会jiong掉了。

2.优先级

文法(4):
A := A+B | B
B := B*i | i
给定句子i+i*i,可以有如下规约:
i+i*i->i+B*i->i+B->B+B->A+B->A
这样的规约就是“先乘除后加减”的直接体现。
再看下面的:
i+i*i->B+i*i->A+i*i->A+B*i->A*i->A*B ???
规约不下去了。

如果给定一个i+i*i这样一个句子,也是有歧义的,于是可以规定先乘后加,
于是就可以消歧了,换句话说,指定了文法(4)。

到这里就可以明白了,在这里所谓结合性和优先级,就是指定了某个文法。

如果文法改成:

A := A+B | B
B := B*C | C
C := i | (A)

于是就可以接受(i+i)*i之类的句子了,其中用意,你懂的。

3.
文法(5)
D := PD
PD := *PD | DD
DD := i | DD[number]
number是一个非负整数。

首先看看能被文法(5)接受的句子:
i
*i
i[10]
*i[10]
*****i[10][10][10]

如果在前面加个int,在最后加一个;:
int i;
int *i;
int i[10];
int *i[10];
int *****i[10][10][10];

这就是声明啊。

话说*i[10]才是我们关心的,尝试对这个进行规约:
*i[10]->*DD[number]->*DD->*PD->PD->D
如果试图先对前面的进行规约:
*i[10]->*DD[10]->*PD[10]->PD[10]->D[10]???
又走不动了。

所以,给定了文法,在这里没有歧义, i总是和后面的[10]形成一个语法单位,再和前面的*
形成一个语法单位。

如果要求先和前面的*形成语法单位呢?

D := PD
PD := *PD | DD
DD := i | DD[number] | (D)
number是一个非负整数。

于是对 (*i)[10]有如下规约:
(*i)[10]->(*DD)[10]->(*PD)[10]->(PD)[10]->(D)[10]->DD[10]->DD[number]->
DD->PD->D.

到了这里,相信大家懂的。

4.
当有人对int *arr[10];和int (*ptr)[10];的区别进行解释,并试图用优先级和结合律进行解释的时候,
大家懂的。

5.
进一步说明:
在第1,2节中,最后说“如果给定一个i+i*i这样一个句子”,这里是指没有文法的情况下,因为这样的句子
首先在数学上有,然后在指定结合性和优先级的时候就等同于指定文法。

而在第3节末尾,就没有类似的说法了,而是指定了文法,再说没有文法歧义。

PS:
木有检查,如果有bug或者叙述不严格的地方,敬请指教。
2011/01/19 17:22
创建
2011/01/19 17:29
增加“进一步说明”
2011/02/16 13:28
文中以前用推导的地方应该用规约,其逆过程才叫推导。
2013/06/29

瞄了一下龙书,发现这些东西在龙书中已经说清楚了,进一步理解需要参考:

龙书,第二版,中文,29到30页。

 Alfred V.Aho,Monica S.Lam,Ravi Sethi,Jeffrey D.Ullman著,赵建华,郑滔,载新宇译,编译原理,机械工业出版社,p29-30

 

读者可以参考声明转换以加深对C++声明的理解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值