文法的概念
每一種自然語言或者是編程語言都需要文法來描述,文法相當於語言學的語義分析,即分析每一句話所表示的含義,編譯器需要利用文法來完成其語法分析和語義分析。
在目前編程語言領域,上下文無關文法作爲程序語言的描述工具,比如a = b + c
是一個合法的賦值語句。
符號和符號串的定義
每個程序都可以看成是一個“基本符號”串,如果有一個基本符號集,那麼C語言等編程語言可以看成是在這個基本符號集上定義的、按照一定規則構成的一切基本符號串組成的集合。
字母表是元素的非空有窮集合,字母表中的元素稱之爲符號,因此字母表也稱之爲符號集。例如C語言中的字母表由字母、數字、關鍵字等組成。
符號串就是由符號集中的元素組成的序列。例如給定符號集{a,b,c}
,那麼abc
、abb
、ac
就是由該符號集組成的符號串。
文法的形式化定義
文法的形式化定義可以表述爲 ,其中:
- 爲終結符集合
- 爲非終結符集合
- 爲產生式集合
- 爲開始符號
何爲終結符?在編程語言中,終結符可以理解爲不能再進行拆分的基本符號,例如C語言中的if
、else
、while
關鍵字,也可以是一個變量名、數字。
和終結符相反,非終結符就是可以再進行拆分的符號,它可以推出其它的語法成分。如果要對一個非終結符進行語法分析,就需要對它需要進行遞歸分析。在C語言的if-else
文法中,if
或者else
後面跟着的代碼塊可以看成是非終結符。
一個文法含有一個或多個產生式,產生式描述了將終結符集合和非終結符集合組合成串的方法。其一般形式爲 ,其中:
- 稱之爲產生式的頭或左部,並且 ,表示至少要包含中的一個元素。
- 稱之爲產生式的體或右部,並且,表示可以包含零個或多個中的元素。
對於文法產生式當中的符號,我們約定終結符爲:
- 英文小寫字母,如
a
、b
、c
等 - 運算符,如
+
,*
等 - 標點符號,如逗號,括號等
- 數字
- 粗體字符串,如if、else等
- 希臘字母
ε
爲空串
非終結符約定爲:
- 英文大寫字母,如
A
、B
、C
等。其中字母S
通常表示爲開始符號 - 小寫、斜體的名字,如expr、stmt等
- 代表程序構造的大寫字母。如
E
(表達式)、T
(項)和F
(因子) - 字母表中排在後面的大寫字母(如X、Y、Z)表示文法符號(即終結符或非終結符)
- 字母表中排在後面的小寫字母(主要是u、v、…、z)表示終結符號串(包括空串)
- 小寫希臘字母,如
α
、β
、γ
,表示文法符號串(包括空串)
如非特別說明,第一個產生式的左部就是開始符號。
文法的分類
文法分爲0型、1型、2型、3型四種,它們之間的差別在於對產生式施加的不同限制,形似於數據庫不同範式之間的差異。我們在判斷時,一般先覈對該文法是否是3型文法,如果不是再覈對是否是2型文法,依次往下推。
下面給出各個文法的定義
0型文法
當文法 的每個產生式 滿足以下條件:
- 至少含有一個非終結符
則稱文法 爲0型文法。0型文法又稱短語文法,任何0型語言都是遞歸可枚舉的,反過來也成立。
1型文法
文法 的每個產生式在 滿足0型文法的要求外,還滿足以下要求:
- (絕對值符號代表集合中元素的個數)
- 除外
則稱文法 爲1型文法,又稱上下文有關文法。
例如文法,、的產生式爲:
因爲每個產生式都滿足右部元素數量大於等於左部數量,並且沒有產生式爲 ,所以文法 是一個1型文法。
2型文法
文法 的每個產生式 在滿足1型文法的要求外,還滿足以下要求:
- 僅僅是一個非終結符
則稱此文法是2型文法,又稱上下文無關文法。
例如文法 ,、,產生式爲:
(等價於兩個產生式: 和 ,符號|
含義爲“或”)
該文法就是一個2型文法。
3型文法
文法 的每個產生式滿足2型文法外,還滿足以下要求:
- 形如 和 ,
- 、都是非終結符
- (爲非終結符的零個或多個元素)
則稱文法 爲3型文法,又稱正規文法。
語法樹
語法樹又稱語法分析樹或分析樹。
給定文法 ,對於 的任何句型都能夠構造出與之相關的語法樹,這顆樹滿足4個條件:
- 每個結點都有一個標記,這個標記屬於 或者
- 根的標記是
- 若一個結點 至少有一個子結點,那麼
- 如果結點 的直接子節點從左到右的順序爲 ,其標記分別爲 ,那麼產生式 一定是文法 產生式集合 中的元素。
語法樹表示了在推導過程中採取了哪個產生式和使用在了哪個非終結符上,它並沒有表明採用的產生式的順序。
根據語法樹定義,我們可以畫出文法 的語法樹。
例題:給出文法 ,其中 包含:
上述文法可以有三種推導方式:
該推導總是選擇最右邊的非終結符,並找出以該非終結符爲左部的產生式進行遞歸推導,該推導方式爲最右推導,也被稱之爲規範推導。
該推導總是選擇最左邊的非終結符,並找出以該非終結符爲左部的產生式進行遞歸推導,該推導方式爲最左推導。
該推導則是根據情況選擇不同的產生式來替換非終結符
上述三種推導方式得到的語法樹都爲:
如果一個文法存在某個句子對應兩棵語法樹,那麼則稱該文法是二義的。根據現有理論,無法判斷一個文法是否是二義的,因爲這個問題是遞歸不可解的。