版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、編譯原理實驗姓 名:朱彥榮學(xué) 號:專 業(yè):軟件工程 2 實驗題目:詞法分析 完成語言: C/C+ 上級系統(tǒng): VC+6.0日 期: 2015/11/7詞法分析設(shè)計題目: 手工設(shè)計 c 語言的詞法分析器(可以是 c 語言的子集 )設(shè)計內(nèi)容:處理 c 語言源程序, 過濾掉無用符號 ,判斷源程序中 單詞的合法性 ,并 分解出 正確的單詞 ,以 二元組形式存放在文件 中。設(shè)計目的: 了解高級語言單詞的分類,了解狀態(tài)圖以及如何表示并識別單詞規(guī)則, 掌握狀態(tài)圖到識別程序的編程。結(jié)果要求: 課程設(shè)計報告。完成日期: 第十五周提交報告一 分析要想 手工設(shè)計詞法分析器,實現(xiàn) C 語言子集的識別,就要明白 什么是
2、詞法分析器 ,它的 功能是什么。詞法分析是編譯程序進行編譯時 第一個要進行的任務(wù)主要是對源程序進行編譯預(yù)處理 (去除注釋、 無用的回車換行找到包含的文件等) 之后, 對整個源程序進行分解 ,分解成 一個個單詞 ,這些單詞有且 只有五類 ,分別是 標(biāo)識符、保留字、常數(shù)、運算符、界符 。以便為下面的語法分析和語義分析要定義好這五種符號的集合 。下做準(zhǔn)備??梢哉f詞法分析面向的對象是 單個的字符 ,目的是把它們 組成有效的單 詞(字符串);而 語法的分析 則是利用詞法分析的結(jié)果作為輸入來分析是否符合語 法規(guī)則并且進行 語法制導(dǎo) 下的語義分析,最后產(chǎn)生 四元組 (中間代碼 ),進行優(yōu)化 (可有可無)之后
3、最終生成 目標(biāo)代碼 ??梢娫~法分析是所有 后續(xù)工作的基礎(chǔ) ,如 果這一步出錯,比如明明是 <='卻被拆分成 <'和 ='就會對下文造成不可面是我構(gòu)造的一個 C 語言子集 。第一類:標(biāo)識符 letter(letter | digit)*無窮集第二類:常數(shù) (digit)+ 無窮集第三類:保留字 (32)autobreakcase charconstcontinuedefaultdodouble elseenumexternfloatforgoto ifintlongregisterreturnshort signedsizeofstaticstructswit
4、chtypedef unionunsignedvoidvolatilewhile第四類:界符 /*'、/ '、 () " " ' 等第五類:運算符 <、<=、 >、 >=、 =、 +、-、*、/、八、等挽回的影響。因此,在進行詞法分析的時候一定對所有可數(shù)符號進行編碼:<$,0><auto,1> <while,32><+,33> <-,34> <*,35> </,36> <<,37> <<=,38> <&
5、gt;,39> <>=,40> <=,41><=,42><!=,43><,44><(,45><),46><八,47><,48><",49><',50><#,51><&,52><&&,53><|,54><|,55><%,56><,57><<<,58>左移<>>,59>右移<,6
6、0><,61><,62><,63><,64><.,65><?,66><:,67><!,68>"","","",""<常數(shù) 99 ,數(shù)值 ><標(biāo)識符 100 ,標(biāo)識符指針 >上述二元組中左邊是單詞的符號,右邊為其 種別碼 ,其中常數(shù)和標(biāo)識符有點特別,因為是無窮集合,因此常數(shù)用自身來表示,種別碼為99,標(biāo)識符用標(biāo)識符符號表的指針表示(當(dāng)然也可用自身顯示,比較容易觀察) ,種別碼 100。根據(jù)上述
7、約定,一旦見到了種別碼syn=63就唯一確定了 '這個單詞。下面是一些變量的約定:/ 全局變量,保留字表static char reserveWord3220 = "auto", "break", "case", "char", "const", "continue", "default", "do", "double", "else", "enum", "e
8、xtern", "float", "for", "goto", "if", "int", "long","register", "return", "short", "signed", "sizeof", "static","struct", "switch", "typedef", &q
9、uot;union", "unsigned", "void", "volatile", "while"/ 界符運算符表 ,根據(jù)需要可以自行增加static char operatorOrDelimiter3610= "+","-","*","/","<","<=",">",">=","=","=
10、","!=",";","(",")","A",",",""","'","#","&","","",".","?",":","!";static char IDentifierTbl100050="";/ 標(biāo)識符表char r
11、esourceProject10000;/ 輸入的源程序存放處,最大可以存放 10000個字符。char token20=0;每次掃描的時候存儲已經(jīng)掃描的結(jié)果。int syn=-1;/syn即為種別碼,約定$'的種別碼為0,為整個源程序的結(jié)束符號一旦掃描到這個字符代表掃描結(jié)束int pProject = 0;/源程序指針,始終指向當(dāng)前源程序待掃描位置。幾個重要函數(shù):/ 查找保留字,若成功查找,則返回種別碼/ 否則返回 -1,代表查找不成功,即為標(biāo)識符 int searchReserve(char reserveWord 20, char s)/* 判斷是否為字母 */ bool IsL
12、etter(char letter)/* 判斷是否為數(shù)字 */bool IsDigit(char digit)/* 編譯預(yù)處理,取出無用的字符和注釋 */ void filterResource(char r,int pProject)/*分析子程序,算法核心 */void Scanner(int &syn,char resourceProject,char token,int &pProject)面說一下整個程序的流程:1. 詞法分析程序 打開源文件, 讀取文件內(nèi)容, 直至遇上 '$'文件結(jié)束符, 然后讀取結(jié)束。2. 對讀取的文件進行預(yù)處理,從頭到尾進行掃描,
13、 去除/和/*/的內(nèi)容 ,以及一些無用的、影響程序執(zhí)行的符號如換行符、回車符、制表符等。但是 千萬注意不要在這個時候去除空格,因為空格在詞法分析中有用,比如說int i=3;這個語句,如果去除空格就變成了 “ inti=3”,這樣就失去了程序的本意,因此不能在這個時候去除空格。3. 選下面就要對 源文件從頭到尾進行掃描 了,從頭開始掃描, 這個時候掃描程序首先要 詢問當(dāng)前的字符 是不是空格 ,若是空格,則繼續(xù)掃描下一個字符,直至不是空格,然后詢問這個字符 是不是字母 ,若是則進行標(biāo)識符和保留字的識別; 若這個 字符為數(shù)字 ,則進行數(shù)字的判斷。 否則, 依次對這個 字符可能的情況進行判斷, 若是
14、將所有可能都 走了一遍還是沒有知道它是誰,則認定為 錯誤符號,輸出該錯誤符號 ,然后結(jié)束。每 次成功識別了一個單詞后,單詞都會存在 token 中。然后確定這個單詞的 種別碼 , 最后進行下一個單詞的識別。 這就是掃描程序進行的工作, 可以說這個程序徹底實現(xiàn) 了 確定有限自動機 的某些功能,比如說 識別標(biāo)識符,識別數(shù)字 等。為了簡單起見,這 里的數(shù)字只是 整數(shù) 。4. 主控程序主要負責(zé)對每次識別的種別碼 syn進行判斷,對于不同的單詞種別做出不同 的反應(yīng), 如對于標(biāo)識符則將其插入標(biāo)識符表中。 對于保留字則輸出該保留字的種別碼 和助記符,等等吧。直至遇到 syn=0程序結(jié)束。二流程圖下面是程序的
15、流程圖:三運行與測試比如說,就拿這個源程序的一部分進行測試:運行程序后結(jié)果為: 同樣單詞也寫入了文件如下: 。綜上分析,達到了預(yù)期的結(jié)果。四實驗體會每做一次比較大的實驗, 都應(yīng)該寫一下實驗體會, 來加深自己對知識的認識。其實這次的實驗,算法部分并不難,只要知道了 DFA這個模塊很好寫,比較麻煩的就是五種 類型的字符個數(shù)越多程序就越長。 但為了能識別大部分程序, 我還是用了比較大的子集, 結(jié)果花了一下午的功夫才寫完,雖然很累吧,但看著這個詞法分析器的處理能力,覺得 還是值得的。同時也加深了對字符的認識。程序的可讀性還算不錯。程序沒有實現(xiàn)的是對所有復(fù)合運算的分離,但原理是相同的,比如“+=“,只需
16、在” +“的邏輯之后向前掃描就行了, 因此就沒有再加上了。 感受最深的是學(xué)習(xí)編譯原理必須要做實驗, 寫程序, 這樣才會提高自己的動手能力,加深自己對難點的理解,對于以后的求 first,follow,fisrtVT,lastVT5 是應(yīng)該如此。五源程序/ Lexical_Analysis.cpp : 定義控制臺應(yīng)用程序的入口點。/#include "stdio.h"#include "stdlib.h"#include "string.h"#include "iostream"using namespace std
17、;/ 詞法分析程序/ 首先定義種別碼/*第一類:標(biāo)識符letter(letter | digit)*無窮集第二類:常數(shù)(digit)+ 無窮集第三類:保留字 (32)autobreakcasecharconstcontinuedefaultdodoubleelseenumexternfloatforgotoifintlongregister returnshortsignedsizeofstaticstructswitchtypedefunionunsignedvoidvolatilewhile第四類:界符 /*'、 / '、() "II1第五類:運算符 <、&
18、lt;=、>、>=、=、+、-、*、/、八、對所有可數(shù)符號進行編碼:<$,0><auto,1><while,32><+,33><-,34><*,35></,36><<,37><<=,38><>,39><>=,40><=,41><=,42><!=,43><,44><(,45><),46><八,47><,48><",49&
19、gt;<',50><#,51><&,52><&&,53><|,54><|,55><%,56><,57><<<,58>左移<>>,59>右移<,60><,61><,62><,63><,64><.,65><?,66><:,67><!,68>"","","",&
20、quot;"<常數(shù) 99 ,數(shù)值 ><標(biāo)識符 100 ,標(biāo)識符指針 > */*/*/*查找保留字 */ 全局變量,保留字表static char reserveWord3220 = "auto", "break", "case", "char", "const", "continue", "default", "do", "double", "else", &qu
21、ot;enum", "extern", "float", "for", "goto", "if", "int", "long", "register", "return", "short", "signed", "sizeof", "static", "struct", "switch",
22、 "typedef", "union", "unsigned", "void", "volatile", "while"/ 界符運算符表 ,根據(jù)需要可以自行增加 static char operatorOrDelimiter3610 = +", "-", "*", "/", "<", "<=", ">", ">=&
23、quot;, "=", "=","!=", ";", "(", ")", "A", ",", """, "'", "#", "&","&&", "|", "|", "%", "", "<<&quo
24、t;, ">>", "", "", "", "", "", ".", "?", ":", "!"static char IDentifierTbl100050 = "" ;/ 標(biāo)識符表*int searchReserve(char reserveWord20, char s) for (int i = 0; i < 32; i+)if (strcmp(rese
25、rveWordi, s) = 0)/ 若成功查找,則返回種別碼return i + 1;/ 返回種別碼return -1;/ 否則返回 -1,代表查找不成功,即為標(biāo)識符*查找保留字 *判斷是否為字母*bool IsLetter(char letter)/ 若為多行注釋“ /*0 0 0*/ ”則去除該內(nèi)容/ 注意 C 語言允許下劃線也為標(biāo)識符的一部分可以放在首部或其他地方if (letter >= 'a'&&letter <= 'z' | letter >= 'A'&&letter <= &
26、#39;Z'| letter='_') return true;elsereturn false;*判斷是否為字母*判斷是否為數(shù)字*bool IsDigit(char digit)if (digit >= '0'&&digit <= '9')return true;elsereturn false;*判斷是否為數(shù)字*編譯預(yù)處理,取出無用的字符和注釋*void filterResource(char r, int pProject)char tempString10000;int count = 0;for (i
27、nt i = 0; i <= pProject; i+) if (ri = '/'&&ri + 1 = '/')/ 若為單行注釋“ / ” ,則去除注釋后面的東西,直至遇到回車換行while (ri != 'n')i+;/ 向后掃描if (ri = '/'&&ri + 1 = '*')i += 2;while (ri != '*' | ri + 1 != '/')i+;/ 繼續(xù)掃描if (ri = '$')printf("
28、;注釋出錯,沒有找到*/,程序結(jié)束! ! n");exit(0);i += 2;/ 跨過“ */ ”if (ri != 'n'&&ri != 't'&&ri != 'v'&&ri != 'r')/ 若出現(xiàn)無用字符,則過濾;否則加載 tempStringcount+ = ri;tempStringcount = '0'strcpy(r, tempString);/產(chǎn)生凈化之后的源程序編譯預(yù)處理,取出無用的字符和注釋*/*分析子程序,算法核心 */void Sc
29、anner(int &syn, char resourceProject, char token, int &pProject) /根據(jù)DFA的狀態(tài)轉(zhuǎn)換圖設(shè)計int i, count = 0;/count用來做token的指示器,收集有用字符char ch;/作為判斷使用ch = resourceProjectpProject; while (ch = ' ')/ 過濾空格,防止程序因識別不了空格而結(jié)束pProject+;ch = resourceProjectpProject;for (i = 0; i<20; i+)/ 每次收集前先清零tokeni =
30、 '0'if (IsLetter(resourceProjectpProject)/ 開頭為字母tokencount+ = resourceProjectpProject;/收集pProject+;/ 下移while (IsLetter(resourceProjectpProject) | IsDigit(resourceProjectpProject)/ 后跟字母或數(shù)字tokencount+ = resourceProjectpProject;/|攵集pProject+; 下移/ 多讀了一個字符既是下次將要開始的指針位置tokencount = '0'syn
31、= searchReserve(reserveWord, token);/查表找至 U種別碼if (syn = -1)/ 若不是保留字則是標(biāo)識符syn = 100;/標(biāo)識符種別碼return;else if (IsDigit(resourceProjectpProject)/ 首字符為數(shù)字while (IsDigit(resourceProjectpProject)/ 后跟數(shù)字tokencount+ = resourceProjectpProject;/|攵集pProject+;/ 多讀了一個字符既是下次將要開始的指針位置tokencount = '0'syn = 99;/常數(shù)
32、種別碼else if (ch = '+' | ch = '-' | ch = '*' | ch = '/' | ch = '' | ch = '(' | ch = ')' | ch = 'A'| ch = ',' | ch = '"' | ch = ''' | ch = '' | ch = '#' | ch = '%' | ch = ''|
33、 ch = '' | ch = '' | ch = '' | ch = '' | ch = '.' | ch = '?' | ch = ':')/ 若為運算符或者界符,查表得到結(jié)果 token0 = resourceProjectpProject; token1 = '0'/ 形成單字符串 for (i = 0; i<36; i+) / 查運算符界符表if (strcmp(token, operatorOrDelimiteri) = 0)syn = 33 + i
34、;獲得種別碼,使用了一點技巧,使之呈線性映射break;/ 查到即推出pProject+;指針下移,為下一掃描做準(zhǔn)備return;else if (resourceProjectpProject = '<')/<,<=,<<pProject+;后移,超前搜索if (resourceProjectpProject = '=')syn = 38;else if (resourceProjectpProject = '<')/ 左移pProject-; syn = 58;elsepProject-;syn = 37;
35、pProject+;指針下移 return;else if (resourceProjectpProject = '>') />,>=,>>pProject+;if (resourceProjectpProject = '=') syn = 40;else if (resourceProjectpProject = '>') syn = 59;else pProject-; syn = 39;pProject+; return;else if (resourceProjectpProject = '=&
36、#39;) /=.=pProject+;if (resourceProjectpProject = '=') syn = 42;else pProject-; syn = 41;pProject+; return;else if (resourceProjectpProject = '!') /!,!=pProject+;if (resourceProjectpProject = '=') syn = 43;else syn = 68; pProject-;pProject+;return;else if (resourceProjectpPro
37、ject = '&')/&,&&pProject+;if (resourceProjectpProject = '&')syn = 53;elsepProject-; syn = 52;pProject+;return;else if (resourceProjectpProject = '|')/|,|pProject+;if (resourceProjectpProject = '|')syn = 55;elsepProject-; syn = 54;pProject+;return;e
38、lse if (resourceProjectpProject = '$')/ 結(jié)束符syn = 0;/ 種別碼為 0 else/ 不能被以上詞法分析識別,則出錯printf("error: there is no exist %c n", ch); exit(0);int main()/ 打開一個文件,讀取其中的源程序char resourceProject10000;char token20 = 0 ;int syn = -1, i;/ 初始化int pProject = 0;/ 源程序指針FILE *fp, *fp1;if (fp = fopen(&q
39、uot;D:zyr_rc.txt", "r") = NULL)/ 打開源程序cout << "can't open this file" exit(0); resourceProjectpProject = fgetc(fp);while (resourceProjectpProject != '$')將源程序讀入 resourceProject數(shù)組 pProject+;resourceProjectpProject = fgetc(fp); resourceProject+pProject = '0'fclose(fp);cout << endl << "源程序為 :" <<
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年度特種工程沙石材料供貨合同3篇
- 2024年商業(yè)店面裝修工程合同2篇
- 2024版?zhèn)€人發(fā)明專利許可及知識產(chǎn)權(quán)轉(zhuǎn)讓合同示例3篇
- 2024年度上海市房屋租賃合同樣本6篇
- 2024實習(xí)教師教育實習(xí)指導(dǎo)教師責(zé)任合同協(xié)議3篇
- 2024年度電商企業(yè)廣告投放合同3篇
- 2024宿舍管理員宿舍設(shè)施更新改造服務(wù)合同2篇
- 2024年度房屋買賣合同中的房屋質(zhì)量保證3篇
- 2024年度企業(yè)內(nèi)部講師認證授權(quán)培訓(xùn)協(xié)議合同范本3篇
- 2024年度演出節(jié)目單制作合同演出主辦方與節(jié)目單制作公司之間的節(jié)目單制作協(xié)議3篇
- 【MOOC】大學(xué)攝影-河南理工大學(xué) 中國大學(xué)慕課MOOC答案
- 執(zhí)紀(jì)審查業(yè)務(wù)專題培訓(xùn)
- 音樂著作權(quán)授權(quán)合同模板
- 《鐵路軌道維護》課件-鋼軌鉆孔作業(yè)
- 【MOOC】數(shù)據(jù)結(jié)構(gòu)與算法-北京大學(xué) 中國大學(xué)慕課MOOC答案
- 信息安全意識培訓(xùn)課件
- Python試題庫(附參考答案)
- 道法第二單元 成長的時空 單元測試 2024-2025學(xué)年統(tǒng)編版道德與法治七年級上冊
- MOOC 理解馬克思-南京大學(xué) 中國大學(xué)慕課答案
- 海洋的前世今生智慧樹知到期末考試答案2024年
- 預(yù)算與預(yù)算法課件
評論
0/150
提交評論