此篇文章承接上一篇:【编译原理】理解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’ + option_identifier + ‘{’ + value_list + ‘};’
option_identifier=identifier | ‘’
value_list=’’ | value_list + ‘,’ + indentifier | value_list + ‘,’ + indentifier + ‘=’ + Num
写到最后的value_list会发现,不管怎么写都会多出一个逗号。
因为BNF里面的控制命令太少了,想要表达出我们想要表达的规则,我们得求助于EBNF。
EBNF介绍
下面是EBNF的介绍:
EBNF,E即Extended,EBNF即扩展BNF范式。
它最初由尼古拉斯·沃斯开发,最常用的 EBNF 变体由标准,特别是 ISO-14977 所定义。 ——来自维基百科
更详细的介绍可以参考维基百科: 扩展巴科斯范式(可能需要翻墙)
ISO-14977标准文档获取方法,参考文章:去哪查阅ISO国际标准?
下图列举了EBNF包含的符号:
可见EBNF中包含了更多的控制命令。相对于BNF来说,它的描述能力更为强大。
重写
我们现在使用EBNF重写上面的枚举声明语法。
enum_decl = 'enum'[id]'{'[id'='num]{','id'='num}'}';
可见上面用一个EBNF语句即描述BNF很多条语句才能描述的内容。
以此类推,可以自己尝试编写。
欢迎专注【编译原理】专栏!