到底什么是上下文無關文法?


在龍書Compilers - Principles, Techniques, & Tools英文版第2版42頁中,提到上下文無關文法有以下的特點:

 

  1. 一個終結符的有限集(A set of terminal symbols),構成文法的最基本的字符就是這個文法的終結符,例如一個能夠產生個位數的文法規則digit --> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9,則數字0~9就是這個文法的終結符,一個能夠產生變量名的文法規則variable --> ('A'-'Z' | 'a'-'z') *(('A'-'Z' | 'a'-'z' | '0'-'9'),則所有的英文字母和數字就是文法的終結符。
  2. 一個非終結符的有限集(A set of nonterminals),例如上面的digit、variable就是非終結符。
  3. 一個產生式的有限集,例如上面的“digit --> ...”和“variable --> ...”兩個規則可以構成一個產生式集
  4. 一個非終結符作為開始符號,在非終結符集中,必須指定其中一個作為開始符號。
雖然這4個特點已經規定了上下文無關文法的特征,但我們仍然好奇,為什么是“上下文無關”而不是“上下文有關”呢?這是因為在利用一個上下文無關文法生成語言的時候,我們可以隨意將文法規則左邊的非終結符派生(更換)為右邊的終結符或非終結符。舉個例子,如果有下面的文法:
  1. Number --> 0 / 1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9
  2. Alpha --> 'A'-'Z' / 'a'-'z'
  3. AlphaNum --> Alpha / Number
  4. Variable --> Alpha *AlphaNum
假設Variable是這個文法的開始符號,我們要根據這個文法生成一個語言實例。先應用規則4,Variable派生為Alpha AlphaNum(星號表示后面的符號可以出現0到若干次,這里我們選擇出現1次)。然后對Alpha應用規則2,派生為'A',因此整個Variable就派生為'A' AlphaNum。現在來考慮AlphaNum如何派生,有沒有限制這個AlphaNum可以派生為Alpha還是Number呢?它是否會受到前面的Alpha的影響而不同?我們說, 在一個上下文無關文法中,這個派生是不受上下文影響的,也就是說,我們可以隨意的讓其派生為Alpha或者Number,而不必考慮前后文的情況。有關解釋可以參考 http://cs.union.edu/~striegnk/courses/nlp-with-prolog/html/node37.html

 

因此,“文法”是用來產生語言(字符串)而不是用來識別語言的(參見http://www.cis.upenn.edu/~jean/gbooks/tcbookpdf2.pdf)。對於語言的創造者而言,“文法”是用來描述所要創造的語言的。對於語言的閱讀者來說,可以將“文法”轉換為有限狀態機,這個狀態機可以用於識別這個文法所生成的語言。

其他參考:http://en.wikipedia.org/wiki/Context-free_grammar

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM