rea*_*esk 6 c parsing lalr bnf glr
我对著名的Backus-Naur形式的C语法感兴趣并且研究了一段时间,令我感到困惑的是,某些语法在我看来错了,但根据BNF却被认为是正确的。
例如,int test {}这是什么?我认为这在C语言中是一种错误的语法,但事实是BNF认为这是一个函数定义:
int -> type_const -> type_spec -> decl_specs
test-> id -> direct_declarator -> declarator
'{' '}' -> compound_stat
decl_specs declarator compound_stat -> function_definition
Run Code Online (Sandbox Code Playgroud)
我用bison尝试过,它认为输入int test {}是正确的形式,但是我在C编译器上尝试过,它将无法编译。
所以有问题:
int test {} 正确的语法吗?语法是必要的,但不足以描述有效的 C 程序。为此,您还需要标准的约束。一个更简单的例子是0++,它遵循 C 表达式的语法,但肯定不是有效的程序片段......
- 函数定义中声明的标识符(即函数的名称)应具有函数类型,由函数定义的声明符部分指定。 [162]
脚注162解释了约束的目的是typedef 不能使用a ,即
typedef int F(void);
F f { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
typedef即使这样的 a可以用于函数声明,也将无效,即
F f;
Run Code Online (Sandbox Code Playgroud)
将声明该函数
int f(void);
Run Code Online (Sandbox Code Playgroud)
但仅此约束的存在也证明 BNF 语法本身在这种情况下是不够的。因此,您是正确的,因为语法会将这样的片段视为函数定义。