侧边栏壁纸
  • 累计撰写 218 篇文章
  • 累计创建 59 个标签
  • 累计收到 5 条评论

巴科斯范式与元语言

barwe
2024-02-19 / 0 评论 / 0 点赞 / 545 阅读 / 3,178 字
温馨提示:
本文最后更新于 2024-02-19,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

巴科斯范式

巴科斯范式(Backus-Normal Form, BNF)是一种用于描述编程语言的语言。

通过递归来定义编程语言的基本结构,单个语句的结构为:

<non-terminal> ::= <replacement>

其中

  • ::= 意为“定义为”,用于将左边的单个复合结构拆分为右边的多个结构
  • non-terminal 意为非终止符,可以进一步拆分的复合结构
  • replacement 是对左侧单个结构的进一步解释

定义自然数

例如我们通过 BNF 定义自然数:

<number> ::= <digit> | (<digit> <number>)
<digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"

首先 digit 定义为右侧的十个十进制符号,我们认为这十个符号是自然数表示里面最基本的符号,即终止符

number 表示一个自然数字符串,它被定义为单个 digit 符号,或者一个 digit 符号紧跟另一个自然数字符串。

例如 number 结构 3 可以定义为单个 digit 结构 3;number 结构 123 可以定义为 digit 结构 1 后紧跟另一个 number 结构 23 组成,而 number 23 又可以拆分成 digit 2 和 number 3,number 3 再次被定义为 digit 3。

通过这两条语句,我们能够基于 10 个终止符解释任意一个自然数。

定义主谓宾句子

参考:

BNF范式(巴科斯范式)到底是什么? - 不是Zoe的回答 - 知乎
https://www.zhihu.com/question/27051306/answer/579820547

BNF 表达式中,左边是永远是待拆分的,所以左边永远不可能是终止符。

当一个句子完全被拆分成终止符时,拆分过程被终止。

定义 Python 字符串字面量

Python 中的字符串字面量有两类:短字符串(单号字符串)和长字符串(多行字符串)。

每个字符串都通过引号包裹字符序列构成:

  • 引号可以是', ", ''', """
  • 字符可以是普通字符(例如a, 1)和转义字符(例如\n, \t
  • 单引号字符串\'是转义字符,双引号字符串中\"是转义字符

首先我们定义普通字符和转义字符:

stringescapeseq ::= "\" <any source character>

可以看到转义字符都是由一个反斜线紧跟一个普通字符构成的。

然后我们定义普通字符,这里短字符串和长字符串使用的普通字符集存在差别:

  • 二者都不包含反斜线字符\,该字符专门用作转义
  • 短字符串不包括换行符\n,长字符串可以包含
  • 单引号短字符串不包含单引号字符',双引号字符串不包含双引号字符"
shortstringchar ::= <any source character except "\" or newline or the quote>
longstringchar ::= <any source character except "\">

然后我们定义字符串的字符单位(一个普通字符或者一个转义字符):

shortstringitem ::= shortstringchar | stringescapeseq
longstringitem ::= longstringchar | stringescapeseq

string item 的重复再加上首位两端的引号就构成了字符串:

shortstring ::= "'" shortstringitem* "'" | '"' shortstringitem* '"'
longstring ::= "'''" longstringitem* "'''" | '"""' longstringitem* '"""'

其中 A* 表示 A 项出现零次及以上。

此外,Python 中的字符串还可能带上前缀,例如常见的格式化字符串f"{name}: {age}":

stringprefix ::= "r" | "u" | "R" | "U" | "f" | "F" | "fr" | "Fr" | "fR" | "FR" | "rf" | "rF" | "Rf" | "RF"

结合字符串前缀,我们可以定义完整的字符串字面量:

stringliteral ::= [stringprefix](shortstring | longstring)

其中 [A] 表示该项是可选的,(A | B) 表示任选一项。

综上,字符串字面量的完整 BNF 定义是:

stringliteral   ::=  [stringprefix](shortstring | longstring)       
stringprefix    ::=  "r" | "u" | "R" | "U" | "f" | "F" | "fr" | "Fr" | "fR" | "FR" | "rf" | "rF" | "Rf" | "RF"
shortstring     ::=  "'" shortstringitem* "'" | '"' shortstringitem* '"'
longstring      ::=  "'''" longstringitem* "'''" | '"""' longstringitem* '"""'
shortstringitem ::=  shortstringchar | stringescapeseq
longstringitem  ::=  longstringchar | stringescapeseq
shortstringchar ::=  <any source character except "\" or newline or the quote>
longstringchar  ::=  <any source character except "\">
stringescapeseq ::=  "\" <any source character>

BNF 语法

  • ::= “定义为……”
  • <A> 必选项
  • "A" or 'A' 基本术语,不用继续定义
  • [A] 可选项
  • A* 重复项,可重复 0 次及以上
  • A+ 重复项,应当重复 1 次及以上
  • A B 组合多项
  • A | B 只能多选一

元语言

当我们谈论一个事物时使用的语言叫做对象语言

事物可以是自然事物(自然语言),也可以是计算机计算过程(编程语言)。

相对的,当我们描述对象语言时,我们也需要使用特定的语言,这就是元语言

所以元语言就是描述和定义其他语言的一种更高级的语言。

一些具体的元语言:巴科斯范式、λ演算……

0

评论区