學完了詞法分析,我們知道詞法分析器將正規表示式轉換成詞法單元流,但對於這個記號流我們不知道是否能由正確的文法產生,因此我們需要通過語法分析器來檢測其合法性。語法分析器的輸出是一棵語法分析樹(無論顯性還是隱性),並且進行一些語法糾錯處理。語法分析的整個過程大概就是我們先定義乙個語法,再用相應的演算法來檢測我們的詞法單元流是否符合該語法。這裡主要討論上下文無關文法構成的語法和自頂向下、自底向上的語法分析。
定義為乙個四元組(vt,vn,s,p)
類似自動機的定義,不過是語法的產生式。
為什麼要叫上下文無關文法呢?因為產生式的左邊只有乙個符號,也就是說只要滿足了右側的串就可以直接歸約到左邊的符號,不需要檢視上下文。與此相對的上下文有關文法例如asb -> abab 就是上下文有關文法。
把產生式看成重寫規則,符號串中的非終結符用產生式右部的串(α)代替。
推導具有自反性,傳遞性。
舉例:有以下文法: s->s(s)s|e 如何用最左推導推導出串 (()())?
法一:s=>s(s)s=>e(s)s=>e(s(s)s)s=>e(s(s)s(s)s)s=>e(e(s)s(s)s)s=>…=>e(e(e)e(e)e)e
法二:s=>s(s)s=>e(s)s=>e(s(s)s)s=>e(e(s)s)s=>e(e(e)s)s=>e(e(e)s(s)s)s=>…=>e(e(e)e(e)e)e
我們每次遵循必須替換掉最左邊的s的原則,嘗試每一種匹配,如果失敗,退回,選擇下一匹配,直到成功。這樣我們得到了乙個串的最左推導。不過以上例子我們得到了兩個不同的最左推導,並且都是嚴格遵照了最左推導的要求來的。因此,我們說這個文法具有二義性。計算機不喜歡二義性,計算機喜歡單刀直入,因此後面我們會看到消除二義性的辦法。
語法分析樹是推導的圖形表示。乙個推導對應一棵語法分析樹。
我們對上例法一進行語法分析樹的構建(e就是空串):
總之,就是將左推導展開成樹的形式。
所謂自頂向下分析,就是從分析樹的頂部向底部構造分析樹,也即從開始符號s推出整個串的過程。自頂向下分析採用最左推導,因為分析器是從左到右掃瞄的。
然而,有的文法不能採用自頂向下分析,因為產生了左遞迴。
1.直接左遞迴
使用公式:
(原始)
a → aα1 | aα2 | … | aαm| β1 | β2 | … | βn
(轉化)
a → β1 a』 | β2 a』 | … | βn a』
a』 → α1a』 | α2a』| … | αma』 | e
2.間接左遞迴
間接左遞迴就是要通過多次推導才能看出文法有左遞迴。如:
s→qc|c,q→rb|b,r→sa|a有s =>qc =>rbc =>sabc
先轉變成直接左遞迴,再使用公式。
把所有關於s的文法帶入,並且得到直接左遞迴的公式,例如上面的文法:
q→(sa|a)b即q→sab|ab|b
s→sabc|abc|c|bc
然後就可以使用公式了。
這一節的主要內容應該是自頂向下分析,為了構建這一棵語法樹,我們使用上下文無關文法,定義了推導的概念,發現我們要使用左推導,並且解決了二義性,順便消除了左遞迴,這才成功構建出這樣一棵語法樹。
上下文無關文法
1 上下文無關文法又稱cfg。許多cfg由幾個較簡單的cfg合併起來。可以先構造每個部分的cfg,比如 s1,s2,s3.sk。然後加入新的規則s s1 s2 sk 2 例如 構造語言 的cfg,1 構造 s1 0 s1 1 2 s2 1 s2 0 3 整合 s s1 s2 3 如果語言是正則的,可...
上下文無關文法
上下文無關文法 context free gammar 指文法的前後 上下 沒有關係,如文法 statement name is name s friend.是上下文無關文法,因為文中出現的兩個 name 可以不同 也可以相同,假設自己可以是自己的朋友 而文法 statement name like...
上下文無關文法
1 上下文無關文法又稱cfg。許多cfg由幾個較簡單的cfg合併起來。可以先構造每個部分的cfg,比如 s1,s2,s3.sk。然後加入新的規則s s1 s2 sk 2 例如 構造語言 的cfg,1 構造 s1 0 s1 1 2 s2 1 s2 0 3 整合 s s1 s2 3 如果語言是正則的,可...