BNF表示法

2025 年 6 月 3 日 | 阅读 5 分钟

编译器设计中的 BNF 符号简介

在这个现代世界中,人们普遍认为 编译器设计是计算机科学中的一个重要领域,它主要侧重于将我们用编程语言编写的代码转换为计算机实际可以运行的东西。当我们用高级语言(如 Python 或 Java)编写程序时,编译器会介入,以便将人类可读的代码翻译成计算机可以理解的机器代码二进制指令字符串。

BNF Notation

此外,此过程通常涉及多个步骤,其中一个关键部分就是理解编程语言的结构或语法。 这就是所谓的 Backus-Naur 范式(或 BNF)发挥作用的地方。 BNF 是一种特殊方式,有效地用于描述编程语言的规则和语法,几乎就像英语中的语法规则一样。 尽管如此,BNF 是在 20 世纪 50 年代末由 John Backus 和 Peter Naur 开发的,最初用于定义一种称为 ALGOL 60 的编程语言的语法。 BNF 背后的主要思想只是将一种语言分解为规则,而这些规则又是由符号组成的。 符号有两种类型:终结符和非终结符

  • 终结符用于语言的最基本元素,例如关键字(if、while)、运算符(+、-)或标点符号(;)。
  • 非终结符被认为是表达式、循环或函数定义等模式或结构的占位符。

例如,如果我们实际上想定义一个简单的数学表达式是什么样的,那么我们可能需要使用 BNF 来说:

<expression> ::= <number> "+" <number>

这条规则告诉我们,表达式通常由两个数字组成,中间有一个加号。

BNF表示法

BNF 代表 Backus-Naur 范式。 它用于编写上下文无关文法的正式表示。 它也用于描述编程语言的语法。

符号表示

BNF 符号基本上只是上下文无关文法的一种变体。

在 BNF 中,产生式具有以下形式

其中 leftside ∈ (Vn∪ Vt)+,definition ∈ (Vn∪ Vt)*。 在 BNF 中,leftside 包含一个非终结符。

我们可以用相同的 leftside 定义多个产生式。 所有产生式都用竖线符号“|”分隔。

任何文法都有如下的产生式

在 BNF 中,我们可以将上述文法表示为如下

制定 BNF 的规则

自然地,我们将为 BNF 中的规则定义文法,并且在其核心,BNF 文法规则将如下所示:

rule → name ::= expansion

在此,name 是语言一部分的标签,通常写在尖括号之间,例如 <identifier>。 expansion 描述了该部分如何通过简单地使用较小部分或符号的组合来形成。

所有这些扩展的工作方式可以这样描述:

  • 一个扩展可以很容易地被另一个扩展所跟随(这被称为串联)。
  • 然而,这些扩展也可以是替代方案,并且可以通过管道符号 | 来分隔。
  • 扩展可以是名称(非终结符)或终结符(语言中的实际符号或单词)。

通常,终结符通常是特定的片段,例如关键字(if、while)或符号(+、-)。 有时,它们是引号内的文字字符串,例如“+”或“switch”。 其他时候,它们也可能引用类别,例如整数标识符s,这些类别在其他地方定义,通常借助正则表达式。

说到正则表达式,许多文法都借用它们来简化重复和选项。 例如:

  • A * 表示“重复零次或多次”。
  • A + 表示“重复一次或多次”。
  • A? 表示“可选”(零次或一次)

此外,一个实际的例子是关于 Python 如何通过混合所有这些想法来定义浮点数。 Python 的文法也使用诸如 BNF 之类的文法,但它并不总是使用尖括号,并且它将正则表达式与方括号 [ ] 结合起来用于可选部分。 这是对浮点定义的简化看法

  • 浮点数可以是带有小数点的数字,也可以是带有指数的数字。
  • 小数部分可能是可选的或必需的,具体取决于格式。
  • 指数部分可以包括 e 或 E,后跟一个可选的符号,以及高效的数字。

尽管所有这些符号混合在一起,但它分别显示了语法规则在清晰而精确地描述编程语言时可以具有的灵活性和强大功能。

常见问题解答/FAQ

问题 1:术语 ATL 是什么意思?

答案:ATL 主要代表 Active Template Library 它是 C++ 中的一组工具,可帮助开发人员更轻松有效地构建 COM(组件对象模型)组件。

问题 2:什么是类数据值?

答案:类数据值是属于类本身的信息,而不仅仅是一个对象。 它在从该类创建的所有对象之间共享,有点像共享设置或共同特征。

问题 3:我们为什么要使用 ATL?

答案:使用 ATL 可以使创建 COM 对象的过程更快,并且不易出错。 通过提供现成的代码结构,它还可以节省开发人员的时间。

问题 4:Backus-Naur 范式 (BNF) 是做什么的?

答案:BNF 是一种轻松定义编程语言规则的方式。 它帮助开发人员实际描述有效的代码应该是什么样子,以便编译器可以正确地理解和处理它。

问题 5:为什么 BNF 符号很重要?

答案:BNF 主要帮助个人清晰地定义编程语言文法,从而确保在语言设计、文档和实施过程中,人和编译器都能以有效的方式一致地解释语法。


下一个主题YACC