要介绍上下文无关语言,我们先来了解一下定义上下文无关文法的工具——产生式的写法。我们还是使用编程语言的表达式作为例子,但这次我们假设表达式只有三种——单个表示变量名标识符、括号括起来的表达式和两个表达式相加。比如a是一个变量表达式,a+b是两个变量表达式相加的表达式,(a+b)是一个括号表达式。我们用符号E来表示一个表达式,那么这三种表达式分别可以定义为:
这种形式的定义就叫做产生式。出现在→左侧符号E称作非终结符(nonterminal symbol),代表可以继续产生新符号的“文法变量”。 符号→表示非终结符可以“产生”的东西。而上述产生式中的蓝色等符号,是具有固定意义的单词,它们不再会产生新的东西,称作终结符(terminal symbol)。注意,非终结符可以出现在产生式的右侧,这就是具有递归性质文法的来源。产生式经过一系列的推导,就能够生成各种完全由终结符组成的句子。比如,我们演示一下表达式(a + b) + c的推导过程:
E => E + E => (E) + E => (E + E) + E => (a + E) + E => (a + b) + E => (a + b) + c
推导过程中的=>代表将当前句型中的一个非终结符替换成产生式右侧的内容。以上推导过程中,我们每次都将句型中最左边一个非终结符展开,所以这种推导称为最左推导。当然也有最右推导,不同之处就算是每次将句型中最右边的非终结符展开:
E => E + E => E + c => (E) + c => (E + E) + c => (E + b) + c => (a + b) + c
可见,同一个结果可以具有多种不同的推导过程。使用最左推导时,句型的左侧逐渐变得只有终结符;而最右推导正好相反,推导过程中句型的右侧逐渐变得只有终结符,最终结果都是整个句子变为终结符。所有符合文法定义的句子,都可以用文法的产生式推导出来。