有了前文中的積木,繼續實現一個詞法分析器就不再困難。
先回顧一下各個模塊:
然后我們試圖將他們組裝起來,因為一開始實現的都是零件(子函數)部分,本文主要介紹在main函數中運行的自動機。
還記得-1篇中的DFA嗎?
經過第0篇,以及滿足題目要求,我們最終的DFA應該是這樣:
流程大致為:
按照以上思路,經過不斷地調試完善,主函數設計為:
int main()
{
initialize();
string tmp;
char c;
while((c = getchar()) != EOF)
{
if(isspace(c)) // 忽略空白
continue;
if(isdigit(c)) // 如果是數字開頭
{
ungetc(c, stdin);
cout << "DIGIT : " << num() << endl;
continue;
}
char peek;
peek = getchar(); // 一步提前量
if((c == '+' || c == '-') && isdigit(peek)) //輸入帶符號數
{
ungetc(peek, stdin);
ungetc(c, stdin);
cout << "DIGIT : " << num() << endl;
continue;
}
if(c == '/' && peek == '*') //輸入注釋
{
cout << "COMMENTS : /*" << comments() << endl;
continue;
}
int tkn = 0;
string s;
if(!isalnum(c)) // 輸入c為專用符號
{
s += c;
if(peek == '=') // 所定義的雙目運算符中第二個只有 = 可以偷懶;
s += peek;
else ungetc(peek, stdin);
tkn = query(s);
}
if(!tkn){ // 若不是專用符號開頭,即為字母開頭
ungetc(peek, stdin);
s += c;
while((c = getchar()) != EOF) // 讀入這一串字母
{
if(isspace(c)) break;
if(isalnum(c) || c == '_')
s += c;
else{
ungetc(c, stdin);
break;
}
}
tkn = query(s); // 查詢token
}
switch (tkn) // 依據token打印
{
case 1:
cout << "KEYWORD : " << s << endl;
break;
case 2:
cout << "BASIC : " << s << endl;
break;
case 3:
cout << "IDENTITY : " << s << endl;
break;
case 5:
cout << "SYMBOL : " << s << endl;
break;
default:
break;
}
}
return 0;
}
測試
使用測試樣例1:
{ /* An example */
int i,j; float x; float[100] a;
while ( true) {
do i = i + 1; while ( a[i] < x);
if ( i >= j ) break;
x = a[i];
}
}
輸出結果:
// line 1 { /* An example */
SYMBOL : {
COMMENTS : /* An example */
// line 2 int i,j; float x; float[100] a;
BASIC : int
IDENTITY : i
SYMBOL : ,
IDENTITY : j
SYMBOL : ;
BASIC : float
IDENTITY : x
SYMBOL : ;
BASIC : float
SYMBOL : [
DIGIT : 100
SYMBOL : ]
IDENTITY : a
SYMBOL : ;
// line 3 while ( true) {
KEYWORD : while
SYMBOL : (
KEYWORD : true
SYMBOL : )
SYMBOL : {
// line 4 do i = i + 1; while ( a[i] < x);
KEYWORD : do
IDENTITY : i
SYMBOL : =
IDENTITY : i
SYMBOL : +
DIGIT : 1
SYMBOL : ;
KEYWORD : while
SYMBOL : (
IDENTITY : a
SYMBOL : [
IDENTITY : i
SYMBOL : ]
SYMBOL : <
IDENTITY : x
SYMBOL : )
SYMBOL : ;
// line 5 if ( i >= j ) break;
KEYWORD : if
SYMBOL : (
IDENTITY : i
SYMBOL : >=
IDENTITY : j
SYMBOL : )
KEYWORD : break
SYMBOL : ;
// line 6 x = a[i];
IDENTITY : x
SYMBOL : =
IDENTITY : a
SYMBOL : [
IDENTITY : i
SYMBOL : ]
SYMBOL : ;
// line 7 }
SYMBOL : }
// line 8 }
SYMBOL : }
可以發現輸出結果是完全正確的。
測試樣例2:測試數字
+1212.551e1589
輸出:
DIGIT : +1212.551e1589
好,到此,我們就完成了本次實驗任務,一個簡單的詞法分析器的設計,在設計過程中,我們使用到了Trie樹這一數據結構,使得代碼變得美觀了許多,同時,針對較為復雜的數字讀取行為,我們設計了一個DFA確定的有限狀態自動機完成,最終,我們在main函數中,將他們拼接起來,就形成了最后的詞法分析器,整個實驗用時半天,整體思想并不難理解,相信大家如果從頭看到此處應該邏輯會相當清晰。
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
分析器
+關注
關注
0文章
92瀏覽量
12486 -
有限狀態自動機
+關注
關注
0文章
2瀏覽量
889
發布評論請先 登錄
相關推薦
LabVIEW 生命小游戲 元胞自動機
生命小游戲,又叫元胞自動機,一個令人著迷的圖靈完備系統參考資料:https://zhuanlan.zhihu.com/p/347305597https://www.zhihu.com
發表于 02-12 18:33
NFA→FA→GFA自動機轉換算法
研究了不確定有窮自動機NFA、確定有窮自動機FA、規范有窮自動機GFA的基本關系與等價轉換;給出了“NFA→FA”等價轉換算法與“FA→GFA”等價轉換算法,構造性證明了從FA到GFA的存
發表于 12-10 17:25
?14次下載
加性細胞自動機的同構性分析
根據矩陣方程理論和細胞自動機原理,提出了加性細胞自動機狀態轉移結構的同構性方法,該方法利用狀態轉移矩陣方程及其特征多項式分析規則90和150加性細胞自動機,證明了特
發表于 02-28 17:03
?35次下載
[自動機與自動線].李紹炎.掃描版
本書結合目前國內自動機械行業的現狀,從應用的角度系統介紹了自動機械的模塊化結構及工作原理、設計選型方法、裝配調試及維護要領等。主要內容包括:自動機械的結構組成、輸
發表于 09-17 16:02
?0次下載
異步多進程時間自動機的可覆蓋性問題
已有的實時系統模型無法動態創建新進程.為此,基于時間自動機模型,提出了異步多進程時間自動機模型,將每個進程抽象為進程時間自動機,其部分狀態能夠觸發新進程,考慮到隊列會導致模型圖靈完備,進程都被緩存
發表于 12-29 14:10
?0次下載
基于統計的AC自動機空間優化
基于訪問頻率、訪問層次以及結合上述2種特征對AC自動機的部分節點實現完全化的算法。在Snort、ClamAV、URL等真實數據集上的實驗結果表明,HybridFA算法的存儲空間低于高級AC自動機的5%。此外,結合訪問頻率和訪問層
發表于 03-13 16:47
?0次下載
自動機器學習簡述
自動機器學習(AutoML)的目標就是使用自動化的數據驅動方式來做出上述的決策。用戶只要提供數據,自動機器學習系統自動的決定最佳的方案。領域專家不再需要苦惱于學習各種機器學習的算法。
自動機終結字查找算法實現優化綜述
自動機的秩與工業自動化中的部件定向器設計問題和理論計算機科學中的 Cerny-pin猜想密切相關。計算自動機的秩可以歸結于查找
發表于 04-28 15:49
?3次下載
評論