@
yulon 所以你所谓的右边是个啥?“右边表达式”?
得了吧。
你到现在还不承认你混淆表达式和声明符的入门级错误。
我反对左边右边的笼统分法(而不只是左边具体是什么右边又是什么),首先是因为这东西也就是一种文法的实例(都算不上特例)——文法上极少有递归到自己的分类,可以说到处都构成文法的元素是“××”在“××”的左边或者右边(或者还有递归的),比如表达式中某个操作符和操作数之间的顺序关系。(考虑到操作符数量不少还有更多子类,划分优先级结合性之类辅助记忆倒是情有可原,起码没直球“左”“右”上来就那么白开水废话。)
声明的文法何德何能体现需要死记硬背的独特性?鼓吹这种死记硬背只会挖更多坑。
如果你非要说左边和右边,左边是声明指示符,而右边是可能带有初值符的声明符列表。声明符列表进一步 parse 才 reduce 掉逗号。
这种东西在标准里声明的形式文法里非常清楚,被你这么一描述反而引起混乱。
你所谓的左边也有问题。声明指示符就不只是表示类型,也可以是其它的。像 inline 这样的函数指示符,也是左边的一部分。
所以 [左边结果类型,右边表达式] 明显就没一个是对的。
关于声明的文法规则,我懒得抄,但是回答一些基本的问题,至少比你自己造个漏洞百出的来说,毫不费劲。
“为什么符号是声明符的一部分?”(我姑且理解所谓的符号是指 * )——文法规定。
“不是类型的一部分”(我理解为类型指示符)——文法规定。
“为什么类型只用在左边写一次”(我理解为“左边”的声明指示符)——文法规定。
“因为标准所有人讲都一样,那么自己去看就好了”——不同版本的形式文法其实可能有修改,所以这里我都没对形式文法原文引用(讲清楚你的问题也还用不到那么具体)。
当然,跨语言的差异很可能更大。构成声明符的 * 在 C 的文法里叫 pointer ;这部分在 C++ 对应的叫 ptr-operator ,这个叫法引起歧义和违反 PL 传统,就比较山寨。正好,理解了 ptr-operator 里可以有 * 也可以有 &,OP 的直接问题就算是基本解决了。而你在这里和稀泥公然对着干,就很莫名其妙。
另一方面,硬说声明文法的独特性,那会涉及具体是什么的问题——这种划分声明指示符和声明符的设计的反人类味儿太冲了。而且确实也就 C 和 C++ 这样的过气古董设计里使用。
跟 B 语言引入 ++ -- 主要就是为了省代码长度(一开始我猜的,因为想不出技术好处;后来看 K. Thompson 的理由确实如此)一样,中缀声明符语法设计也算是一种复用左侧元素的“压缩”技术,实践上没什么别的技术优势。
这种设计非常不便于非形式地简单描述规则,反而逼得二道贩子出世。你这种错漏描述也是拜其所赐。