編譯原理筆記第三部分,因爲內容過長因此分爲了兩部分,跳轉連接在總閱讀目錄處,內容參考:北航軟院教師邵兵課堂課件及內容、張莉著《編譯原理及編譯程序構造》、國防工業出版社的《編譯原理——學習指導與典型題解析》、AlvinZH的學習筆記以及我的理解html
目前是包含了所有內容的版本,後續會推出精簡版和複習知識點版正則表達式
若有建議或錯誤錯誤歡迎在評論中指出或聯繫我:QQ:847590417算法
本章總內容函數
第一部分:工具
3.1 詞法分析程序的功能及實現方案學習
3.2 單詞的種類及詞法分析程序的輸出形式編碼
3.3 正則文法及狀態圖spa
3.4 正則表達式與有窮自動機FA設計
第二部分:3d
重點:詞法分析介紹、詞法分析單詞種類劃分、正則文法、狀態圖、正則表達式、自動機、自動機的轉化、表達式文法和自動機的轉化、詞法分析程序的設計實現,詞法分析程序自動生成器LEX。
以前的內容
詞法分析介紹、詞法分析單詞種類劃分、正則文法、狀態圖、正則表達式、自動機、自動機的轉化會在第三章的第一部分進行介紹。
轉化流程圖:
如下轉換的順序是按圖上箭頭的順序進行排序的(NFA包含DFA,因此和NFA的轉化可能稱之爲DFA的轉化)。
繪製左線性文法的狀態圖(狀態圖只能用於左線性文法,這是和後面的DFA的明顯區別)狀態圖的繪製沒有嚴格規定(右線性的暫時不作考慮)
1.文法的非終結符號是一個個的結點
2.設一開始狀態S(句子)
3.對規則Q::=t(t爲終結符),須要一條從S到Q的一條弧,弧上標記爲t
4.對Q::=Rt,畫一條從R到Q的弧,弧上標記爲t
(倒,誰規約於誰,誰指向誰)
5.根據自動機方法,可加上開始狀態和終止狀態標誌,識別符號做終止狀態,用雙圓圈標識
規則:
1.對(A,t) = B,寫成:A→tB(只推右線性,左線性在推導時可能遞歸)
2.對每一個可接受狀態Z(終止狀態),增長產生式Z→ε
3.有窮自動機的初態對應文法開始符號,有窮自動機的字母表爲文法的終結符號集
例:
規則:(和狀態圖的轉化相似)
1.字母表(弧上的全部符號組成的表)和G的終結符號相同
2.爲G中的每一個非終結符生成M的一個狀態,G大的開始符號S是開始狀態S
3.增長一個新狀態Z,做爲NFA的終態
4.對G中的形如A→tB,其中t爲終結符或空字符,A和B爲非終結符號的產生式,構造M的一個轉換函數(A,t)=B
4.對G中形如A→t的產生式,構造M的一個轉換函數(A,t)=Z
例:
他們是等價的
定理:在Σ上的一個字集V,V是Σ*的子集,是正則集合,當且僅當存在一個DFA M使V=L(M).
規則:
一個正則表達式,構建時從左到右拆解分析便可
a. 對空集φ不做處理
b. 對正則式ε,由x射出符號爲空符號的弧到y
c. 對字母表中存在的字母符號如正則式a,由x射出符號爲該字符的弧到y
(x,y爲狀態,只是構建的臨時初態終態,符號便是正則表達式中讀取到的字符(從左到右分解))
多個正則式,例如s,t,他們的NFA爲Ns和Nt
a. R=s|t
b. R=st
c. R=s*
d. R=(s),和R=S的NFA同樣
例:
1.從裏開始構建NFA
2.從外開始構建
規則:
(1)在M上加兩個結點x,y。從x用空符號弧鏈接到M的全部初態節點,從M的全部終態節點用空符號弧鏈接到y,造成和M等價的的M’,此時只有一個初態一個終態。
(2)消除M’中的其餘節點(除了x,y)
1.鄰合併
2.並變或
3.遞歸加邊加星號
即正則表達式轉NFA倒過來
例:
三個規則,可將正則文法轉換爲一個只剩一個開始符號的產生式,而且右側不含非終結符,僅含對應的表達式。轉換後的產生式應用擴充的BNF表示,而在標識符好的0~n次重複時應該用*代替
(1)代入規則:對A→xB,B→y轉化爲A→xy
(2)消除遞歸規則:對A→xA|y轉化爲A→x*y
(3)BNF規則:對A→x,A→y轉化爲A→x|y
注:左線性的話,對A→Ax|y轉化爲A→yx*
例如:
例:
規則以下:
(1)對任何正則表達式r,選擇一個非終結符S做爲識別符號,併產生產生式S→r
(2)若x,y是正則表達式:
1.對A→xy,轉化爲A→xB,B→y,B爲新的非終結符
2.對A→x*y,轉化爲A→xA,A→y(注:對A→x*y,則須要轉化爲A→xA,A→ε)
3.對A→x|y的產生式
例如:
例:
左線性的話:(會死循環)
說明:
1.對於註釋符號是不輸出的
2.各單詞之間用空白符號(空格、製表、回車)分開
在得知文法後
須要根據文法將全部終結符號的轉化過程給繪製出來(初始符號就是每一個終結符號)
這裏出現的其餘字符,實際是任意字符,例如讀到+後再讀入+,後一個+相對於前一個也是其餘字符。
而後將這些轉化過程都結合起來,初始狀態當作傳入的符號串。合併後還須要注意:對重複符號進行特殊處理(單雙字符分界符處理合並),還須要一個出錯的狀態(符號串不屬於任一流程)。
不一樣狀態的作法
開始狀態:利用程序依次讀入字符,讀到空字符就跳過,而後對每個非空字符串轉到程序中進行處理。
標識符狀態:在組合成標識符後,判斷是保留字仍是用戶自定義的
整數狀態:組成數字後還要作數字字符到二進制數值的轉換
單字符分界符狀態:判斷對應的類別編碼便可
冒號狀態:須要和下一個字符結合進行判斷,是單字符仍是雙字符
斜豎狀態:一樣須要判斷後面的字符,做爲字符仍是跳過註釋
錯誤狀態:打印錯誤信息並跳過
注:在詞法分析時爲了判別是否已經讀到了單詞的右端符號,有時候須要向前多讀一個字符,例如在標識符和無符號整數等狀態。這是爲了防止跳過某個不應跳過的字符。因此在返回調用程序前應該將讀字符指針後退一個字符。(字符指針後退實際就是退到前一個字符,由於在讀取字符時可能多讀一個字符,致使後面讀取時這個字符就被忽略了,因此須要後退(字符指針是一直前進的,後退就是向上一個讀的字符吐出來一個))
一個詞法分析程序須要:1.單詞及內部表示 2.詞法分析程序須要引用的公共(全局)變量和過程 3.詞法分析程序算法
1.輸出形式:即按單詞及內部表示的規定進行(通常是二元式,一個是類別編碼,一個是對應的單詞值)
2.全局變量和過程(即一個詞法分析程序須要引用的變量和過程,通常提早定義好須要使用的,須要用時調用便可)
3.詞法分析程序算法
其實算法程序的具體結構仍是由開發者決定的,例如是否進行字符流的回退,如何進行類型的判斷等等,都是由具體的實現進行決定的。
將以前的完整狀態圖構造爲算法便可
僞代碼:
當詞法分析程序做爲子程序時,通常由語法分析程序調用,當詞法分析程序組合出一個單詞時就返回給語法分析語句,而且返回時應將單詞的類別碼送入變量單元symbol。(語法分析程序中會設有變量class,用於存放單詞的類別碼)
功能:輸入LEX源程序即可通過LEX後生成詞法分析程序L
而後輸入S.P.字符串通過L即可輸出S.P.單詞字符串
主要由三部分組成:
1.規則定義式,定義識別規則中要用到的正則表達式名
2.識別規則,用正則表達式給出單詞的定義和在識別後的下一步行爲(例如要直行的代碼片斷)
3.用戶子程序,給出用戶須要的其餘操做
各部分之間須要用%%分開
規則定義式:以下形式的LEX語句
,D爲正則表達式名字,簡名;R爲正則表達式
例如:
識別規則:一串以下形式的LEX語句
P爲定義在Σ∪{D1,D2,D3.....}上的正則表達式,詞形
A爲語句序列,是指識別出詞形爲P的但此後,詞法分析器所應作的動做,基本動做即返回單詞的類別編碼和單詞值。
一個完整的LEX源程序:
小提示:正則中{}+,表示至少1次重複
LEX的功能是根據LEX源程序構造一個此法分析程序,該詞法分析器實質上是一個有窮自動機。
LEX生成的詞法分析程序由兩部分組成:狀態轉換矩陣DFA和控制執行程序。則有LEX的功能即根據LEX源程序生成狀態轉換矩陣和控制程序。
LEX的處理過程:
NFA(空符號,多後繼),DFA必定是NFA
轉化成的DFA,每一個新的終止狀態所識別的單詞類型,根據該子集包含的原NFA的終止狀態而定,只包含一個,則就是那個終止狀態是別的單詞,若是多個,則須要加一個或。
1.掃描每條識別規則P構造一相應的非肯定有窮自動機M
2.將各條規則的有窮自動機Mi合併成一個新的NFA M
3.NFA肯定化爲DFA
4.生成該DFA的狀態轉換矩陣和控制執行程序
LEX的二義性原則,兩原則
例如begin是關鍵字仍是標識符
1.最長匹配原則
在識別單詞過程當中,有一字符串根據最長匹配原則,應識別爲這是一個符合Pk規則的單詞而不是小範圍的:
2.最優匹配原則
若有一字符串,有兩條規則能夠匹配,那麼用規則序列中位於前面的規則相匹配,即排列在前面的的規則優先權高。
LEX實例:
1.得出單獨的NFA
2.合併爲一個NFA
3.肯定化
4.最後寫出狀態轉換矩陣和控制程序便可
分析過程:
構造出的LEX是一個通用的工具,用它能夠生成各類語言的語法分析程序,只須要根據不一樣的語言書寫不一樣的LEX源文件就能夠了。
LEX不但能自動生成詞法分析其,並且也能夠產生多種模式識別器及文本編輯程序。
在描述推導過程是,若是有了根據...,則沒必要再說一個「可得」了
作題時注意判斷全部的終結符和非終結符,看題
判斷短語:在一句型的語法樹中,對任意結節點U,若是以其爲根節點的子樹高度不爲0,將此子樹的全部葉節點鏈接獲得串u,u則是相對於U的對於該句型的短語,也就是說即便在樹的最後,只要有f→p,且p後無延伸,則p自己也是一個短語,且是一個簡單短語。
在繪製特定描述的字符串自動機時,直接編寫語法可能會不夠隨機,能夠用狀態圖進行輔助。
在根據集合獲取對應字符的後繼集合時,步驟以下:遍歷集合的每一個狀態,獲取每一個狀態經過任意長度符號爲該符號的弧到達的狀態以及從該狀態通過任意長ε弧到達的狀態(不包含出發的那個狀態,除非能夠經過這兩種方法到達)。遍歷結束後彙總獲取到的狀態便可得到新的集合。
左右線性:根據右側非終結符的位置而定,在左則左。
左右線性文法生成狀態圖:後續補充。
給出描述的正則表達式時,注意幾個點:保持隨機,分段構造表達式,注意符號的真正含義(*是重複,而且是從0到無窮的,而且若是沒括號只能重複一個,例如(11)*就是偶數個重複)。
表達式構造FA:從外開始從左開始,而且*轉時,兩個ε不是必需的,什麼時候使用??
進行肯定化時因爲是集合類型,因此注意看清
判斷NFA:同一個符號兩個後繼、有ε弧
FA的五元:所有狀態,所有符號,轉化矩陣,開始狀態(非空開始集合),終止狀態集合。注意狀態轉化後若是是{},就是多個後繼。