單詞符號種別識別程序設計_第1頁
單詞符號種別識別程序設計_第2頁
單詞符號種別識別程序設計_第3頁
單詞符號種別識別程序設計_第4頁
單詞符號種別識別程序設計_第5頁
已閱讀5頁,還剩9頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、班級: 學號: 姓名:實驗二 單詞符號種別識別程序設計一、實驗目的通過C語言詞法分析程序的實現理解編譯程序過程中詞法分析對單詞的種別識別過程。二、實驗重難點單詞識別三、實驗內容與要求1. 閱讀教材P2-P3詞法分析部分內容,明確詞法分析的任務。2. 閱讀實驗案例,明確實驗要求、模塊流程圖和程序實現方案;3. 參考實驗案例,完成簡單的詞法分析程序設計。四、實驗學時4課時五、實驗設備與環境C語言編譯環境六、實驗案例1. 待分析的簡單的詞法(1) 關鍵字:begin if then while do end所有的關鍵字都是小寫。(2) 運算符和界符: = + - * / < <= <

2、;> > >= = ; ( ) #(3) 其他單詞是標識符(ID)和整型常數(SUM),通過以下正規式定義:ID = letter (letter | digit)*NUM = digit digit*(4) 空格由空白、制表符和換行符組成。空格一般用來分隔ID、SUM、運算符、界符和關鍵字,詞法分析階段通常被忽略。2. 各種單詞符號對應的種別碼見表6.1:表6.1 各種單詞符號對應的種別碼單詞符號種別碼 單詞符號種別碼begin1:17if2=18then3<20while4!=21do5<=22end6>237>=248=25+9;26lettet

3、(letter|digit)*10(27dight dight*11)28+13-29-1430*15!31/16#03. 詞法分析程序的功能:輸入:所給文法的源程序字符串。輸出:二元組(syn,token或sum)構成的序列。其中:syn為單詞種別碼; token為存放的單詞自身字符串; sum為整型常數。例如:對源程序begin x:=9; if x>9 then x:=2*x+1/3; end #的源文件,經過詞法分析后輸出如下序列:(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)4. 詞法分析程序的算法思想:算法的基本任務是從字符串表示的源程序中識

4、別出具有獨立意義的單詞符號,其基本思想是根據掃描到單詞符號的第一個字符的種類,拼出相應的單詞符號。(1) 主程序示意圖:主程序示意圖如圖6-1所示。其中初值包括以下兩個方面:Ø 關鍵字表的初值:關鍵字作為特殊標識符處理,把它們預先安排在一張表格中(稱為關鍵字表),當掃描程序識別出標識符時,查關鍵字表。如能查到匹配的單詞,則該單詞為關鍵字,否則為一般標識符。關鍵字表為一個字符串數組,其描述如下:Char *rwtab6 = “begin”, “if”, “then”, “while”, “do”, “end”,;置初值調用掃描子程序輸出單詞二元組輸入串結束 否 是結束 圖6-1 主程序

5、流程圖Ø 程序中需要用到的主要變量為syn,token和sum(2) 掃描子程序的算法思想:首先設置3個變量:token用來存放構成單詞符號的字符串;sum用來存放整型單詞;syn用來存放單詞符號的種別碼。掃描子程序主要部分流程如圖6-2所示。變量初始化忽略空格是否文件結束? 返回 是否字母拼字符串 數字 其他運算符、 符號界符等符號是否關鍵字?返回拼數 否對不同符號給出相應的syn值報錯syn=10 是syn=1111syn為對應關鍵字的單詞種別碼圖 6-2 掃描子程序算法流程圖5. 詞法分析程序的C語言程序源代碼:#include <stdio.h>#include

6、<stdlib.h>#include <string.h>#include <ctype.h>#include <malloc.h>#include <conio.h>char prog80, ch;int p,m,n;char token8;int syn,sum;char *rwtab6="begin","if","then","while","do","end" /關鍵字表初始化scaner(); /聲明一個函

7、數名為scanser()的子函數main()p=0; printf("n please input a string(end with '#'):n"); do scanf("%c",&ch);/用%c控制輸入則空格等表示有效輸入,用%S控制,空格等表示輸入結束 progp+=ch; while(ch!='#');/遇到“#”,輸入結束 p=0; do scaner(); switch(syn) case 11:printf("( %-10d%5d )n",sum,syn);/*種別為數字時;%

