上下文无关文法
上下文无关文法是用来描述程序语言的一种表达方式,通过简单的符号描述语言的集合。正如我们所知道,一个程序即为一个句子(字符串),语言就是所有句子的集合。上下文无关文法是用来描述语言的工具。通过一个简单的例子建立对上下文无关文法的感性认知。
假设一种语言X,它的句子结构只有主语、谓语和宾语,主语只能是我、你和他,谓语只能是喜欢,宾语只能是黑色和白色。语言X的上下文无关文法表达如下:
语句 -> 主语 谓语 宾语
主语 -> 我 | 你 | 他
谓语 -> 喜欢
宾语 -> 黑色 | 红色
我们可以发下语言X只有6条语句,并且结构都是主语、谓语和宾语。在上下文文法中,“语句 -> 主语 谓语 宾语”称为产生式,其中左边的语句称为非终结符同时也是起始符号,其中非终结符表示可以继续扩展或产生的符号,即可以被继续替换的符号;起始符号表示语言X中的所有句子都从该符号开始。与非终结符相对的就是终结符,也就是例子中的我、你、他、喜欢、黑色和红色,表示的是不能够继续产生新的符号,即无法被替换。
一个上下文无关文法G就是由一个终结符集合T,一个非终结符集合N,一个产生式集合P以及一个起始符号S(S属于N)组成,由文法G推导产生的所有句子集合称为G语言。
终结符和非终结符统称为符号,符号一般用字母 A, B, X, Y, a, b 表示,符号串一般用小写字母 u, v 表示。产生式的形式为 A -> u ,其中 A 为非终结符, u 为一个符号串。下面在看一个文法的例子。
S –> AB
A –> aA | ε
B –> b | bB
这里面的第二行中的ε表示一个空句子,表示A可以用一个空句子来代替。经过观察,我们可以发现上述文法可以用以下集合来代替。
A : { ε, a, aa, aaa, ... }
B : { b, bb, bbb, ... }
S : { b, bb, bbb, ..., ab, abb, ..., aab, aabb, ... }
进一步思考发现,S可以用正则表达式 a*b+ 表示。
通过上述两个例子,我们基本建立对上下文无关文法的感性认识。下面给出相关术语的正式定义。
终结符集合T(terminal set):一个有限集合,其元素称为终结符(terminal)。
非终结符集合N(non-terminal set):一个有限集合,与T无公共元素,其元素称为 非终结符(non-terminal)。
符号集合 V (alphabet) : T 和 N 的并集,其元素称为 符号(symbol) 。因此终结符和非终结符都是符号。符号可用字母:A, B, C, X, Y, Z, a, b, c 等表示。
符号串(a string of symbols) : 一串符号,如 X1 X2 ... Xn 。只有终结符的符号串称为 句子(sentence)。 空串 (不含任何符号)也是一个符号串,用 ε 表示。符号串一般用小写字母 u, v, w 表示。
产生式(production) : 一个描述符号串如何转换的规则。对于上下文本无关语法,其固定形式为: A -> u ,其中 A 为非终结符, u 为一个符号串。
产生式集合 P (production set) : 一个由有限个产生式组成的集合。
展开(expand) : 一个动作:将一个产生式 A -> u 应用到一个含有 A 的符号串 vAw 上,用 u 代替该符号串中的 A ,得到一个新的符号串 vuw 。
折叠(reduce) : 一个动作:将一个产生式 A -> u 应用到一个含有 u 的符号串 vuw 上,用 A 代替该符号串中的 u ,得到一个新的符号串 vAw 。
起始符号 S (start symbol) : N 中的一个特定的元素。
推导(derivate) : 一个过程:从一个符号串 u 开始,应用一系列的产生式,展开到另一个的符号串 v。若 v 可以由 u 推导得到,则可写成: u => v 。
上下文本无关语法 G (context-free grammar, CFG) : 一个 4 元组: (T, N, P, S) ,其中 T 为终结符集合, N 为非终结符集合, P 为产生式集合, S 为起始符号。一个句子如果能从语法 G 的 S 推导得到,可以直接称此句子由语法 G 推导得到,也可称此句子符合这个语法,或者说此句子属于 G 语言。 G 语言( G language) 就是语法 G 推导出来的所有句子的集合,有时也用 G 代表这个集合。
解析(parse) : 也称为分析,是一个过程:给定一个句子 s 和语法 G ,判断 s 是否属于 G ,如果是,则找出从起始符号推导得到 s 的全过程。推导过程中的任何符号串(包括起始符号和最终的句子)都称为 中间句子(working string) 。