为什么`int test {}`是C语言BNF中的函数定义
why is `int test {}` a function definition in C language BNF
我对著名的 The syntax of C in Backus-Naur Form 很感兴趣并研究了一段时间,让我感到困惑的是有些语法对我来说是错误的,但根据 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
我用 bison 试过,它认为输入 int test {}
是正确的形式,但我在 C 编译器上试过,它无法编译。
所以有问题:
int test {}
语法是否正确?
- 如果语法正确,那是什么意思,为什么编译器无法识别它?
- 如果是错误的语法,我能说BNF不严谨吗?这是否意味着现代C编译器不坚持这个BNF?
语法是必需的,但不足以描述一个有效的 C 程序。为此,您还需要来自标准的 constraints。一个更简单的例子是 0++
,它遵循 C 表达式的语法,但肯定不是有效的程序片段...
- The identifier declared in a function definition (which is the name of the function) shall have a function type, as specified by the declarator portion of the function definition. [162]
脚注 162 解释说,约束的意图 是 typedef
不能使用 ,即
typedef int F(void);
F f { /* ... */ }
将无效,即使这样的 typedef
可用于函数 声明 ,即
F f;
将声明函数
int f(void);
但是仅仅存在这个约束也证明BNF文法本身在这种情况下是不够的。因此,您是正确的,因为 grammar 会将这样的片段视为函数定义。
BNF 形式是描述语言语法的一种精确方式,即如何精确地从原始输入开始获取解析树。
对于每种语言,您可以定义无数种描述该语言的语法。这些描述同一种语言的文法的属性可能相差很大。
如果你学习 C 语言的语法,请注意它不是上下文无关的,而是上下文敏感的,这意味着,选择规则或其他规则的决定取决于输入中该点周围的内容。
阅读 lexer hack
了解如何正确解释 C 语法的 Backus Naur 形式。
我对著名的 The syntax of C in Backus-Naur Form 很感兴趣并研究了一段时间,让我感到困惑的是有些语法对我来说是错误的,但根据 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
我用 bison 试过,它认为输入 int test {}
是正确的形式,但我在 C 编译器上试过,它无法编译。
所以有问题:
int test {}
语法是否正确?- 如果语法正确,那是什么意思,为什么编译器无法识别它?
- 如果是错误的语法,我能说BNF不严谨吗?这是否意味着现代C编译器不坚持这个BNF?
语法是必需的,但不足以描述一个有效的 C 程序。为此,您还需要来自标准的 constraints。一个更简单的例子是 0++
,它遵循 C 表达式的语法,但肯定不是有效的程序片段...
- The identifier declared in a function definition (which is the name of the function) shall have a function type, as specified by the declarator portion of the function definition. [162]
脚注 162 解释说,约束的意图 是 typedef
不能使用 ,即
typedef int F(void);
F f { /* ... */ }
将无效,即使这样的 typedef
可用于函数 声明 ,即
F f;
将声明函数
int f(void);
但是仅仅存在这个约束也证明BNF文法本身在这种情况下是不够的。因此,您是正确的,因为 grammar 会将这样的片段视为函数定义。
BNF 形式是描述语言语法的一种精确方式,即如何精确地从原始输入开始获取解析树。
对于每种语言,您可以定义无数种描述该语言的语法。这些描述同一种语言的文法的属性可能相差很大。
如果你学习 C 语言的语法,请注意它不是上下文无关的,而是上下文敏感的,这意味着,选择规则或其他规则的决定取决于输入中该点周围的内容。
阅读 lexer hack
了解如何正确解释 C 语法的 Backus Naur 形式。