为什么 C 的 BNF 语法允许使用空序列的初始化声明符进行声明?
Why does C's BNF grammar allow declarations with an empty sequence of init-declarators?
在查看 C 的 BNF 语法时,我认为声明的产生式规则看起来很奇怪(根据 https://cs.wmich.edu/~gupta/teaching/cs4850/sumII06/The%20syntax%20of%20C%20in%20Backus-Naur%20form.htm):
<declaration> ::= {<declaration-specifier>}+ {<init-declarator>}* ;
为什么要对 init-declarator
使用 *
量词(表示零次或多次出现)?这允许 int;
或 void;
等语句在语法上有效,即使它们在语义上无效。他们不能在产生式规则中使用 +
量词(出现一次或多次)而不是 *
吗?
我尝试编译一个简单的程序来查看编译器输出的内容,它所做的只是发出警告。
输入:
int main(void) {
int;
}
输出:
test.c: In function ‘main’:
test.c:2:5: warning: useless type name in empty declaration
int;
^~~
declaration-specifier
包括 type-specifier
,其中包括 enum-specifier
。像
这样的结构
enum stuff {x, y};
是有效的 declaration
,没有 init-declarator
。
像int;
这样的构造被constraints beyond the grammar排除了:
A declaration other than a static_assert declaration shall declare at least a declarator (other than the parameters of a function or the members of a structure or union), a tag, or the members of an enumeration.
我猜你的编译器只发出警告是有向后兼容性的原因。
没有 init 声明符的声明:
<declaration> ::= {<declaration-specifier>}+ {<init-declarator>}* ;
对于不是单个 enum
/struct
/union
说明符的声明说明符列表是无害的,并且它可以有效地匹配那些
在任何情况下,所提供的语法也会错误地匹配像 int struct foo x;
或 double _Bool y;
这样的声明(它允许多个说明符来匹配像 long long int
这样的东西),但是所有这些稍后可以在语义检查中检测到。
BNF 语法本身不会清除所有非法结构。
在查看 C 的 BNF 语法时,我认为声明的产生式规则看起来很奇怪(根据 https://cs.wmich.edu/~gupta/teaching/cs4850/sumII06/The%20syntax%20of%20C%20in%20Backus-Naur%20form.htm):
<declaration> ::= {<declaration-specifier>}+ {<init-declarator>}* ;
为什么要对 init-declarator
使用 *
量词(表示零次或多次出现)?这允许 int;
或 void;
等语句在语法上有效,即使它们在语义上无效。他们不能在产生式规则中使用 +
量词(出现一次或多次)而不是 *
吗?
我尝试编译一个简单的程序来查看编译器输出的内容,它所做的只是发出警告。
输入:
int main(void) {
int;
}
输出:
test.c: In function ‘main’:
test.c:2:5: warning: useless type name in empty declaration
int;
^~~
declaration-specifier
包括 type-specifier
,其中包括 enum-specifier
。像
enum stuff {x, y};
是有效的 declaration
,没有 init-declarator
。
像int;
这样的构造被constraints beyond the grammar排除了:
A declaration other than a static_assert declaration shall declare at least a declarator (other than the parameters of a function or the members of a structure or union), a tag, or the members of an enumeration.
我猜你的编译器只发出警告是有向后兼容性的原因。
没有 init 声明符的声明:
<declaration> ::= {<declaration-specifier>}+ {<init-declarator>}* ;
对于不是单个 enum
/struct
/union
说明符的声明说明符列表是无害的,并且它可以有效地匹配那些
在任何情况下,所提供的语法也会错误地匹配像 int struct foo x;
或 double _Bool y;
这样的声明(它允许多个说明符来匹配像 long long int
这样的东西),但是所有这些稍后可以在语义检查中检测到。
BNF 语法本身不会清除所有非法结构。