【编译原理】三、编写BNF

此篇文章承接上一篇:【编译原理】理解BNF


前言

理解了BNF,就能实现代码解析了吗?在进行编码之前,还需要学习如何编写BNF。实际上,用代码实现BNF有固定的模式,也有现成的工具,比如可以使用yacc、bison等工具自动化进行,当然这些工具有自己的语言来描述语法规则,但学会编写BNF是使用这些成熟工具的基础。

也就是说,在学习用代码实现语法解析之前,我们要将目标语法规则使用统一的语言描述出来、公式化,这样更利于我们设计代码,同时这也利于将规则从设计到实现的过程标准化、工程化。


编写BNF

上一篇文章中,我们介绍了如何编写四则运算的BNF,我们需要遵循几个原则:

  • 优先级越高的产生式越接近终端节点;
  • 有左递归要消除左递归。

是否所有的BNF都可以这么来写呢?下面我们尝试对常见语法使用BNF进行编写。

如C语言中枚举类型的定义:

enum EnumName
{
	A, B, C
};

枚举类型的定义语法,用语言描述出来是:

以一个enum开头,后面可以跟一个标识符,也可以省略不写。
接着是一个左大括号;
接着是枚举值列表,枚举值列表可以为空,不为空时,多个枚举值之间用逗号隔开。
枚举值可以只写出标识符名称,也可以给它赋值,如A和A=1都是正确的;
接着是一个右大括号和一个分号。

其BNF可以尝试写出来,如下所示:

enum_decl = 'enum' enum_name '{' value_list '};'
enum_name = identifier | ''
value_list = '' | not_empty_value_list
not_empty_value_list = identifier | identifier '=' number | not_empty_value_list ',' identifier | not_empty_value_list ',' identifier '=' number

我们不使用 := ,而直接使用 = ,更容易理解。identifier为标识符,number代表数字,这里为了简化,也没有给出其生成式,这里明白大意即可,我们后面会编写 identifier 和 number 的生成式。

注意,BNF的写法不唯一,就像是不同的人用语言描述同一个事物一样,每个人都有自己的描述方式,关键在于描述正确即可。

假如我们用 * 号表示 一个语法节点出现 0次 或 0次以上,被量词描述的一个或多个语法节点可以用括号括起来。下面将枚举定义语法改写成:

enum_decl = 'enum' (identfiier)* '{' value_list* '};'
value_list  = identifier | identifier '=' number | value_list (',' identifier)* | value_list (',' identifier '=' number)*

我们通过对BNF进行自定义扩展,描述了C语言中枚举的定义语法。

实际上,对BNF的扩展工作已经由EBNF完成,下面介绍EBNF。


EBNF介绍

下面是EBNF的介绍:

EBNF,E即Extended,EBNF即扩展BNF范式。
它最初由尼古拉斯·沃斯开发,最常用的 EBNF 变体由标准,特别是 ISO-14977 所定义。 ——来自维基百科
更详细的介绍可以参考维基百科: 扩展巴科斯范式(可能需要翻墙)
ISO-14977标准文档获取方法,参考文章:去哪查阅ISO国际标准?

下图列举了EBNF包含的符号:
EBNF包含的公式符号
可见EBNF中包含了更多的控制命令。相对于BNF来说,它的描述能力更为强大。


重写

我们现在使用EBNF重写上面的枚举声明语法。

enum_decl = 'enum', [identifier], '{', [identifier, ['=', number], {',', identifier, ['=', number]}], '};'

可见上面用一个EBNF语句即描述BNF很多条语句才能描述的内容。
以此类推,可以自己尝试编写。

升级版EBNF

参考:三大浪漫之编译原理-前置知识-EBNF。文中提到,W3C标准下的EBNF,更加强大和简洁。我们这里就称之为 EBNF2.0。下面使用EBNF2.0 对枚举声明语法进行重写:

enum_decl = 'enum' identifier? '{' (identifier ('=' number)? (',' identifier ('=' number)? )? )? '};'

可是,看上去并没有任何简化。这是因为 EBNF2.0 中有很多高度简化的描述语句我们还未使用,在下一篇文章中,我们将使用更多 EBNF2.0 语句去描述四则运算语法。


欢迎专注【编译原理】专栏!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

撬动未来的支点

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值