




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、編譯原理實(shí)驗(yàn)姓 名:朱彥榮學(xué) 號:專 業(yè):軟件工程 2 實(shí)驗(yàn)題目:詞法分析 完成語言: C/C+ 上級系統(tǒng): VC+6.0日 期: 2015/11/7詞法分析設(shè)計(jì)題目: 手工設(shè)計(jì) c 語言的詞法分析器(可以是 c 語言的子集 )設(shè)計(jì)內(nèi)容:處理 c 語言源程序, 過濾掉無用符號 ,判斷源程序中 單詞的合法性 ,并 分解出 正確的單詞 ,以 二元組形式存放在文件 中。設(shè)計(jì)目的: 了解高級語言單詞的分類,了解狀態(tài)圖以及如何表示并識別單詞規(guī)則, 掌握狀態(tài)圖到識別程序的編程。結(jié)果要求: 課程設(shè)計(jì)報告。完成日期: 第十五周提交報告一 分析要想 手工設(shè)計(jì)詞法分析器,實(shí)現(xiàn) C 語言子集的識別,就要明白 什么是
2、詞法分析器 ,它的 功能是什么。詞法分析是編譯程序進(jìn)行編譯時 第一個要進(jìn)行的任務(wù)主要是對源程序進(jìn)行編譯預(yù)處理 (去除注釋、 無用的回車換行找到包含的文件等) 之后, 對整個源程序進(jìn)行分解 ,分解成 一個個單詞 ,這些單詞有且 只有五類 ,分別是 標(biāo)識符、保留字、常數(shù)、運(yùn)算符、界符 。以便為下面的語法分析和語義分析要定義好這五種符號的集合 。下做準(zhǔn)備。可以說詞法分析面向的對象是 單個的字符 ,目的是把它們 組成有效的單 詞(字符串);而 語法的分析 則是利用詞法分析的結(jié)果作為輸入來分析是否符合語 法規(guī)則并且進(jìn)行 語法制導(dǎo) 下的語義分析,最后產(chǎn)生 四元組 (中間代碼 ),進(jì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第四類:界符 /*'、/ '、 () " " ' 等第五類:運(yùn)算符 <、<=、 >、 >=、 =、 +、-、*、/、八、等挽回的影響。因此,在進(jìn)行詞法分析的時候一定對所有可數(shù)符號進(jìn)行編碼:<$,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)識符有點(diǎn)特別,因?yàn)槭菬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"/ 界符運(yùn)算符表 ,根據(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. 對讀取的文件進(jìn)行預(yù)處理,從頭到尾進(jìn)行掃描,
13、 去除/和/*/的內(nèi)容 ,以及一些無用的、影響程序執(zhí)行的符號如換行符、回車符、制表符等。但是 千萬注意不要在這個時候去除空格,因?yàn)榭崭裨谠~法分析中有用,比如說int i=3;這個語句,如果去除空格就變成了 “ inti=3”,這樣就失去了程序的本意,因此不能在這個時候去除空格。3. 選下面就要對 源文件從頭到尾進(jìn)行掃描 了,從頭開始掃描, 這個時候掃描程序首先要 詢問當(dāng)前的字符 是不是空格 ,若是空格,則繼續(xù)掃描下一個字符,直至不是空格,然后詢問這個字符 是不是字母 ,若是則進(jìn)行標(biāo)識符和保留字的識別; 若這個 字符為數(shù)字 ,則進(jìn)行數(shù)字的判斷。 否則, 依次對這個 字符可能的情況進(jìn)行判斷, 若是
14、將所有可能都 走了一遍還是沒有知道它是誰,則認(rèn)定為 錯誤符號,輸出該錯誤符號 ,然后結(jié)束。每 次成功識別了一個單詞后,單詞都會存在 token 中。然后確定這個單詞的 種別碼 , 最后進(jìn)行下一個單詞的識別。 這就是掃描程序進(jìn)行的工作, 可以說這個程序徹底實(shí)現(xiàn) 了 確定有限自動機(jī) 的某些功能,比如說 識別標(biāo)識符,識別數(shù)字 等。為了簡單起見,這 里的數(shù)字只是 整數(shù) 。4. 主控程序主要負(fù)責(zé)對每次識別的種別碼 syn進(jìn)行判斷,對于不同的單詞種別做出不同 的反應(yīng), 如對于標(biāo)識符則將其插入標(biāo)識符表中。 對于保留字則輸出該保留字的種別碼 和助記符,等等吧。直至遇到 syn=0程序結(jié)束。二流程圖下面是程序的
15、流程圖:三運(yùn)行與測試比如說,就拿這個源程序的一部分進(jìn)行測試:運(yùn)行程序后結(jié)果為: 同樣單詞也寫入了文件如下: 。綜上分析,達(dá)到了預(yù)期的結(jié)果。四實(shí)驗(yàn)體會每做一次比較大的實(shí)驗(yàn), 都應(yīng)該寫一下實(shí)驗(yàn)體會, 來加深自己對知識的認(rèn)識。其實(shí)這次的實(shí)驗(yàn),算法部分并不難,只要知道了 DFA這個模塊很好寫,比較麻煩的就是五種 類型的字符個數(shù)越多程序就越長。 但為了能識別大部分程序, 我還是用了比較大的子集, 結(jié)果花了一下午的功夫才寫完,雖然很累吧,但看著這個詞法分析器的處理能力,覺得 還是值得的。同時也加深了對字符的認(rèn)識。程序的可讀性還算不錯。程序沒有實(shí)現(xiàn)的是對所有復(fù)合運(yùn)算的分離,但原理是相同的,比如“+=“,只需
16、在” +“的邏輯之后向前掃描就行了, 因此就沒有再加上了。 感受最深的是學(xué)習(xí)編譯原理必須要做實(shí)驗(yàn), 寫程序, 這樣才會提高自己的動手能力,加深自己對難點(diǎn)的理解,對于以后的求 first,follow,fisrtVT,lastVT5 是應(yīng)該如此。五源程序/ Lexical_Analysis.cpp : 定義控制臺應(yīng)用程序的入口點(diǎn)。/#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第五類:運(yùn)算符 <、&
18、lt;=、>、>=、=、+、-、*、/、八、對所有可數(shù)符號進(jìn)行編碼:<$,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"/ 界符運(yùn)算符表 ,根據(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è)計(jì)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 = ':')/ 若為運(yùn)算符或者界符,查表得到結(jié)果 token0 = resourceProjectpProject; token1 = '0'/ 形成單字符串 for (i = 0; i<36; i+) / 查運(yùn)算符界符表if (strcmp(token, operatorOrDelimiteri) = 0)syn = 33 + i
34、;獲得種別碼,使用了一點(diǎn)技巧,使之呈線性映射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 << "源程序?yàn)?:" <<
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 麻疹、風(fēng)疹、腮腺炎聯(lián)合疫苗項(xiàng)目風(fēng)險識別與評估綜合報告
- Unit 3 Section A 教學(xué)設(shè)計(jì) 2024-2025學(xué)年人教版(2024)七年級英語上冊
- Unit 4 Birthday Lesson 3 Have Fun(教學(xué)設(shè)計(jì))-2024-2025學(xué)年北師大版(三起)英語六年級上冊
- 《Unit 4 Colour a Keyboard》(教學(xué)設(shè)計(jì))-2024-2025學(xué)年教科版(2024)英語三年級上冊
- 5玲玲的畫教學(xué)設(shè)計(jì)-2024-2025學(xué)年二年級上冊語文統(tǒng)編版
- 《數(shù)學(xué)好玩 - 數(shù)圖形的學(xué)問》(教學(xué)設(shè)計(jì))-2024-2025學(xué)年北師大版數(shù)學(xué)四年級上冊
- Module 5 Unit 1 We went to the Great Wall. (教學(xué)設(shè)計(jì))2024-2025學(xué)年外研版(一起)英語四年級上冊
- 11《大家排好隊(duì)》(教學(xué)設(shè)計(jì))-2024-2025學(xué)年統(tǒng)編版道德法治二年級上冊
- 6《除數(shù)是整十?dāng)?shù)的筆算除法》(教學(xué)設(shè)計(jì))-2024-2025學(xué)年四年級上冊數(shù)學(xué)人教版
- 《因數(shù)和倍數(shù)-2、5、3的倍數(shù)》(教學(xué)設(shè)計(jì))-2023-2024學(xué)年五年級下冊數(shù)學(xué)人教版
- 2024年南信語文數(shù)學(xué)試卷(含答案)
- JGJ46-2024 建筑與市政工程施工現(xiàn)場臨時用電安全技術(shù)標(biāo)準(zhǔn)
- 2016-2023年江蘇電子信息職業(yè)學(xué)院高職單招(英語/數(shù)學(xué)/語文)筆試歷年考點(diǎn)試題甄選合集含答案解析
- DSP原理及應(yīng)用教程-第二章 DSP芯片結(jié)構(gòu)和CPU外圍電路
- 中共一大代表的不同人生路程及其啟
- 注塑報價表模版
- 長江流域氣候變化影響脆弱性和適應(yīng)性
- 地理知識介紹課件
- 民航國內(nèi)航空匯編航路_3.1.8w系列航線
- 高數(shù)常微分方程-高階微分方程
- 竹里館ppt課件
評論
0/150
提交評論