lex實現擴充套件的pl0語言的詞法分析器(附原始碼)
詞法分析器實驗報告
文章目錄
實驗目的
- 理解編譯器的工作機制,掌握編譯器的工作原理
- 掌握詞法分析器生成工具LEX的用法
實驗構成以及說明
實驗說明
-
使用LEX實現擴充套件的pl0語言的詞法分析器
-
pl0語法擴充套件包括:
-
支援字元型別及相關運算
-
支援浮點型別及相關運算
-
支援整形陣列
-
支援for迴圈語句
-
支援repeat語句
-
-
保留字:
if | then | while | do | read | write | call | begin | end | const | var | procedure | odd | for | to | repeat | until|of|Array
for, to, repeat, until, of, Array 這幾個保留字是根據擴充套件語法新加入的
-
界符
“[”|"("|")"|","|":"|";"|"."|"]"|"…"
[]和…會在array宣告中用到
-
語句型別:
- 賦值語句:if…then…, while…do…, read, write, call,
- 複合語句:begin… end,
- 說明語句: const…, var…, procedure…
- 重複語句:for…to…, repeat…until…
-
輸出型別:
- K類(關鍵字)
- I類(識別符號)
- C類(常量)
- O類(算符)
- D類(界符)
- T類(其他) 將錯誤的型別,比如長度不和規範的識別符號、常量,含有非法字元的識別符號也歸於此類
程式碼說明
輔助定義
-
real型別支援負數運算,並且支援科學計數法
-
integer型別和real型別都有長度限制
-
array型別,採用pascal的陣列宣告方式
-
illegal是非法型別
將所有正確的字元排除以後的所有其他字元或是字串全部算作非法型別
-
空格、回車、換行符、製表符分開處理,在打印出分析結果時,沒有輸出空格
digit [0-9]
letter [a-zA-Z]
identifier {letter} ({letter}|{digit})*
integer {digit}+
real -?{digit}+(\.{digit}+)([Ee][-+][0-9]+)?
whitespace [ ]
newline [\n]
return_ [\r]
col_8 [\t]
char (\'[^ \n\r\t]\')
string (\".{2,}\")
array Array\ \[(1\.\.{integer})(\,1\.\.{integer})*\]\ of\ (integer|real|char|string)
t_1 ([^\t\n\f\v\r ])([_?!$&#@`]+)({letter}|{digit})+
t_2 ({digit}+){letter}({letter}|{digit})*
識別規則
- {integer}|{real}|-{integer} 包含對於常量長度的檢查
- {char} 包含對char型別的檢查(是否只包含一個字元)
- {identifier} 對識別符號長度進行檢查
{integer}|{real}|-{integer} {
/*檢查長度*/
if(yyleng > 14)
{
printf("Error! The length of this number is too long!\n");
exit(0);
}
print_out('C');col = col + yyleng;
}
{char} {
if(yyleng > 3){
/*char型別 'k' 長度為3*/
printf("The length of char must be 1.");
exit(0);
}
print_out('C'); col = col + yyleng;
}
{identifier} {
/*檢查長度是否超出範圍*/
if(yyleng > 10){
printf("Error! The length of this idetifier is too long!\n");
exit(0);
}
print_out('I');col = col + yyleng;
}
- 錯誤處理
{illegal} {
/*含有非法字元的字串*/
/*數字開頭的identifier*/
/*real裡是錯誤型別*/
printf("This word is incorrect! ");
print_out('T');
}
使用者子程式
此處子程式借鑑的老師ppt裡的例子
將所需處理的檔名用 argv傳遞進來
處理以後的結果輸出到檔案中
設計思路
在教材中,把詞法分析器安排成一個子程式,每當語法分析器需要一個單詞符號時就呼叫這個子程式;每呼叫一次,詞法分析器就從輸入串中識別出一個單詞符號,然後把它交給語法分析器。
圖片已丟失。。。因此,生成的詞法分析器需要能夠順序逐個將單詞的屬性和位置(列數、行數)輸出。
單詞按照不同的屬性進行單獨處理。
在程式碼中使用全域性變數File* fout將詞法分析結果輸出到檔案中。
實驗步驟
- 根據詞法規則和擴充套件語法要求,將對應的詞法定義規則寫到code.l檔案中
- 用flex工具將lex源程式生成lex.yy.c檔案
- 在c語言環境下,對lex.yy.c檔案進行編譯,生成可執行檔案a.out
- 使用a.out檔案對pl0測試集中資料進行測試
- 將結果存放在輸出集資料夾中
原始碼
github address: https://github.com/Ethan00Si/Pl0-compiler/tree/master/%E8%AF%8D%E6%B3%95%E5%88%86%E6%9E%90%E5%99%A8