8、-10d:表示輸出共占10位,%5d共占5位,右對齊左端補空格*/ break; case -1:printf("you have input a wrong stringn"); getch(); exit(0); default: printf("( %-10s%5d )n",token,syn); break; while(syn!=0); /“#”,syn=0 getch(); scaner() sum=0; for(m=0;m<8;m+) tokenm=NULL; / token8賦初值為空,token存放待識別的單詞 ch=progp+

9、; m=0; while(ch=' ')|(ch='n') ch=progp+;/空格或回車,不用判斷,直接進入下一個單詞 /*如果這是一個字符串,拼字符串,判斷種別碼*/if(ch<='z')&&(ch>='a')|(ch<='Z')&&(ch>='A') /如果首字母為字母,拼出完整字符串 /*lettet(letter|digit)判斷后續字符是不是數字或字母,如果是就往下拼;如果不是,結束拼字符串*/while(ch<='

10、z')&&(ch>='a')|(ch<='Z')&&(ch>='A')|(ch>='0')&&(ch<='9') tokenm+=ch; ch=progp+; p-; /使得progp為下一個帶處理的字符 syn=10; /*查關鍵字表,進一步判斷這個字符串是標識符還是關鍵字*/ for(n=0;n<6;n+) if(strcmp(token,rwtabn)=0) syn=n+1; break; /*如果這是一個數串,拼數,

11、判斷種別碼*/ else if(ch>='0')&&(ch<='9') while(ch>='0')&&(ch<='9') sum=sum*10+ch-'0' ch=progp+; p-; syn=11; /*如果這是一個界符、運算符,判斷種別碼*/ else switch(ch)/*如果是<打頭,判斷是 < 還是 <= */case '<':tokenm+=ch; ch=progp+; if(ch='='

12、;) syn=22; tokenm+=ch; else syn=20; p-; break;/*如果是>打頭,判斷是 < 還是 >= */ case '>':tokenm+=ch; ch=progp+; if(ch='=') syn=24; tokenm+=ch; else syn=23; p-; break;/*如果是+打頭,判斷是 + 還是 + */ case '+': tokenm+=ch; ch=progp+; if(ch='+') syn=9; tokenm+=ch; else syn=13; p

13、-; break;/*如果是-打頭,判斷是 - 還是 - */ case '-':tokenm+=ch; ch=progp+; if(ch='-') syn=29; tokenm+=ch; else syn=14; p-; break;/*如果是!打頭,判斷是 != 還是 ! */ case '!':ch=progp+; if(ch='=') syn=21; tokenm+=ch; else syn=31; p-; break;/*如果是=打頭,判斷是 = 還是 = */ case '=':tokenm+=ch;

14、ch=progp+; if(ch='=') syn=25; tokenm+=ch; else syn=18; p-; break; case '*': syn=15; tokenm+=ch; break; case '/': syn=16; tokenm+=ch; break; case '(': syn=27; tokenm+=ch; break; case ')': syn=28; tokenm+=ch; break; case '': syn=7; tokenm+=ch; break; cas

15、e '': syn=8; tokenm+=ch; break; case '': syn=26; tokenm+=ch; break; case '"': syn=30; tokenm+=ch; break; case '#': syn=0; tokenm+=ch; break; case ':':syn=17; tokenm+=ch; break; default: syn=-1; break; tokenm+='0'/給字符串加上字符串結束標志 6. 結果分析:輸入begin x:=9

16、; if x>9 then x:=2*x+1/3; end # 后經詞法分析輸出如下序列:(begin 1)(x 10)(:17)(= 18)(9 11)(;26)(if 2) 如圖6-3所示: 圖6-3七、簡單的詞法分析程序的設計1. The definition of P of a provided context-free grammar is as below:P=<標識符> <字母><字母數字串><字母數字串> <字母><字母數字串>|<數字><字母數字串>|<下劃線>&

17、lt;字母數字串>|<無符號整數>- <數字><數字串><數字串> <數字><數字串> |<加法運算符> +<減法運算符> -<大于關系運算符> ><大于等于關系運算符> >=2. The classes of token:關鍵字:if、int、for、while、do、return、break、continue;單詞種別碼為1。標識符:單詞種別碼為2。常數(無符號整數):單詞種別碼為3。運算符+、*、/、=、>、<、>=、<=、!=

18、:單詞種別碼為4。界符包括:,、;、(、); 單詞種別碼為5。3. sample input: main()int a,b;a = 10; b = a + 20;4. sample output:(2,“main”)(5,“(”)(5,“)”)(5,“”)(1,“int”)(2,“a”)(5,“,”)(2,”b”)(5,“;”)(2,“a”)(4,“=”)(3,“10”)(5,“;”)(2,“b”)(4,“=”)(2,“a”)(4,“+”)(3,“20”)(5,“;”)(5,“)5. 詞法分析程序(c語言版):#include <stdio.h>#include <stdli

19、b.h>#include <string.h>#include <ctype.h>#include <malloc.h>#include <conio.h>char prog80, ch;int p,m,n;char token8;int syn,sum;char *rwtab8="if","int","for","return","break","continue","while","do&

20、quot; /關鍵字表初始化scaner(); /聲明一個函數名為scanser()的子函數main()p=0; printf("n please input a string(end with '#'):n"); do scanf("%c",&ch);/用%c控制輸入則空格等表示有效輸入,用%S控制,空格等表示輸入結束 progp+=ch; while(ch!='#');/遇到"#",輸入結束 p=0; do scaner(); switch(syn) case 3:printf("

21、("%d"t "%d"t)n",syn,sum);/*種別為數字時;%-10d:表示輸出共占10位,%5d共占5位,右對齊左端補空格*/ break; case -1:printf("you have input a wrong stringn"); getch(); exit(0); default: printf("("%d"t "%s"t)n",syn,token); break; while(syn!=0); /"#",syn=0 get

22、ch(); scaner() sum=0; for(m=0;m<8;m+) tokenm=NULL; / token8賦初值為空,token存放待識別的單詞 ch=progp+; m=0; while(ch=' ')|(ch='n') ch=progp+;/空格或回車,不用判斷,直接進入下一個單詞 /*如果這是一個字符串,拼字符串,判斷種別碼*/if(ch<='z')&&(ch>='a')|(ch<='Z')&&(ch>='A') /如果

23、首字母為字母,拼出完整字符串 /*lettet(letter|digit)判斷后續字符是不是數字或字母,如果是就往下拼;如果不是,結束拼字符串*/while(ch<='z')&&(ch>='a')|(ch<='Z')&&(ch>='A')|(ch>='0')&&(ch<='9') tokenm+=ch; ch=progp+; p-; /使得progp為下一個帶處理的字符 syn=2;/ /*查關鍵字表,進一步判斷這個

24、字符串是標識符還是關鍵字*/ for(n=0;n<6;n+) if(strcmp(token,rwtabn)=0) syn=1; break; /*如果這是一個數串,拼數,判斷種別碼*/ else if(ch>='0')&&(ch<='9') while(ch>='0')&&(ch<='9') sum=sum*10+ch-'0' ch=progp+; p-; syn=3; /*如果這是一個界符、運算符,判斷種別碼*/ else switch(ch)/*如

25、果是<打頭,判斷是 < 還是 <= */case '<':tokenm+=ch; ch=progp+; if(ch='=') syn=4; tokenm+=ch; else syn=4; p-; break;/*如果是>打頭,判斷是 < 還是 >= */ case '>':tokenm+=ch; ch=progp+; if(ch='=') syn=4; tokenm+=ch; else syn=4; p-; break;/*如果是+打頭,判斷是 + 還是 + */ case '

26、;+': tokenm+=ch; ch=progp+; if(ch='+') syn=4; tokenm+=ch; else syn=4; p-; break;/*如果是-打頭,判斷是 - 還是 - */ case '-':tokenm+=ch; ch=progp+; if(ch='-') syn=4; tokenm+=ch; else syn=4; p-; break;/*如果是!打頭,判斷是 != 還是 ! */ case '!':ch=progp+; if(ch='=') syn=4; tokenm+=ch; else syn=4; p-; break;/*如果是=打頭,判斷是 = 還是 = */ case '=':tokenm

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論