從txt檔案中讀入正規表示式
#include
#include
#include
#include
#include
#define max_token 100
using
namespace std;
//詞struct token
;int
readtxt
(string filename,vector
&tokens)
//讀取正規表示式
string line;
//讀入的每一行
while
(getline
(input,line)
) temp.regexp=line.
substr
(i+1
,line.
size()
-i);
//獲取詞的正規表示式
tokens.
push_back
(temp);}
input.
close()
;return0;
}
把使用連線運算的地方換成「.」(符號可自定義),然後將中綴正規表示式轉成字尾表示式。
#include
#include
#include
#include
#include
#include
using
namespace std;
//把兩字元之間的連線加上.
string add_symbol
(string reg)
//a.( )
else
if(reg[i+1]
=='('
&®[i]
!='|'
&®[i]
!='(')}
return rege;
}//運算子優先順序表
char
*priorities=
;//運算子編號
intgetnum
(char c)
}//中綴轉字尾
string convert
(string reg)
//運算子處理
else
op.pop();
//彈出左括號,不輸出
break
;default
://優先順序大於棧頂優先順序
if(op.
top()==
'('||
(op.
top()!=
'('&&priorities[
getnum
(op.
top())
][getnum
(reg[i])]
=='//優先順序小於棧頂優先順序
else
op.push
(reg[i]);
}break;}
}}while
(!op.
empty()
) post.
pop_back()
;//去掉'#'
return post;
}
遇到字母,構建基本nfa(我這裡用cell資料結構表示),入棧
遇到運算子,出棧相應數量的nfa(如:| 作為雙目運算子,就要出棧兩個nfa),然後構建對應的nfa,入棧
#include
#include
#include
#include
#include
#include
#define max 5000
using
namespace std;
/*注意狀態總數量和狀態編號是不同的,因為狀態總數可能減少(連線運算),但編號是一直增下去的*/
int state_count=0;
//狀態的總數量
int nmbstate=1;
//狀態編號
int nullsymbol=0;
//輸入字元為?的邊的數量
struct state
;struct edge
;//單個nfa單元
struct cell
;//合併後正則的nfa
struct bigcell
;//單個字元nfa
cell makenfa
(char c)
//把s中的邊複製到t中
intedgescopy
(cell s,cell &t)
}//把s中的邊複製到t中
intedgescopy
(cell s,bigcell &t)
}//或運算nfa
cell ornfa
(cell left,cell right)
//連線運算nfa
cell andnfa
(cell left,cell right)
//改變結束狀態是right的開始狀態的邊
else
if(right.start.id==right.edges[i]
.target.id)
} right.start.id=left.end.id;
edgescopy
(right,left)
; left.end.id=right.end.id;
return left;
}//星閉包運算nfa
cell starnfa
(cell a)
cell reg2nfa
(string reg)
} current=s.
top();
s.pop();
return current;
}int
shownfa
(cell c)
cout<
return0;
}int
shownfa
(bigcell c)
cout<
return0;
}
因為最後要構建詞法分析器,所以做成乙個大的nfa後期識別會比較方便,因此可選擇將每個正規表示式的nfa合併為乙個大的。
具體方法是把新增乙個狀態0,把所有nfa的起點連起來。
//將各個正規表示式的nfa合併
bigcell mergenfa
(vectornfa)
return nfa;
}
輸入:數字、字母及自定義id的正規表示式
輸出:每一條邊的 起點 輸入字元(』?』 代表空) 終點
正規表示式轉NFA
最近一直在忙著寫大作業,考試複習,複習演算法的時候寫了一些隨筆,現在忙起來都落下了部落格,這裡有乙個vc 寫的大作業,主要是正規表示式轉nfa並顯示。內容如下。介紹一下nfa在表示的結構設計,由於nfa本身是一種有向圖,所以這裡的儲存結構設計和鄰接表相似,圖中的每個節點後面是一些與其連線的節點的值,...
正規表示式轉NFA
正規表示式有三種基本的運算 連線 concatenation 例如 abc,由a,b,c組成 聯合 union 例如 a b c,表示a或者b或者c kleene閉包 kleene 例如 ab 表示ab串不出現,或者出現1次或一次以上 其它的運算如 等都可以用以上三種基本運算或者運算的組合來表示。2...
編譯原理中的正規表示式 NFA和DFA
from 正規表示式,接觸得已經不少,各種語言都會有些正規表示式的庫來增強字串處理功能,這裡就編譯原理的詞法分析要用到的內容 下下。嗯,我很懶 還是課件截圖 這裡用遞迴定義來定義正則的,原因是簡潔方便,方便以後進一步學習,比如nfa。如果要說正規表示式的術語定義,又得找維基了,鏈結 在電腦科學中,是...