为什么 C 的 BNF 语法允许使用空的 init-declarators 序列进行声明?

raf*_*lfp 29 c context-free-grammar language-lawyer

在查看 C 的 BNF 语法时,我认为声明的产生式规则看起来很奇怪(根据https://cs.wmich.edu/~gupta/teaching/cs4850/sumII06/The%20syntax%20of% 20C%20in%20Backus-Naur%20form.htm):

<declaration> ::=  {<declaration-specifier>}+ {<init-declarator>}* ;
Run Code Online (Sandbox Code Playgroud)

为什么对 ? 使用*量词(表示出现零次或多次)init-declarator?这允许诸如int;或 之类的语句void;在语法上有效,即使它们在语义上无效。难道他们不能只在产生式规则中使用+量词(出现一次或多次)*吗?

我尝试编译一个简单的程序来查看编译器输出的内容,它所做的只是发出警告。

输入:

<declaration> ::=  {<declaration-specifier>}+ {<init-declarator>}* ;
Run Code Online (Sandbox Code Playgroud)

输出:

int main(void) {
    int;
}
Run Code Online (Sandbox Code Playgroud)

use*_*ica 30

declaration-specifier包括type-specifier,其中包括enum-specifier。一个像

enum stuff {x, y};
Run Code Online (Sandbox Code Playgroud)

是有效的declaration,没有init-declarator

像这样的int;结构被语法之外的约束排除:

static_assert 声明以外的声明应至少声明一个声明符(函数的参数或结构或联合的成员除外)、标记或枚举的成员。

我猜你的编译器只发出警告背后有向后兼容的原因。


PSk*_*cik 14

没有 init 声明符的声明:

<declaration> ::=  {<declaration-specifier>}+ {<init-declarator>}* ;
Run Code Online (Sandbox Code Playgroud)

是无害的是不是一个单一的声明说明清单enum/ struct/union符,它有效地匹配那些。

在任何情况下,所呈现的语法也将错误地匹配像int struct foo x;or 之类的声明double _Bool y;(它允许多个说明符以匹配诸如 之类的东西long long int),但所有这些都可以在以后在语义检查中检测到。

BNF 语法本身不会清除所有非法结构。