一、正則式(regular expression)
1.正則式定義:
ε表示語言,a表示語言,(r)|(s)表示語言l(r)並l(s),(r)(s)表示語言l(r)l(s),(r)*表示語言(l(r))*
正則式優先順序為 閉包》連線》或,即((a)(b)*)|(c)寫為ab*|c 。
再給一些例子:(a|b)(a|b)定義的語言為,(a|b)*定義為由a和b表示的所有串集。
2.c語言識別符號的正則定義:
letter_ → a|b|...|z|a|b|...|z|_
digit
→0|1|...|9id→
letter_(letter_ | digit)*
3.正則式和上下文無關文法比較:
任何正則式都可寫出上下文無關文法(更準確地說為正規文法,即3型文法)。
如正則式 (a|b)*ab 一定能給出上下文無關文法(由於可以給出它的nfa,之後會介紹)
→aa0 | ba0 | aa1 狀態0可由a轉換到狀態0,可由b轉換到狀態0,可由a轉換到狀態1。a1→
ba2 狀態1可由b轉換到狀態2a2→
ε 狀態2為結束因此對應空串
二、有限自動機(finite automata)
1.非確定有限自動機(nfa):
如需要識別語言 (a|b)*ab ,可引出如下非確定有限自動機
非確定有限自動機中,當前狀態與乙個輸入能轉換到多個狀態,如狀態0輸入a後既能轉換到狀態0又能轉換到狀態1,上圖中兩個圈(狀態2)表示該狀態為結束狀態(可認為一到該狀態就返回成功識別)。
只要包含如下特徵任意乙個就是非確定有限自動機:1.當前狀態與乙個輸入對應多個轉換狀態,2.存在ε輸入。
非確定有限自動機用程式實現比較困難,因此需要變換為確定有限自動機。
注:如果結束狀態右邊加乙個星號*則表示結束後還要吐出乙個字元。
2.根據正規式畫非確定有限自動機:
根據以上規則,可一步步得到正規式(a|b)*ab的nfa
3.確定有限自動機(dfa):
如需要識別語言 (a|b)*ab ,可引出如下確定有限自動機
必須滿足如下:1.當前狀態與乙個輸入對應最多乙個轉換狀態,2.不存在ε輸入。
因此確定有限自動機對應乙個二維陣列
4.非確定有限自動機確定化(子集構造法):
用乙個例子說明,有如下非確定有限自動機表示 (a|b)*ab,將其確定化。
<1>——開始狀態能夠經過空轉換到達的合成乙個狀態,即由0的ε閉包構成dfa的開始狀態a
a=<2>——由a的a閉包狀態集合構成dfa狀態b
b=<3>——由a的b閉包狀態集合構成dfa狀態c
<4>——依次類推,直到沒有新狀態,最後得到
a=,b=,c=,d=
其中包含原nfa結束狀態9的必為現dfa的結束狀態。
例題1:
設有正則式 r = (a|ab) (a|b)* b
1.構造nfa,2.轉化為dfa,3.給出正規文法(3型文法)。
解:
(1)構造nfa比較容易,根據二.2直接給出答案。
(2)轉化為dfa,運用二.4子集構造法。
<1>——開始狀態空閉包
x0=<2>——x0狀態a閉包
x1=<3>——x0狀態b閉包無,再求x1狀態a閉包
x2=<4>——x1狀態b閉包
x3=<5>——求x2狀態a閉包(為x2),再求x2狀態b閉包(為x3),再求x3狀態a閉包(為x2),再求x3狀態b閉包(為x3),得到最終狀態轉換圖,即可畫出對應dfa。
(3)給出正規文法,即3型文法。x0→
ax1 x0狀態所有指向 x1
→ax2 | bx3 x1狀態所有指向 x2
→ax2 | bx3 x2狀態所有指向x3→
ax2 | bx3 | ε x3狀態所有指向,結束處要加乙個空串
編譯原理 詞法分析器
1 從源程式檔案中讀入字元。2 統計行數和列數用於錯誤單詞的定位。3 刪除空格類字元,包括回車 製表符空格。4 按拼寫單詞,並用 內碼,屬性 二元式表示。屬性值 token 的機內表示 5 如果發現錯誤則報告出錯 6 根據需要是否填寫識別符號表供以後各階段使用 int tag 0 設立標誌 一開始本...
詞法分析器
這是我自己的第一篇部落格,就分享一下最近才做完的編譯原理實驗,詞法分析器。本次實驗中我用mysql資料庫儲存自動機狀態表,這樣做的目的只是為了在後續的課設中可以繼續使用現在的 這一段 並不是太完善,發出來只是為了太完善。裡面還有很多問題,比如對字元和字串的識別,不知道為什麼資料庫無法將 和 轉換到我...
詞法分析器
include using namespace std const int maxn 1e3 10 int n 輸入文字的行數 char buffer maxn maxn 緩衝區 int len maxn 輸入文字每行的列數 struct out 輸出格式 out string a,int b re...