上下文無關文法
下面給出一個例子:
上下文無關文法的推導
生成樹
下面給出一個例子:
歧義文法
如果一個字符串有多個推導,或者有多個生成樹可以生成同樣的字符串,則稱這個文法是歧義的。如果每個字符串都只對應於一個生成樹,則稱這個文法是非歧義的。
下面給出一個例子:
去除文法的歧義性
無法根據一個確切的算法來判斷一個文法是否是歧義的,而且如果一個上下文無關的語言只存在一個具有歧義的文法,那么就無法去除歧義性。
出現歧義的原因:
- 沒有考慮運算符的優先級。例如上面的例子,左圖是×先於+結合,而右圖是+先於×結合,這兩者都是正確的生成樹。然而在一個無歧義的文法中只允許左圖的結構。
- 一系列同樣的運算符既可以從左到右也可以從右到左結合。例如對於字符串E+E+E將會得到兩顆不同的生成樹,因為加法滿足結合律,所以無論從左還是從右結合都無所謂,但是為了去除歧義,習慣性的采用從左到右的結合方式。
對於一個問題,強制優先級的問題的解決方法是引入幾個不同的變元,每個變元代表擁有同樣級別的“黏結強度”的那些表達式。對於上面那個具有歧義的文法,可以進行如下轉化:
最左推導作為一種歧義的表達
即使文法的是無歧義的,推導也有可能不唯一。但下面的結論總是成立的:在無歧義的文法中,最左推導是唯一的,最右推導也是唯一的。對於任何文法G=(V, T, P, S)和T*中的串w,w有兩顆不同的生成樹當且僅當從S到w有兩個不同的最左推導。
固有的歧義性
如果一個上下文無關的語言L的所有的文法都是歧義的,則稱它是固有歧義的。只要L有一個文法是非歧義的,那么L就是非歧義的。例如,在上面的例子中的文法所生成的語言實際上是非歧義的,因為它存在一個非歧義的文法。