语法/文法,bnf 够用指南

2,105 阅读2分钟

对语言的深入了解:语言就是有语法或者说文法所规定的

文法可以说是由一系列规则组成的

每个规则都有两部分:(1) 名称 (2) 名称的扩展。

例如,如果我们创建一个语法来处理英语文本,我们可能会添加一个规则,例如:

名词短语可以扩展为词名词。

从中我们最终可以推断出“狗”是一个名词短语。

或者,如果我们描述一种编程语言,我们可以添加一个规则,例如:

表达式可以扩展为扩展表达式

接下来我们拿bnf举个例子:

expr ::= term { "+" term | "-" term }.
term ::= factor { "*" factor | "/" factor }.
factor ::= "(" expr ")" | const.
const := "1" | "2" | "3".

bnf由四条规则组成(在bnf中 “可以扩展”被表示为:: =):

rule1.名称:expr

名称的扩展: term { "+" term | "-" term }.(可以理解成一个term或者一个term + term或者 term-term)

这个规则就是讲一个expr可以生成(变成)一个term 或者 term + term 或者term - term

rule2.名称:term

名称的扩展: factor { "*" factor | "/" factor }..(可以理解成一个factor或者一个factor * factor或者 factor / factor)

这个规则就是讲一个term可以生成(变成)一个factor或者 factor * factor或者 factor / factor

rule3.名称:factor

名称的扩展: "(" expr ")" | const.

这个规则就是讲一个factor可以生成(变成)(expr)或者 const (为什么expr要加括号呢?在下面的例子中有体现)

rule4.名称:const

名称的扩展:"1" | "2" | "3".

这个规则就是讲一个const可以生成(变成)1或者2或者3

举个具体例子:1*(2+3)

-> expr
-> term
-> factor *  factor
-> const  *  expr
-> const  * (term   + term)
-> const  * (factor + factor)
-> const  * (const  + const-> 1      * (2      + 3

有一点要注意就是那个expr的括号,因为考虑到优先级的原因。

你有没有考虑到这些规则的顺序问题,为什么第一个是加减呢?(我个人觉得是因为一个整式expr比如我们这个‘1 (2+3)’都可以分解成‘1(2+3)’ + 0,而0可以不表示。要是*/,那么就要多出一个1)

这个bnf解析的过程就是一棵树的构造过程,这棵树就是ast

image-20230328210554232

参考资料

1.The language of languages(Grammar: The language of languages (BNF, EBNF, ABNF and more) (might.net))

2.柯里化的前生今世(三):语言和同像性 (柯里化的前生今世(三):语言和同像性 - 知乎 (zhihu.com)