實驗一、詞法分析實驗
商業軟件工程專業 李梓維 201506110105
一、 實驗目的
通過設計一個詞法分析程序,對詞法進行分析,加強對詞法的理解,掌握對程序設計語言的分解和理解。
二、 實驗內容和要求
在原程序中輸入源代碼
- 對字符串表示的源程序
- 從左到右進行掃描和分解
- 根據詞法規則
- 識別出一個一個具有獨立意義的單詞符號
- 以供語法分析之用
- 發現詞法錯誤,則返回出錯信息
在源程序中,自動識別單詞,把單詞分為五種,並輸出對應的單詞種別碼。
- 識別關鍵字:main if int for while do return break continue,該類的單詞碼為1.
- 識別標識符:表示各種名字,如變量名、數組名、函數名等,如char ch, int syn, token,sum,該類的單詞碼為2.
- 運算符:+、-、*、/、=、>、<、>=、<=、!=
- 分隔符:,、;、{、}、(、)
- 常數,如123,4587
各種單詞符號對應的種別碼:

輸出形式:
- 二元式
– (單詞種別,單詞自身的值)
- 單詞種別,表明單詞的種類,語法分析需要的重要信息
– 整數碼
- 關鍵字、運算符、界符:一符一碼
- 標識符:10, 常數:11
- 單詞自身的值
– 標識符token、常數sum
– 關鍵字、運算符、界符token
一、 實驗方法、步驟及結果測試
1.源程序名:編譯原理 實驗報告 中源程序名 算法分析.c
可執行程序名:編譯原理 實驗報告.exe
2.原理分析及流程圖

3.程序代碼
1 #include<stdio.h> 2 #include<string.h> 3 void F(char c,char b); 4 void word(char a[]); 5 void number(char a[]); 6 int i; //定義全局變量i 7 int s=1; //用來記錄是否存在非法字符 8 main(){ 9 char a[50]; 10 printf("請輸入需要分析的字符串:"); 11 gets(a); 12 printf("您要分析的字符串為:"); 13 printf("%s",a); 14 printf("\n"); 15 for(i=0;(a[i]!='\0')&&(i<50)&&s==1;i++){ 16 if((a[i]>='a' && a[i]<='z')||(a[i]>='A' && a[i]<='Z')) 17 word(a); 18 else if(a[i]>='0' && a[i]<='9') 19 number(a); 20 else 21 F(a[i],a[i+1]); 22 } 23 printf("\n"); 24 } 25 26 void number(char a[]) //對數字字符進行掃描分析 27 { 28 char b[50]; 29 int m,k=0,t; 30 m=i; 31 while(a[m]>='0' && a[m]<='9') 32 { 33 b[k]=a[m]; //用數組b存放數組a中的數字 34 k++; 35 m++; 36 } 37 i=m-1; 38 printf("(11,"); 39 for(t=0;t<k;t++) 40 printf("%c",b[t]); 41 printf(")"); 42 printf("\n"); 43 } 44 45 void word(char a[]) //對字母字符進行掃描分析,並識別保留字 46 { 47 int k=0,m,flag=0,t; 48 char b[50]; 49 char *key[6]={"begin","if","then","while","do","end"}; 50 m=i; 51 while((a[m]>='a'&&a[m]<='z')||(a[m]>='A'&&a[m]<='Z')) //用數組b存放數組a中的字母 52 { 53 b[k]=a[m]; 54 k++; 55 m++; 56 b[k]='\0'; 57 } 58 i=m-1; 59 for(t=0;t<6;t++) 60 { 61 if(strcmp(b,key[t])==0) //將數組b與關鍵字進行比較 62 { 63 printf("(%d,%s)",t+1,key[t]); //輸出關鍵字 64 flag=1; 65 printf("\n"); 66 } 67 } 68 if(flag==0) 69 { 70 printf("(10,%s)",b); //輸出標識符 71 printf("\n"); 72 } 73 } 74 void F(char c,char b) //對特殊字符進行掃描分析 75 { 76 switch(c){ 77 case '+': 78 printf("(13,+)\n"); 79 break; 80 81 case '-': 82 printf("(14,-)\n"); 83 break; 84 85 case '*': 86 printf("(15,*)\n"); 87 break; 88 89 case '/': 90 printf("(16,/)\n"); 91 break; 92 93 case ':': 94 if(b=='=') 95 { 96 i++; 97 printf("(18,:=)\n"); 98 } 99 else 100 printf("(17,:)\n"); 101 break; 102 103 case ' ': 104 break; 105 106 case '<': 107 if(b=='>') 108 { 109 i++; 110 printf("(21,<>)\n"); 111 } 112 else if(b=='=') 113 { 114 i++; 115 printf("(22,<=)\n"); 116 } 117 else 118 printf("(20,<)\n"); 119 break; 120 121 case '>': 122 if(b=='=') 123 { 124 printf("(24,>=)\n"); 125 i++; 126 } 127 else 128 printf("(23,>)\n"); 129 break; 130 131 case '=': 132 printf("(25,=)\n"); 133 break; 134 135 case ';': 136 printf("(26,;)\n"); 137 break; 138 139 case '(': 140 printf("(27,()\n"); 141 break; 142 143 case ')': 144 printf("(28,))\n"); 145 break; 146 147 case '#': 148 printf("(0,#)\n"); 149 break; 150 151 152 default: 153 { 154 printf("\n存在字符 '%c',無法繼續識別!\n",c); 155 s=0; //用s=0記錄存在非法字符 156 break; 157 } 158 } 159 }
4.運行結果

二.實驗總結
通過存儲輸入的字符串,用循環的方式逐個提取出來與種別碼比較,然后進行輸出。
本人覺得該實驗難點在於如何讓程序自動識別“ ”與“#”等特殊方式,以及循環的跳出條件,此實驗使我對代碼的理解更加的深刻。
